Asp.net mvc 在发送到视图之前,如何在控制器操作中修改已发布的表单数据?
我希望在成功操作后渲染相同的视图(而不是使用RedirectToAction),但我需要修改渲染到该视图的模型数据。以下是一个人为的示例,演示了两种不起作用的方法:Asp.net mvc 在发送到视图之前,如何在控制器操作中修改已发布的表单数据?,asp.net-mvc,Asp.net Mvc,我希望在成功操作后渲染相同的视图(而不是使用RedirectToAction),但我需要修改渲染到该视图的模型数据。以下是一个人为的示例,演示了两种不起作用的方法: [AcceptVerbs("POST")] public ActionResult EditProduct(int id, [Bind(Include="UnitPrice, ProductName")]Product product) { NORTHWNDEntities entities = ne
[AcceptVerbs("POST")]
public ActionResult EditProduct(int id, [Bind(Include="UnitPrice, ProductName")]Product product) {
NORTHWNDEntities entities = new NORTHWNDEntities();
if (ModelState.IsValid) {
var dbProduct = entities.ProductSet.First(p => p.ProductID == id);
dbProduct.ProductName = product.ProductName;
dbProduct.UnitPrice = product.UnitPrice;
entities.SaveChanges();
}
/* Neither of these work */
product.ProductName = "This has no effect";
ViewData["ProductName"] = "This has no effect either";
return View(product);
}
有人知道实现这一点的正确方法吗?值存储在
ModelState
中
这应该满足您的要求:
ModelState.SetModelValue("ProductName", "The new value");
不过我不建议你这么做。。。正确的方法是遵循以下步骤
HTHs,查尔斯 编辑:更新以反映在更改模型之前设置@Gary发现的
ModelState
值的更好方法
...
ModelState.Clear()
dbProduct.ProductName = product.ProductName;
dbProduct.UnitPrice = product.UnitPrice;
...
在进一步研究之后,我解释了为什么以下代码在操作中没有效果:
product.ProductName = "This has no effect";
ViewData["ProductName"] = "This has no effect either";
我的视图使用HTML帮助程序:
<% Html.EditorFor(x => x.ProductName);
或者,要清除ModelState值,请执行以下操作:
ModelState.SetModelValue("ProductName", null);
您可以创建一个扩展方法来简化语法:
public static class ModelStateDictionaryExtensions {
public static void SetModelValue(this ModelStateDictionary modelState, string key, object rawValue) {
modelState.SetModelValue(key, new ValueProviderResult(rawValue, String.Empty, CultureInfo.InvariantCulture));
}
}
然后你可以简单地写:
ModelState.SetModelValue("ProductName", "Your new value");
有关更多详细信息,请参阅。这将触发模型在简单条件下重新评估:
ModelState.Clear();
model.Property = "new value";
TryValidateModel(model);
顾名思义,ModelState.Clear()会删除整个模型状态,这是不可取的。谢谢——该解决方案确实有效,尽管我需要为密钥指定“product.ProductName”,而不仅仅是“ProductName”。在我的真实场景中(示例代码是为了演示而编写的),我需要在验证失败后清除一个特定的值,所以我不想重定向。当验证成功时,我将遵循您推荐的PRG模式。再次感谢。谢谢,这非常有用。我用它来删除输入错误的信用卡号后重新显示的信用卡号。我很惊讶这个任务是如此的不平凡/不直观。这就是我想要的,谢谢你的帮助。
ModelState.Clear();
model.Property = "new value";
TryValidateModel(model);