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-mvc – 自定义模型绑定器不验证模型
- 为什么NuPack生成的NinjectMVC3.cs无法编译? (或者ASP.NET
- asp.net-mvc – 在ASP.NET MVC中的ReturnUrl
- asp.net-mvc – 有没有办法重命名RequestVerificationToken
- asp.net-mvc-3 – WSFederationAuthenticationModule.IsSig
- asp.net – 如何防止PDF文档下载到用户PC?
- asp.net – 保持当前的jQuery标签跨回发?
- ASP.NET(AJAX+JSON)实现对象调用
- asp.net – WebAPI不返回XML,即使有正确的Accepts头
- asp.net-mvc – 为Cascade子列表构建一个空的MVC DropdownL
