zoukankan      html  css  js  c++  java
  • 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(更新、删除)被重复调用

     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("
    ",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

    欢迎大家拍砖!

  • 相关阅读:
    JavaEE--JNDI(下,实现)
    JavaEE--JNDI(上,简介)
    JavaSE--java是值传递还是引用传递
    Mysql--主库不停机搭建备库
    MySQL--从库启动复制报错1236
    JVM·垃圾收集器与内存分配策略之垃圾收集器!
    mysql·事务挂起
    hash·余数hash和一致性hash
    关于正则效率问题(正则导致程序卡死)
    JVM·参数配置
  • 原文地址:https://www.cnblogs.com/majiang/p/5365296.html
Copyright © 2011-2022 走看看