asp.net-mvc – ASP.NET MVC – 复杂模型验证
我有一个像这样的ViewModel类:
class CaseModel { public Boolean ClientPresent { get; set; } public ClientModel Client { get; set; } } class ClientModel { [Required] public String FirstName { get; set; } [Required] public String LastName { get; set; } } 视图页面由< input type =“checkbox”name =“ClientPresent”/>组成.和一个Html.EditorFor(m => m.Client)局部视图. 这个想法是,当用户提供有关案例(业务域对象)的信息时,他们可以选择不通过取消选中ClientPresent框来指定有关客户端(另一个商业对象)的任何信息. 我希望ASP.NET MVC不对子ClientModel对象执行任何验证 – 但是当表单被POST回服务器时会自动填充CaseModel.Client属性,但是因为FirstName和LastName不是(必然)由user表示它未通过[Required]验证属性,因此ViewData.ModelState.IsValid返回false并且用户收到验证错误消息. 如果CaseModel.ClientPresent为false,我怎样才能获得CaseModel.Client? 请注意,ClientModel是一个完全独立的ViewModel类,在应用程序的其他位置使用(例如在ClientController类中,允许用户编辑客户端的各个实例). 解决方法
我认识到我的问题不是与绑定有关,而是与验证有关:通过保持值意味着当用户重新加载页面时将填充相同的表单字段,我只需要丢弃验证消息,因为它们不是适用.
为此,我意识到我可以执行模型属性验证,但随后使用一些自定义逻辑来删除验证消息.这与我的做法类似: public class CaseModel { public void CleanValidation(ModelStateDictionary dict) { if( this.ClientPresent ) { dict.Keys.All( k => if( k.StartsWith("Client") dict[k].Errors.Clear() ); } } } (显然我的实际代码更健壮,但你得到了一般的想法) CleanValidation方法由控制器的action方法直接调用: public void Edit(Int64 id,CaseModel model) { model.CleanValidation( this.ModelState ); } 我可以通过将CleanValidation作为一种方法添加到新接口IComplexModel并让新模型绑定器自动调用此方法以便控制器不需要自己调用它来整理它. 更新: 我有这个接口,适用于任何需要复杂验证的ViewModel: public interface ICustomValidation { void Validate(ModelStateDictionary dict); } 在我的原始示例中,CaseModel现在看起来像这样: public class CaseClientModel : ICustomValidation { public Boolean ClientIsNew { get; set; } // bound to a radio-button public ClientModel ExistingClient { get; set; } // a complex viewmodel used by a partial view public ClientModel NewClient { get; set; } // ditto public void Validate(ModelStateDictionary dict) { // RemoveElementsWithPrefix is an extension method that removes all key/value pairs from a dictionary if the key has the specified prefix. if( this.ClientIsNew ) dict.RemoveElementsWithPrefix("ExistingClient"); else dict.RemoveElementsWithPrefix("NewClient"); } } 验证逻辑由我的公共BaseController类中的OnActionExecuting调用: protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if( filterContext.ActionParameters.ContainsKey("model") ) { Object model = filterContext.ActionParameters["model"]; ModelStateDictionary modelState = filterContext.Controller.ViewData.ModelState; // ViewData.Model always returns null at this point,so do this to get the ModelState. ICustomValidation modelValidation = model as ICustomValidation; if( modelValidation != null ) { modelValidation.Validate( modelState ); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 如何从WCF客户端拦截raw soap request / respon
- asp.net – 如何在Kendo UI中获取下拉菜单的选定项目的文本
- 如何用asp.net页面提供javascript?
- iis-7 – IIS重置会强制缓存项目重新发送吗?
- asp.net-mvc – 用于控件名称的参数化前缀的局部视图
- asp.net-mvc – 强大的自托管服务器的最佳选择:WCF与ASP.N
- 什么是ASP.NET-MVC 5.1中的ManageController.cs及其创建原因
- asp.net – 什么是建议替代常见的破坏app_offline.htm黑客?
- asp.net-mvc-3 – MVC3 MapRoute,带斜杠的参数
- asp.net-mvc – Moq嘲笑一个类