ASP.NET MVC Remote 驗證無法在後端觸發的解決方式
- 2012-10-02
- 23078
- 0
- ASP.NET MVC3 驗證介紹實作與擴充
MVC的內建驗證中有一個非常好用的 Remote ,如果各位開發人員有用過 jQuery.validate 應該對於 Remote 驗證不會陌生,簡單一點的解釋就是它可以將「後端驗證」做的很像「前端驗證」利用這種方式,開發人員不再受限於前端驗證可以判斷的資訊太少,讓驗證寫的不夠精準的問題,雖然 Remote 驗證相當好用但是有一點小地雷還是要知道的。
之前 demo 就在 twMVC 和微軟講 ASP.NET MVC 驗證的課程時有提到解決方式,但上次 twMVC 固定聚會時有朋友問到,讓我驚覺我還沒寫成文章.....所以立刻來補上。
demo已經介紹過許許多多的 MVC 驗證技巧文章,每個內建驗證都是同時支援前端與後端驗證的,用了一陣子後這個觀念很自然的植入開發人員的腦中,但是偏偏 Remote 不是那麼一回事,Remote 只支援前端驗證是很多開發人員不知道的事情,就這樣很開心的用了這強大的 Remote 後發現前端 JS 被關掉以後怎麼就什麼都擋不住了,雖然這是設計理念的原因不算是一個 Bug 但是這造成了開發時的思考會卡住的問題,變得還要記憶 Remote 不支援後端驗證,這十分的討厭,所以我們應該要來把它改成支援後端驗證因為沒有什麼特別之處(反射算特別嗎?)所以以下ˋ就直接貼出完整 Code
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Text; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace demoValidation { public class RemoteDoublePlus : RemoteAttribute { private string action { get; set; } private string controller { get; set; } private string area { get; set; } public RemoteDoublePlus(string action, string controller, string area) : base(action, controller, area) { this.action = action; this.controller = controller; this.area = area; //修正 Remote 驗證遇到根 Area 的問題 //http://demo.tc/Post/756 this.RouteData["area"] = area; } //覆寫 IsValid 方法 實作後端驗證 protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var additionalFields = this.AdditionalFields.Split(','); var propValues = new List<object>(); propValues.Add(value); foreach (string additionalField in additionalFields) { var prop = validationContext.ObjectType.GetProperty(additionalField); if (prop != null) { object propValue = prop.GetValue(validationContext.ObjectInstance, null); propValues.Add(propValue); } } var controllerType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(d => d.Name.ToLower() == (this.controller + "Controller").ToLower()); if (controllerType != null) { var instance = Activator.CreateInstance(controllerType); var method = controllerType.GetMethod(this.action); if (method != null) { ActionResult response = (ActionResult)method.Invoke(instance, propValues.ToArray()); if (response is JsonResult) { bool isAvailable = false; JsonResult json = (JsonResult)response; string jsonData = Convert.ToString(json.Data); bool.TryParse(jsonData, out isAvailable); if (!isAvailable) { return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); } } } } return null; } } }
- 如果讀者對於自定驗證控制項還不熟悉請參考「ASP.NET MVC3 驗證介紹實作與擴充」系列文章。
- 如果讀者懶得看文章可以參考 twMVC 2012-07-14 的活動記錄(影片、投影片、範例檔)
- 如果還是問題遇到問題歡迎參加 twMVC 每週四固定聚會
回應討論