Просмотр данных модели, переопределяющих данные модели в ASP.NET MVC - PullRequest
0 голосов
/ 13 октября 2009

Я хочу создать пользователя следующим образом.

<% using (Html.BeginForm("SaveUser", "Security")) {%>
    <p>
        <label for="UserName">UserName:</label>
        <%= Html.TextBox("UserName") %>
        <%= Html.ValidationMessage("UserName", "*") %>
    </p>
    <p>
        <label for="Password">Password:</label>
        <%= Html.TextBox("Password") %>
        <%= Html.ValidationMessage("Password", "*") %>
    </p>
    <p>
        <input type="submit" value="Create" />
    </p>
<}%>

При нажатии кнопки «Создать» форма HTML отправляется в действие под названием «SaveUser», которое принимает глагол «POST» только следующим образом.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveUser( UserViewModel user)
{
    //user.Id is zero before save
    //Save the user.  Code omitted...
    //user.Id is now greater than zero
    //redirect to edit user view
    return View("EditUser", user );
}

После сохранения пользователя страница перенаправляется в представление «EditUser» с помощью

<p>
    <label for="Id">Id:</label>
    <%= Html.Hidden("Id", Model.Id)%>
</p>

Вот проблема: значение для скрытого поля все равно показывалось как ноль. Model.Id больше нуля. Казалось, что-то еще переопределяет значение представления модели. ViewDataDictonary был подозреваемым. Поэтому перед возвратом представления в действии добавляется строка следующим образом.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveUser( UserViewModel user)
{
    //user.Id is zero before save
    //Save the user.  Code omitted...
    //user.Id is now greater than zero

    //clear the view data
    ViewData = new ViewDataDictionary();
    //redirect to edit user view
    return View( "EditUser", user);
}

Конечно, это сработало. Скрытое поле теперь имеет значение правильного идентификатора пользователя.

Мы нашли способ лечения симптома, но где источник проблемы?

Мне не нравится идея очищать словарь данных представления каждый раз перед возвратом другого представления.

1 Ответ

4 голосов
/ 13 октября 2009

После успешной операции вы должны использовать

return RedirectToAction("EditUser", new { id = user.Id });

или аналогичный код. Текущий ModelState используется для генерации представления, а связыватель модели не связывает идентификатор.

[Bind(Exclude = "Id")] также может работать, но перенаправление создает новую страницу (без использования текущего ModelState) и является лучшим решением.

Edit:

Если вы не хотите связывать весь объект, вы должны использовать [Bind (Exclude)], или вы просто должны определить SaveUser как SaveUser(string userName, string password) и построить объект UserViewModel самостоятельно. Это избавит вас от ошибок, сгенерированных связывателем модели и значениями модели, которые вы не знаете, откуда взялись.

...