2013-05-24 13 views
16

Jestem bardzo nowy w ASP.NET, właśnie rozpocząłem tutorial MVC dzisiaj na asp.net. Mam tu http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-methods-and-edit-viewJak działa funkcja @ Html.BeginForm()?

tej pory tak dobrze, problem:

moim zdaniem mam następujący kod (Model jest ustawiony na widoku z @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> 
} 

Moja 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); 
    } 

I tu jest pytanie - Jak do cholery to przekazać obiekt filmu metody POST powyżej ?! Kiedy obserwujemy po stronie klienta jest

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

Tutaj nie rozumiem dlaczego action = url tej samej stronie widoku?! 1 także po stronie serwera jest tylko Html.BeginForm() :( Jak to uświadomić, jaka metoda działania odpowiedzieć i co trasa parametry przekazać? to działa, po prostu nie wiem dlaczego

Odpowiedz

35

Wersja BeginForm w kodzie, bez parametrów, wysyła HTTP POST do aktualnego adresu URL, więc jeśli widok jest odpowiedzią na /Movie/Edit/5, tag forma otwarcia będzie wyglądać następująco: < form action="/Movie/Edit/5" method="post">

pomocnik BeginForm HTML pyta silnik routingu, jak dotrzeć do edycji działanie MovieController. Za kulisami używa metody o nazwie GetVirtualPath na właściwości Routes ujawnionej przez RouteTable - w tym miejscu Twoja aplikacja internetowa zarejestrowała wszystkie trasy w global.asax. Jeśli tak to wszystko bez pomocnika HTML, trzeba by napisać cały kod następujące:

@{ 
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> 

Pytałeś jak jest obiektem filmu minęło. To się nazywa model wiązania. Po wykonaniu akcji z parametrem środowisko wykonawcze MVC korzysta ze spoiwa modelu w celu utworzenia parametru . Możesz mieć wiele modeli segregatorów zarejestrowanych w środowisku wykonawczym MVC dla różnych modeli modeli, ale domyślnym koniem roboczym będzie DefaultModelBinder.

W przypadku obiektu Movie domyślny segregator modelu sprawdza film i znajduje wszystkie dostępne właściwości filmu dla wiązania. Zgodnie z konwencją nazewnictwa, którą sprawdziłeś wcześniej, domyślny segregator modelu może automatycznie konwertować i przenosić wartości z żądania do obiektu filmu (spoina modelu może również utworzyć instancję obiektu do wypełnienia). Innymi słowy, gdy segregator modelu widzi film ma właściwość Tytuł, szuka wartości o nazwie "Tytuł" w żądaniu.Zwróć uwagę, że segregator modelu wygląda "w żądaniu", a nie "w formularzu kolekcja ." Segregator modelu używa składników znanych jako dostawca wartości do wyszukiwania wartości w różnych obszarach żądania w . Segregator modelu może przeglądać dane trasy, ciąg zapytania i kolekcję o wartości , a jeśli chcesz, możesz dodać dostawców wartości niestandardowych.

+0

Odtwarzanie z przesłonięciami dla '@ Html.BeginForm' - Dostarczyłem' Html.BeginForm ("Edytuj", "Filmy", FormMethod.Post) '. Zauważ, że nie dostarczyłem trzeciej "id" części trasy. Jednak w wynikowym znaczniku jest: '/ Movies/Edit/4'. Jak to robi? Jeśli suppy 'Html.BeginForm (" Delete "," Movies ", FormMethod.Post)', wynikowy HTML nie ma 'id':'/Movies/Delete'. – mmcrae

4

[HttpPost] atrybut przywiązuje się do działań, które chcesz nazwać na stanowisku przedstawić formularza:

aby zrozumieć, jak @using (Html.BeginForm()) działa, musisz wiedzieć, na której stronie już jest. stosując @using (Html.BeginForm()) w 2 różnych poglądów wróci do dwóch różnych kontrolerów

9

Gdy wywołujesz BeginForm() bez żadnych parametrów, domyślnie jest używany ten sam kontroler/akcja używana do renderowania bieżącej strony. Zakłada on, że będziesz miał akcję z poprawną nazwą na swoim kontrolerze, która będzie akceptować posty zwrotne (które robisz). Do tego celu używa on RouteValues.

Automatycznie wiąże każdą kontrolkę wejściową (według nazwy) z parametrami akcji akceptującej odświeżenie - lub w twoim przypadku właściwości parametru obiektu dla działania akceptującego odświeżenie.

0

Możemy tworzyć formularze, wpisując proste html lub przez pomocników html. Jeden z nich Html.BeginForm(); jest trochę dziwne, ponieważ faktycznie można go zawrzeć w instrukcji using, ponieważ ten konkretny helper zwraca obiekt implementujący IDisposable w języku C#. Najpierw wypisuje tag otwierający. A na dole, gdy wygenerowany kod wywoła utylizację tego obiektu, wtedy będzie wypisywany tag zamykający formularz. Tak więc BeginForm daje mi obiekt, który wypisze mój tag otwierającej formy i zamykający tag. Po tym nie martw się o nic, możesz po prostu skupić się na etykietach i wejściach