Mr *_*rok 114 asp.net-mvc post-redirect-get modelstate
任何人都可以给我一个关于ModelState在Asp.net MVC中的角色的简洁定义(或者链接到一个).特别是我需要知道在什么情况下打电话是必要的或可取的ModelState.Clear().
有点开放了 ......对不起,我想如果告诉你我在做什么可能会有所帮助:
我在一个名为"Page"的控制器上有一个Edit of Action.当我第一次看到表单更改页面的详细信息时,所有内容都很好地加载(绑定到"MyCmsPage"对象).然后,我单击一个按钮,为MyCmsPage对象的某个字段(MyCmsPage.SeoTitle)生成一个值.它生成正常并更新对象,然后我返回动作结果与新修改的页面对象,并期望相关的文本框(使用渲染<%= Html.TextBox("seoTitle", page.SeoTitle)%>)更新...但是它显示了加载的旧模型的值.
我通过使用来解决它,ModelState.Clear()但我需要知道它为什么/如何工作所以我不只是盲目地做.
的PageController:
[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
// add the seoTitle to the current page object
page.GenerateSeoTitle();
// why must I do this?
ModelState.Clear();
// return the modified page object
return View(page);
}
Run Code Online (Sandbox Code Playgroud)
ASPX:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
<div class="c">
<label for="seoTitle">
Seo Title</label>
<%= Html.TextBox("seoTitle", page.SeoTitle)%>
<input type="submit" value="Generate Seo Title" name="submitButton" />
</div>
Run Code Online (Sandbox Code Playgroud)
Tim*_*ott 134
我认为是MVC中的一个错误.我今天花了几个小时努力解决这个问题.
鉴于这种:
public ViewResult SomeAction(SomeModel model)
{
model.SomeString = "some value";
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
视图使用原始模型呈现,忽略更改.所以我想,也许它不喜欢我使用相同的模型,所以我尝试这样:
public ViewResult SomeAction(SomeModel model)
{
var newModel = new SomeModel { SomeString = "some value" };
return View(newModel);
}
Run Code Online (Sandbox Code Playgroud)
并且视图仍然使用原始模型呈现.奇怪的是,当我在视图中放置断点并检查模型时,它具有更改的值.但响应流具有旧值.
最终我发现了你做过的同样的工作:
public ViewResult SomeAction(SomeModel model)
{
var newModel = new SomeModel { SomeString = "some value" };
ModelState.Clear();
return View(newModel);
}
Run Code Online (Sandbox Code Playgroud)
按预期工作.
我不认为这是一个"功能",是吗?
Mat*_*caj 42
更新:
View()从POST操作返回.如果操作成功,请改用PRG并重定向到GET.View()从POST动作,连续做表单验证,并做到这一点的方式MVC设计使用内置的助手.如果你这样做,那么你不应该使用.Clear()ModelState因为您无论如何都不应该使用它.老答案:
MVC中的ModelState主要用于描述模型对象的状态,主要与该对象是否有效有关.本教程应该解释很多.
通常,您不需要清除ModelState,因为它由MVC引擎为您维护.在尝试遵守MVC验证最佳实践时,手动清除它可能会导致意外结果.
您似乎正在尝试为标题设置默认值.这应该在模型对象被实例化时(在某个地方或在对象本身 - 无参数的ctor中),在get动作上进行,以便它第一次或完全在客户端(通过ajax或其他)下载到页面这样看起来好像用户输入了它,然后它返回了已发布的表单集合.一些如何在接收表单集合时添加此值的方法(在POST操作//编辑中)导致这种奇怪的行为可能导致.Clear() 看起来适合您.相信我 - 你不想使用clear.尝试其他一个想法.
小智 17
如果要清除单个字段的值,那么我发现以下技术很有用.
ModelState.SetModelValue("Key", new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture));
Run Code Online (Sandbox Code Playgroud)
注意:将 "Key"更改为要重置的字段的名称.
那么ModelState基本上在验证方面保持了模型的当前状态
ModelErrorCollection:表示模型尝试绑定值时的错误.恩.
TryUpdateModel();
UpdateModel();
Run Code Online (Sandbox Code Playgroud)
或者像ActionResult中的参数
public ActionResult Create(Person person)
Run Code Online (Sandbox Code Playgroud)
ValueProviderResult:保存有关尝试绑定到模型的详细信息.恩.AttemptedValue,Culture,RawValue.
必须谨慎使用Clear()方法,因为它可能导致意外结果.并且您将失去ModelState的一些不错的属性,如AttemptedValue,MVC在后台使用它来在出错时重新填充表单值.
ModelState["a"].Value.AttemptedValue
Run Code Online (Sandbox Code Playgroud)
小智 6
我有一个实例,我想更新一个总结形式的模型,并且不想因为性能原因而"重定向到行动".隐藏字段的先前值保留在我更新的模型上 - 导致各种问题!
几行代码很快就确定了我想删除的ModelState中的元素(在验证之后),因此在表单中使用了新值: -
while (ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult")).Value != null)
{
ModelState.Remove(ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult")));
}
Run Code Online (Sandbox Code Playgroud)
我们很多人似乎都被这个咬了,虽然这种情况发生的原因是有道理的,我需要一种方法来确保模型上的值显示出来,而不是ModelState.
有些人建议ModelState.Remove(string key),但是key应该是什么并不明显,特别是对于嵌套模型.以下是我提出的一些方法来帮助解决这个问题.
该RemoveStateFor方法将获取ModelStateDictionary所需属性的a ,Model和表达式,并将其删除.HiddenForModel可以在View中使用,仅使用Model中的值创建隐藏的输入字段,方法是先删除其ModelState条目.(这可以很容易地扩展为其他帮助扩展方法).
/// <summary>
/// Returns a hidden input field for the specified property. The corresponding value will first be removed from
/// the ModelState to ensure that the current Model value is shown.
/// </summary>
public static MvcHtmlString HiddenForModel<TModel, TProperty>(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression)
{
RemoveStateFor(helper.ViewData.ModelState, helper.ViewData.Model, expression);
return helper.HiddenFor(expression);
}
/// <summary>
/// Removes the ModelState entry corresponding to the specified property on the model. Call this when changing
/// Model values on the server after a postback, to prevent ModelState entries from taking precedence.
/// </summary>
public static void RemoveStateFor<TModel, TProperty>(this ModelStateDictionary modelState, TModel model,
Expression<Func<TModel, TProperty>> expression)
{
var key = ExpressionHelper.GetExpressionText(expression);
modelState.Remove(key);
}
Run Code Online (Sandbox Code Playgroud)
从这样的控制器调用:
ModelState.RemoveStateFor(model, m => m.MySubProperty.MySubValue);
Run Code Online (Sandbox Code Playgroud)
或者从这样的观点来看:
@Html.HiddenForModel(m => m.MySubProperty.MySubValue)
Run Code Online (Sandbox Code Playgroud)
它用于System.Web.Mvc.ExpressionHelper获取ModelState属性的名称.
| 归档时间: |
|
| 查看次数: |
102349 次 |
| 最近记录: |