2013-05-24 3 views
16

Я очень новичок в 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Как работает @ Html.BeginForm()?

До сих пор так хорошо, проблема:

На мой взгляд, у меня есть следующий код (модель устанавливается в представлении с @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> 
} 

Мой 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); 
    } 

И вот вопрос - Как, черт возьми, это передать объект Movie методу POST выше ?! Когда я наблюдаю на стороне клиента есть

<form action = "/Movie/Edit/1" ... /> 

Вот я не понимаю, почему действие = URL из той же странице просмотра?! 1 Кроме того, на стороне сервера есть только Html.BeginForm() :( Как это понять, какой из методов действия, чтобы отправлять и какой маршрут параметры пройти? он работает, я просто не знаю, почему

ответ

35

Версия BeginForm в коде, без параметров, отправляет POST HTTP к текущему URL, так что если представление является ответом на /Movie/Edit/5, открытие формы тег будет выглядеть следующим образом: < form action="/Movie/Edit/5" method="post">

помощник BeginForm HTML просит механизм маршрутизации, как достичь Изменить действие 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, он ищет значение с именем «Заголовок» в запросе.Обратите внимание на то, что модельное связующее выглядит «в запросе», а не «в форме ». Модельное связующее использует компоненты, известные как поставщики стоимости, для поиска значений в различных областях запроса. Модель связующего может просматривать данные маршрута, строку запроса и форму , и вы можете добавить поставщиков специализированных значений, если вы этого желаете.

+0

Играя с переопределениями для '@ Html.BeginForm' - я поставил' Html.BeginForm («Edit», «Movies», FormMethod.Post) '. Заметьте, что я не предоставил третью часть id пути. Однако в полученной разметке она есть: '/ Movies/Edit/4'. Как оно работает? Если я suppy 'Html.BeginForm (« Удалить »,« Фильмы », FormMethod.Post), в результате HTML не будет' id': '/ Movies/Delete'. – mmcrae

4

[HttpPost] атрибут дается к действию, который вы хотите назвать на POST представить формы

чтобы понять, как @using (Html.BeginForm()) работает, вам нужно знать, на какой странице он уже включен. используя @using (Html.BeginForm()) в 2-х разных взглядов вернется к двум различным контроллерам

9

Когда вы вызываете BeginForm() без каких-либо параметров, по умолчанию используется тот же контроллер/действие, что и для отображения текущей страницы. Предполагается, что у вас будет действие с правильным именем на контроллере, который будет принимать обратные передачи (что вы делаете). Для этого используется RouteValues.

Он автоматически связывает каждое управление вводом (по имени) с параметрами действия, принимающего обратную передачу - или в вашем случае - свойствами параметра объекта для действия, принимающего обратную передачу.

0

Мы можем создавать формы, набирая простые html или html-помощники. Один из них Html.BeginForm(); это немного странно, потому что вы действительно можете обернуть его в оператор using, потому что этот конкретный помощник возвращает объект, который реализует IDisposable в C#. Сначала он записывается с открывающим тегом. И внизу, когда сгенерированные вызовы кода выставляются на этом объекте, вот когда он будет выписывать тег закрывающей формы. Поэтому BeginForm дает мне объект, который выписывает мой тег формы открытия и мое закрытие с тега. После этого вы ни о чем не беспокоитесь, вы можете просто сфокусироваться на ярлыках и входах

Смежные вопросы