Asp.net WebAPI Request參數驗證-請不要重複造輪子

隨着web客戶端的發展,如今不少公司都有專業的前端開發,作到系統先後端分離。ap.net後端典型的就是採用webapi,可是發現不少時候你們對webapi並不瞭解,這裏咱們來講說輸入參數的驗證。前一段時間咱們項目組也開始使用webapi來開發接口,開發之初發現設計了不少輸入參數的驗證規則(不適用,很差用而且還不能知足需求),而後咱們在寫業務的方法還的調用參數的驗證方法, 因此開發是很鬱悶的,bug也不少。。。,後來才發現 網上已有相似的博客:http://www.cnblogs.com/r01cn/p/3193095.htmlhtml

好咱們先看效果圖吧:前端

咱們的請求對象中有2個屬性,teamId和start,其中start能夠爲空,可是若是有值就必須是日期類型且有效,如這裏的「2016-2-30「是無效日期,這裏的teamid是DB裏面一張表的主鍵,因此咱們要建立自定義的驗證規則訪問數據庫來驗證其值得有效性。web

自定義驗證類:數據庫

  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("\n",errormsg.ToArray()));
                response.StatusCode = HttpStatusCode.BadRequest;
                throw new System.Web.Http.HttpResponseException(response);

            }
        }
    }

  使用以下:api

    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裏面去寫參數驗證的邏輯是不對的。前後端分離

這裏也還有 跟簡單的寫法:ide

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

歡迎你們拍磚!spa

相關文章
相關標籤/搜索