隨着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("\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
歡迎大家拍磚!