Почему значение, которое я обновляю в моей модели внутри контроллера MVC3, не отображается на клиенте? - PullRequest
5 голосов
/ 15 апреля 2011

У меня есть действие контроллера UpdateCustomer(CustomerDto customer), которое возвращает PartialViewResult с моделью, которая также является CustomerDto:

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

На мой взгляд, у меня есть следующая строка:

@Html.TextBoxFor(model => model.Name)

Пока все хорошо. На мой взгляд, я выполняю асинхронную публикацию этого метода действия, механизм связывания модели выполняет свою работу, и я могу обновить клиента в базе данных. Затем я хочу визуализировать клиента обновленный . Например, я хотел бы изменить имя клиента в моем контроллере. Однако то, что визуализируется, это всегда свойства из опубликованного 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);

Как видите, attemptedValue происходит от ModelState. Он содержит старое значение для CustomerDto.Name (значение, которое было проведено для действия контроллера).

Если это функция, почему она работает таким образом? И есть ли способ обойти это? Я ожидаю, что если я обновлю свою модель, обновление будет выполнено, а не старое значение, которое я опубликовал.

1 Ответ

5 голосов
/ 15 апреля 2011

Ну да, это функция (ModelState всегда проверяется перед фактической моделью), вы можете очистить ModelState или обновить только то значение, которое вам нужно:

ModelState["Name"].Value = updatedCustomer.Name;
...