Как работает @Html.BeginForm()?
Я очень новичок в ASP.NET, только что начал учебник MVC сегодня на asp.net. Я пришел сюда http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-methods-and-edit-view
До сих пор так хорошо, проблема:
В моем представлении у меня есть следующий код
(Модель настроена на представление с помощью @model MyFirstMVC4.Models.Movie)
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Movie</legend>
@Html.HiddenFor(model => model.ID)
//... bla bla html input
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
My MovieController
// Shows the view
public ActionResult Edit(int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
//
// POST: /Movie/Edit/5
[HttpPost] // Handles the view above
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
И вот вопрос: как он передает объект фильма методу POST выше?! Когда я наблюдаю клиентскую сторону, есть
<form action = "/Movie/Edit/1" ... />
Здесь я не понимаю, почему action = url той же самой страницы просмотра?! 1
Также на стороне сервера есть только Html.BeginForm():(
Как он понимает, какой метод действия следует отправлять и какие параметры маршрута должны пройти?
Он работает, я просто не знаю, почему
Ответы
Ответ 1
Версия BeginForm
в коде,
без параметров, отправляет HTTP POST на текущий URL, поэтому, если представление является ответом на
/Movie/Edit/5
, тег формы открытия будет выглядеть следующим образом:
< form action="/Movie/Edit/5" method="post">
Помощник HTML BeginForm подскажет механизму маршрутизации, как достичь действия "Изменить"
MovieController. За кулисами он использует метод GetVirtualPath на маршрутах
свойство, выставленное с помощью RouteTable - там, где ваше веб-приложение зарегистрировало все его маршруты в
global.asax. Если вы сделали все это без помощника HTML, вам нужно написать все следующее
код:
@{
var context = this.ViewContext.RequestContext;
var values = new RouteValueDictionary{
{ "controller", "movie" }, { "action", "edit" }
};
var path = RouteTable.Routes.GetVirtualPath(context, values);
}
<form action="@path.VirtualPath" method="get">
...
</form>
Вы спросили, как передается объект фильма. Это называется привязкой модели .
Когда у вас есть действие с параметром, среда выполнения MVC использует привязку модели для построения
параметр. Вы можете иметь несколько связующих устройств, зарегистрированных в среде MVC для разных типов
моделей, но рабочая лошадка по умолчанию будет DefaultModelBinder
.
В случае фильма
объект, связующее устройство по умолчанию проверяет фильм и находит все доступные свойства фильма
для привязки. Следуя соглашению об именах, которое вы рассмотрели ранее, связующее устройство по умолчанию может автоматически преобразовывать и перемещать значения из запроса в объект фильма (модельное связующее может
также создайте экземпляр объекта для заполнения).
Другими словами, когда модельное связующее видит, что у фильма есть свойство Title, он ищет значение
названный "Заголовок" в запросе. Обратите внимание, что связующее устройство выглядит "в запросе", а не "в форме
коллекции ". В связующем модели используются компоненты, известные как поставщики стоимости, для поиска значений в
разные области запроса.
Модельное связующее может просматривать данные маршрута, строку запроса и форму
коллекции, и вы можете добавить поставщиков услуг по назначению, если вы этого пожелаете.
Ответ 2
Когда вы вызываете BeginForm()
без каких-либо параметров, по умолчанию используется тот же контроллер/действие, используемый для отображения текущей страницы. Предполагается, что у вас будет действие с правильным именем на контроллере, который будет принимать обратные передачи (что вы делаете). Для этого используется RouteValues
.
Он автоматически связывает каждое управление вводом (по имени) с параметрами действия, принимающего обратную передачу - или в вашем случае - свойствами параметра объекта для действия, принимающего обратную передачу.
Ответ 3
Атрибут [HttpPost]
присваивается действию, которое вы хотите вызвать в POST, из формы.
чтобы понять, как работает @using (Html.BeginForm())
, вам нужно знать, на какой странице он уже включен. использование @using (Html.BeginForm())
в 2 разных представлениях вернется к двум различным контроллерам
Ответ 4
Мы можем создавать формы, набирая простые html или html-помощники.
Один из них Html.BeginForm(); это немного странно, потому что вы действительно можете обернуть его в оператор using, потому что этот конкретный помощник возвращает объект, который реализует IDisposable в С#. Сначала он записывается с открывающим тегом. И внизу, когда сгенерированные вызовы кода выставляются на этом объекте, то есть когда он будет выписывать тег закрывающей формы. Поэтому BeginForm дает мне объект, который выписывает мой тег формы открытия и мое закрытие с тега. После этого вы ни о чем не беспокоитесь, вы можете просто сфокусироваться на ярлыках и входах