Asp.net WebAPI Request参数验证-请不要重复造轮子

随着web客户端的发展,现在很多公司都有专业的前端开发,做到系统前后端分离。ap.net后端典型的就是采用webapi,但是发现很多时候大家对webapi并不了解,这里我们来说说输入参数的验证。前一段时间我们项目组也开始使用webapi来开发接口,开发之初发现设计了很多输入参数的验证规则(不适用,不好用并且还不能满足需求),然后我们在写业务的方法还的调用参数的验证方法, 所以开发是很郁闷的,bug也很多。。。,后来才发现 网上已有类似的博客:http://www.cnblogs.com/r01cn/p/3193095.html

好我们先看效果图吧:

我们的请求对象中有2个属性,teamId和start,其中start可以为空,但是如果有值就必须是日期类型且有效,如这里的“2016-2-30“是无效日期,这里的teamid是DB里面一张表的主键,所以我们要创建自定义的验证规则访问数据库来验证其值得有效性。

自定义验证类:

复制代码
  public class DBRecordCheckAttribute : ValidationAttribute
    {
        public DBRecordCheckAttribute(string filter)
        {
            Filter = filter;
        }
        public override string FormatErrorMessage(string name)
        {
            return "The value '" + this.ValueStr + "' is not valid for " + name;
        }

        public override bool IsValid(object value)
        {
            ValueStr = value == null ? string.Empty : value.ToString();
            if (string.IsNullOrEmpty(Filter))
                return true;
            DBContext db = new DBContext();
            IDbCommand command = db.Database.Connection.CreateCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = Filter;
            var p1 = command.CreateParameter();
            p1.ParameterName = "@p1";
            p1.Value = value;
            command.Parameters.Add(p1);
            command.Connection.Open();
            var result = Convert.ToInt32(command.ExecuteScalar());
            command.Connection.Close();
            return result>0;
        }
        private string ValueStr { set; get; }
        public string Filter { set; get; }
    }
复制代码

同时我们还需要一个ActionFilterAttribute的子类来实现验证,验证通过才能访问我们的action,实际中需要验证我们的身份如token, 建议token实时更新保证一次token只能被使用一次,防止api(更新、删除)被重复调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ValidParameterAttribute : ActionFilterAttribute
   {
       public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
       {
           base.OnActionExecuting(actionContext);
           bool vaildedtoken = false;
           //
           try
           {
               vaildedtoken = true;
                  var token = actionContext.Request.Headers.GetValues("token");             
               // valid token
           }
           catch { }
           
           if (!vaildedtoken || !actionContext.ModelState.IsValid) {
               var errors = actionContext.ModelState.Values.Select(x => x.Errors);
               List<string> errormsg = new List<string>();
               foreach (var item in errors)
               {
                   for (int i = 0; i < item.Count; i++)
                   {
                       errormsg.Add(item[i].ErrorMessage);
                   }
                    
               }
               var response = new HttpResponseMessage();
               response.Content = new StringContent(string.Join("\n",errormsg.ToArray()));
               response.StatusCode = HttpStatusCode.BadRequest;
               throw new System.Web.Http.HttpResponseException(response);
 
           }
       }
   }

  使用如下:

复制代码
    public class UserInfo {
        [DBRecordCheckAttribute("SELECT COUNT(*) FROM [dbo].[qal_team] where[team_id]=@p1")]
        public int teamId { set; get; }
        [DataType(DataType.Date)]
        public DateTime? start { set; get; }
    }
    [ValidParameter]
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get([FromUri] UserInfo info)
        {
            return new string[] { "value1", "value2" };
        }
    }
复制代码

在我们的业务ValuesController没有任何的验证,code是不是比较整洁了。当我们做设计的时候,我们一定要熟悉我们所使用的平台和技术,不然就像我们项目组里面在自己的action里面去写参数验证的逻辑是不对的。

这里也还有 跟简单的写法:

http://www.cnblogs.com/r01cn/archive/2012/12/04/2801664.html

欢迎大家拍砖!

posted on   dz45693  阅读(4198)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2013-04-07 SSIS Hresult: 0x80040E4D Description: Login failed for user sa

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示