ASP.net MVC 2.0 использует ту же форму для добавления и редактирования - PullRequest
3 голосов
/ 17 февраля 2011

Я хотел бы использовать то же представление для редактирования сообщения в блоге и добавления сообщения в блоге.Однако у меня возникла проблема с идентификатором.При добавлении сообщения в блоге мне не нужно публиковать значение идентификатора.Когда привязка модели связывает значения формы с объектом BlogPost в контроллере, она автоматически генерирует идентификатор в сущности структуры сущности.

Когда я редактирую сообщение в блоге, мне действительно нужно скрытое поле формы, чтобысохранить идентификатор, чтобы он сопровождал следующую запись формы.Вот представление, которое у меня есть прямо сейчас.

<% using (Html.BeginForm("CommitEditBlogPost", "Admin"))
       { %>
            <% if (Model != null)
               { %>
                    <%: Html.HiddenFor(x => x.Id)%>
            <% } %>
            Title:<br />
            <%: Html.TextBoxFor(x => x.Title, new { Style = "Width: 90%;" })%>
            <br />
            <br />
            Summary:<br />
            <%: Html.TextAreaFor(x => x.Summary, new { Style = "Width: 90%; Height: 50px;" }) %>
            <br />
            <br />
            Body:<br />
            <%: Html.TextAreaFor(x => x.Body, new { Style = "Height: 250px; Width: 90%;" })%>
            <br />
            <br />
            <input type="submit" value="Submit" />
    <% } %>

Прямо сейчас проверка, идет ли модель в NULL, - отличный способ узнать, редактирую ли я сообщение в блоге или добавляю, потому что когда я 'Если добавить один, он будет нулевым, так как он еще не был создан.Проблема возникает, когда возникает ошибка и объект недействителен.Когда контроллер отображает форму после неверной модели, Model != null оценивается как ложное, даже если мы редактируем сообщение, и модель явно существует.Если при добавлении сообщения я отображаю скрытое поле ввода для идентификатора, я получаю сообщение о том, что идентификатор не может быть нулевым.

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ: Я пошел с ответом OJ на этот вопрос, однако я обнаружил кое-что, что заставило меня чувствовать себя глупо, и я хотел поделиться этим на тот случай, если у кого-то возникла подобная проблема.Страница, которая добавляет / редактирует блоги, даже не нуждается в скрытом поле для идентификатора.Причина в том, что когда я иду, чтобы добавить блог, я делаю GET для этого относительного URL BlogProject/Admin/AddBlogPost

Этот URL не содержит идентификатора, а метод действия просто отображает страницу.Страница делает POST к тому же URL при добавлении сообщения в блоге.Входящий объект BlogPost заполняется привязкой модели и имеет нулевой идентификатор, который будет сгенерирован EF во время изменений сохранения.

Теперь при редактировании записи в блоге URL-адрес BlogProject/Admin/EditBlogPost/{Id} Этот URL-адрес содержит идентификаторсообщение в блоге, и поскольку страница публикуется по тому же URL-адресу, идентификатор идет вместе с POST для метода действия, выполняющего редактирование.

Единственная проблема, с которой я столкнулся, заключается в том, что методы действия не могут иметьидентичные подписи.

[HttpGet]
public ViewResult EditBlogPost(int Id)
{

}

[HttpPost]
public ViewResult EditBlogPost(int Id)
{

}

Компилятор будет кричать на вас, если вы попытаетесь использовать эти два метода выше.Слишком удобно, чтобы идентификатор был отправлен обратно при выполнении Html.BeginForm() без аргументов для действия или контроллера.Поэтому вместо того, чтобы изменить имя метода POST, я просто изменил аргументы, добавив FormCollection.Например:

[HttpPost]
public ViewResult EditBlogPost(int Id, FormCollection formCollection)
{
     // You can then use formCollection as the IValueProvider for UpdateModel()
     // and TryUpdateModel() if you wish. I mean, you might as well use the
     // argument since you're taking it.
}

Переменная formCollection заполняется с помощью привязки модели тем же содержимым, что и Request.Form по умолчанию.Вам не нужно использовать эту коллекцию для UpdateModel() или TryUpdateModel(), но я так и сделал, поэтому не чувствовал, что эта коллекция бессмысленна, поскольку на самом деле она просто отличает сигнатуру метода от аналога GET.

Спасибо за помощь, ребята!Дайте мне знать, если вы найдете лучший способ сделать эту работу.Единственное, что меня беспокоит, - это добавление ненужной переменной, чтобы отличить сигнатуру метода.

Ответы [ 2 ]

2 голосов
/ 17 февраля 2011

Несколько вариантов:

  • Создайте Id свойство Nullable и проверьте HasValue.
  • Добавьте какой-нибудь индикатор mode к своему ViewData и покажите скрытое поле в зависимости от значения.
  • Поместите тело формы в частичное представление и включите его в два разных представления, одно с другим, а другое без скрытого поля.
2 голосов
/ 17 февраля 2011

То, что я сделал в своем проекте, следующее:

  • Имеет отдельное действие и представление для редактирования и добавления
  • Вместо этого передайте идентификатор объекта в URL для редактирования.в скрытом поле
  • Используйте шаблон общего редактора для объекта, чтобы избежать написания одного и того же стандартного кода дважды

Если вы сделаете это правильно, представления для добавления и редактирования будут очень маленькими.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...