Каков наилучший подход к созданию формы, которая используется для создания новых моделей и редактирования существующих моделей?
Есть ли какие-то уроки, которые люди могут указать мне в сторону?
Каков наилучший подход к созданию формы, которая используется для создания новых моделей и редактирования существующих моделей?
Есть ли какие-то уроки, которые люди могут указать мне в сторону?
Не используйте одно и то же действие контроллера . New = HTTP PUT; edit = HTTP POST, так что две разные вещи. Однако оба действия могут и должны быть на одном контроллере.
Мне нравится идея использования пользовательского элемента управления для общих функций (например, редакторов) и обертывания этого в представлениях конкретных действий для вещей, которые должны появляться только на новом или редактировании, но не на обоих.
NerdDinner действительно покажет путь.
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>" MasterPageFile="~/Views/Shared/Site.Master" %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Host a Nerd Dinner
</asp:Content>
<asp:Content ID="Create" ContentPlaceHolderID="MainContent" runat="server">
<h2>Host a Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Models.Dinner>"
MasterPageFile="~/Views/Shared/Site.Master" %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
Edit: <%:Model.Title %>
</asp:Content>
<asp:Content ID="Edit" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
<%@ Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.Dinner>" %>
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<% Html.EnableClientValidation(); %>
<%: Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm())
{ %>
<fieldset>
<div id="dinnerDiv">
<%:Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
</div>
<div id="mapDiv">
<%: Html.EditorFor(m => m.Location) %>
</div>
</fieldset>
<% } %>
Учтите, что в этой форме используется Html.EditorForModel()
, который является инновационным методом для генерирования всех полей одновременно, и перед его использованием вы должны изучить его недостатки. Но вы можете легко взять остальную часть примера, чтобы отделить вашу общую форму от представлений создания и редактирования.
Наконец, вы можете просмотреть код контроллера здесь, если вы заинтересованы.
Предположения
Это полезно для пользователя, чтобы видеть различные URL-адреса для разных действий в браузере. Например, "/pages/create" и "/pages/edit/1".
Для разработчика полезно иметь только одну пару действий + для создания и редактирования страниц, потому что они обычно очень похожи. (Кроме того, хорошо иметь один контроллер на сущность.)
Решение
Регистрация маршрутов по умолчанию - '{controller}/{action}/{id}' Мы можем добавить еще два правила до:
{controller}/create (должен указывать на действие CreateOrEdit)
{controller}/edit/{id} (должен также указывать на действие CreateOrEdit)
У нас может быть что-то вроде этого:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "Create",
url: "{controller}/create",
defaults: new { controller = "Default", action = "CreateOrEdit" }
);
routes.MapRoute(
name: "Edit",
url: "{controller}/edit/{id}",
defaults: new { controller = "Default", action = "CreateOrEdit" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
Итак, теперь и запросы создания, и редактирования будут обработаны действием CreateOrEdit. Другие будут работать по умолчанию.
Далее мы должны добавить действие CreateOrEdit для HttpGet и HttpPost в нашем контроллере:
[HttpGet]
public ActionResult CreateOrEdit(int? id)
{
return this.View(new CreateOrEditViewModelBuilder(this).Build(id));
}
[HttpPost]
public ActionResult CreateOrEdit(CreateOrEditViewModel сreateOrEditViewModel)
{
if (this.ModelState.IsValid)
{
Page page = new CreateOrEditViewModelMapper(this).Map(сreateOrEditViewModel);
if (сreateOrEditViewModel.Id == null)
this.UnitOfWork.GetRepository<IPageRepository>().Create(page);
else this.UnitOfWork.GetRepository<IPageRepository>().Edit(page);
this.UnitOfWork.Save();
return this.RedirectToAction("Index");
}
return this.View(сreateOrEditViewModel);
}
И последнее мы должны добавить представление с именем "CreateOrEdit". Мы можем пользователь 'this.Model.Id == null' знать, будем ли мы создавать или редактировать.
Результат
Теперь у нас нет дубликата кода и могут иметь очевидные URL-адреса, например:
/pages (чтобы просмотреть все страницы)
/pages/create (для создания новой страницы)
/pages/edit/1 (для редактирования существующей страницы)
/pages/delete/1 (для удаления существующей страницы)
Я надеюсь, что это поможет кому-то!
Это может быть (должен быть IMO) один контроллер, но разные действия контроллера. Также убедитесь, что у вас есть соответствующие HTTP-глаголы, связанные с соответствующими действиями. Следуйте инструкциям, опубликованным E Rolnicki, и вы будете в пути!
Счастливое кодирование!!
это не всегда лучшая практика, потому что это зависит от случая, вот как я это сделал
1/ я объединил действия контроллера для создания и редактирования
public PartialViewResult Creedit(string id = null)
{
if (id == null)
{
// Create new record (this is the view in Create mode)
return PartialView();
}
else
{
// Edit record (view in Edit mode)
Client x = db.ClientSet.Find(id);
if (x == null) { return PartialView("_error"); }
// ...
return PartialView(x);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Creedit(Client x)
{
if (x.id == null)
{
// insert new record
}
else
{
// update record
}
}
2/ я объединил редактирование и создаю виды в одном представлении, я вызываю Creedit
// if you need to display something unique to a create view
// just check if the Model is null
@if(Model==null){
}
поэтому у меня есть 1 просмотр и 2 действия (1 сообщение и 1 получение) вместо 2 просмотров и 4 действия.
Я помещаю форму в пользовательский элемент управления - скажем, Views/Shared/WidgetForm.ascx. Я поместил все поля формы в этот пользовательский элемент управления, но не сам тег формы.
Представления, например Views/Widgets/New.aspx и Views/Widgets/Edit.aspx, содержат теги формы и все "окружения" - инструкции для заполнения формы, названия страниц и т.д. Затем они включают пользовательский элемент управления внутри тегов формы.
Пользовательский элемент управления просто принимает объект Widget и отображает форму, основанную на результатах. Таким образом, использование разумных настроек по умолчанию в новых вариантах виджета становится важным, но вы все равно это делаете, правильно?;)
У меня есть система, которая, я думаю, работает очень хорошо. В моих общих представлениях у меня есть две общие формы: Edit.aspx и New.aspx
Затем в моей конкретной папке просмотра у меня есть элемент управления с именем EditItems.ascx
В моей форме редактирования у меня есть теги формы и конкретные кнопки для редактирования, а в новой форме у меня есть теги формы и специальные кнопки для новых. В каждом из них есть Html.RenderPartial( "EditItems.ascx" )
Таким образом, ваш пользовательский элемент управления может быть строго типизирован, и все же вы повторно используете внешний вид редактирования и новые страницы.
Теперь в некоторых случаях ваша новая страница может иметь другой макет, чем на странице редактирования. В этом случае просто добавьте "Edit.aspx" в вашу конкретную папку просмотра.
Я нахожу, что это дает мне лучшую комбинацию повторного использования, но при этом позволяет полностью настраивать, если мне это нужно. А что касается действий контроллера, то они должны быть отдельными действиями.
Если у объекта есть какой-то внутренний закрытый ключ (например, член "id", который всегдa > 0), вы можете использовать /Edit/ 0 вместо/Create
Я использую что-то вроде
[HttpGet]
public ActionResult EntityEdit(Guid id)
{
return View();
}
и
[HttpGet]
public ActionResult EntityCreate()
{
return View("EntityEdit");
}
Это работает нормально.