asp.net-mvc – 使用模型对象更新ModelState
问题:如何在发布验证场景时更新ModelState.
我有一个简单的形式: <%= Html.ValidationSummary() %> <% using(Html.BeginForm())%> <%{ %> <%=Html.TextBox("m.Value") %> <input type="submit" /> <%} %> 当用户提交我想要验证输入,在某些情况下,我想修复用户的错误,让他知道他做了一个已经修复的错误: [AcceptVerbs(HttpVerbs.Post)] public ActionResult Index(M m) { if (m.Value != "a") { ModelState.AddModelError("m.Value","should be "a""); m.Value = "a"; return View(m); } return View("About"); } 那么问题是,MVC会简单地忽略传递给视图的模型,并且会重新渲染用户键入的内容,而不是我的值(“a”). 由于我无法更改TextBox渲染器的行为,我发现唯一的解决方案是自己更新ModelState.快速的方式是(ab)使用DefaultModelBinder,并通过简单地更改分配方向来覆盖从表单到模型分配值的方法;).使用DefaultModelBinder我不必解析ids. /// <summary> /// Updates ModelState using values from <paramref name="order"/> /// </summary> /// <param name="order">Source</param> /// <param name="prefix">Prefix used by Binder. Argument name in Action (if not explicitly specified).</param> protected void UpdateModelState(object model,string prefix) { new ReversedBinder().BindModel(this.ControllerContext,new ModelBindingContext() { Model = model,ModelName = prefix,ModelState = ModelState,ModelType = model.GetType(),ValueProvider = ValueProvider }); } private class ReversedBinder : DefaultModelBinder { protected override void BindProperty(ControllerContext controllerContext,ModelBindingContext bindingContext,System.ComponentModel.PropertyDescriptor propertyDescriptor) { string prefix = CreateSubPropertyName(bindingContext.ModelName,propertyDescriptor.Name); object val = typeof(Controller) .Assembly.GetType("System.Web.Mvc.DictionaryHelpers") .GetMethod("DoesAnyKeyHavePrefix") .MakeGenericMethod(typeof(ValueProviderResult)) .Invoke(null,new object[] { bindingContext.ValueProvider,prefix }); bool res = (bool)val; if (res) { IModelBinder binder = new ReversedBinder();//this.Binders.GetBinder(propertyDescriptor.PropertyType); object obj2 = propertyDescriptor.GetValue(bindingContext.Model); ModelBindingContext context2 = new ModelBindingContext(); context2.Model = obj2; context2.ModelName = prefix; context2.ModelState = bindingContext.ModelState; context2.ModelType = propertyDescriptor.PropertyType; context2.ValueProvider = bindingContext.ValueProvider; ModelBindingContext context = context2; object obj3 = binder.BindModel(controllerContext,context); if (bindingContext.ModelState.Keys.Contains<string>(prefix)) { var prefixKey = bindingContext.ModelState.Keys.First<string>(x => x == prefix); bindingContext.ModelState[prefixKey].Value = new ValueProviderResult(obj2,obj2.ToString(),bindingContext.ModelState[prefixKey].Value.Culture); } } } } 所以问题依然存在:我在做一些非常不寻常的事情,还是我错过了什么?如果是前者,那么如何以更好的方式实现这些功能(使用现有的MVC基础架构)? 解决方法
我知道这篇文章是相当古老的,但这是我以前遇到过的一个问题,我只是想到了一个我喜欢的简单解决方案 – 只要清除ModelState后,你可以看到已发布的值.
UpdateModel(viewModel); ModelState.Clear(); viewModel.SomeProperty = "a new value"; return View(viewModel); 并且视图必须使用(可能修改的)视图模型对象而不是ModelState. 也许这真的很明显.事后看起来好像很好 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何在asp.net和C#中实现登录会话
- asp.net – GridView中的工具提示
- asp.net-mvc – 使用Windows身份验证与活动目录组作为角色
- asp.net-mvc – ASP.NET MVC:多个项目错误
- asp.net-mvc – ASP.NET MVC 3从同一表单保存和编辑
- .net – Cache.Add绝对到期 – 是否基于UTC?
- asp.net-mvc – 使用像Stackoverflow这样的查询字符串版本化
- ASP.NET GridView默认排序顺序
- 为什么要使用流畅的验证而不是ASP.NET MVC验证
- asp.net-web-api – ASP.NET Web API自定义帮助页面
- asp.net-mvc – 如何使用post或get来检查控制器是
- 选择完成后和提交上传之前的asp.net FileUpload事
- asp.net – 在.ashx处理程序中查看状态?
- asp.net-web-api – 在WebApi OData中为OData服务
- asp.net – 使用Microsoft Access和VB.NET进行SQ
- 如何配置IIS 7以使用子目录作为默认文档?
- asp.net – 如何增加我的存储过程调用的超时时间
- [asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚
- IIS / .NET上的Blackberry推送服务启动器
- asp.net-mvc – ASP.Net MVC中的线程安全性