为什么我在MVC3控制器内的模型中更新的值未在客户端上呈现?

Ron*_*erg 5 asp.net-mvc partial-views razor asp.net-mvc-3

我有一个控制器动作UpdateCustomer(CustomerDto customer),返回PartialViewResult一个模型,该模型也是CustomerDto:

[HttpPost]
public PartialViewResult UpdateCustomer(CustomerDto customer)
{
    CustomerDto updatedCustomer = _customerService.UpdateCustomer(customer);
    updatedCustomer.Name = "NotThePostedName";
    return PartialView("CustomerData", updatedCustomer);
}
Run Code Online (Sandbox Code Playgroud)

在我看来,我有以下几行:

@Html.TextBoxFor(model => model.Name)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.在我看来,我对这个动作方法进行了异步发布,模型绑定器完成了它的工作,我可以更新数据库中的客户.然后我想将更新的客户呈现给客户.例如,我想更改控制器中的客户名称.但是,渲染的内容始终是已发布customer的属性,而不是来自的属性updatedCustomer.

我决定在我的项目中包含MVC3源代码,看看到底发生了什么.它似乎是MVC3的一个特征(错误?),它总是取值ViewData.ModelState而不是来自的值ViewData.Model.

这发生在第366-367行System.Web.Mvc.Html.InputExtensions:

string attemptedValue =
    (string) htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value",
    attemptedValue ?? ((useViewData)
        ? htmlHelper.EvalString(fullName)
        : valueParameter), isExplicitValue);
Run Code Online (Sandbox Code Playgroud)

如你所见,attemptedValue来自ModelState.它包含旧值CustomerDto.Name((发布到控制器操作的值).

如果这是一个功能,为什么这样做?有没有办法解决它?我希望如果我更新我的模型,会更新更新,而不是我发布的旧值.

tpe*_*zek 5

是的,它是一个功能(ModelState始终在实际模型之前检查),您可以清除ModelState,或只更新您需要的值:

ModelState["Name"].Value = updatedCustomer.Name;
Run Code Online (Sandbox Code Playgroud)