2013-05-24 17 views
16

Sono molto nuovo ad ASP.NET, ho appena avviato il tutorial MVC oggi su asp.net. Sono arrivato qui http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-methods-and-edit-viewCome funziona @ Html.BeginForm()?

Fin qui tutto bene, il problema:

a mio avviso ho il seguente codice (modello è impostato per la vista con @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> 
} 

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

Ed ecco la domanda - Come diavolo fa passare l'oggetto filmato per il metodo POST sopra ?! Quando osservo lato client c'è

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

Qui non capisco il motivo per cui l'azione = URL della stessa pagina di visualizzazione?! 1 anche sul lato server non è solo Html.BeginForm() :( Come ci si rende conto di quello che metodo di azione per inviare e quali parametri percorso per passare? funziona, solo che non so perché

risposta

35

La versione BeginForm nel codice, senza parametri, invia un POST HTTP all'URL corrente, quindi se la vista è una risposta a /Movie/Edit/5, il tag di apertura sarà simile alla seguente: < form action="/Movie/Edit/5" method="post">

l'helper HTML BeginForm chiede al motore di routing come raggiungere l'azione Modifica del MovieController. Dietro le quinte utilizza il metodo denominato GetVirtualPath sulla proprietà Route di esposta da RouteTable - che è dove la tua applicazione web ha registrato tutti i suoi percorsi in global.asax. Se avete fatto tutto questo senza un aiuto HTML, che avrebbe dovuto scrivere tutto il codice seguente :

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

hai chiesto come è oggetto filmato viene passato. Si chiama binding del modello. Quando si esegue un'azione con un parametro, il runtime MVC utilizza un raccoglitore modello per creare il parametro . È possibile avere più modelli di binders registrati nel runtime MVC per diversi tipi di modelli , ma il cavallo di battaglia per impostazione predefinita sarà lo DefaultModelBinder.

Nel caso di un oggetto Movie , il raccoglitore modello predefinito ispeziona il film e trova tutte le proprietà del film disponibili per il binding. Seguendo la convenzione di denominazione esaminata in precedenza, il raccoglitore modello predefinito può convertire e spostare automaticamente i valori dalla richiesta in un oggetto filmato (il raccoglitore modello può creare anche un'istanza dell'oggetto da popolare). In altre parole, quando il raccoglitore modello vede un filmato ha una proprietà Title, cerca un valore denominato "Title" nella richiesta.Si noti che il raccoglitore modello sembra "nella richiesta" e non "nella collezione ". Il raccoglitore modello utilizza componenti noti come fornitori di valore per cercare valori in diverse aree di una richiesta. Il raccoglitore modello può esaminare i dati del percorso, la stringa di query e la collezione di moduli ed è possibile aggiungere fornitori di valore personalizzato se lo si desidera.

+0

Giocare con le sostituzioni per '@ Html.BeginForm' - Ho fornito' Html.BeginForm ("Modifica", "Film", FormMethod.Post) '. Si noti che non ho fornito la terza parte 'id' del percorso. Eppure nel markup risultante, è lì: '/ Movies/Edit/4'. Come fa questo? Se suppongo 'Html.BeginForm (" Elimina "," Film ", FormMethod.Post)', l'HTML risultante non ha l'id ':'/Movies/Delete'. – mmcrae

4

[HttpPost] attributo viene dato all'azione che si desidera essere invitato il POST presentare del modulo

per capire come @using (Html.BeginForm()) funziona, è necessario sapere su quale pagina è già attiva. utilizzando @using (Html.BeginForm()) in 2 viste differenti tornerà a due diversi controllori

9

Quando si chiama BeginForm() senza parametri, per impostazione predefinita utilizza lo stesso controller/azione utilizzato per il rendering della pagina corrente. Si presuppone che tu abbia un'azione con il nome corretto sul tuo controller che accetterà i postback (che fai). Usa lo RouteValues per farlo.

Lega automaticamente ogni controllo di input (in base al nome) ai parametri dell'azione che accetta il postback o, nel caso, le proprietà del parametro oggetto per l'azione che accetta il postback.

0

Possiamo creare moduli digitando semplici html o html helper. Uno di questi Html.BeginForm(); è un po 'strano perché in realtà è possibile racchiuderlo in un'istruzione using perché questo particolare helper restituisce un oggetto che implementa IDisposable in C#. Prima scrive con il tag di apertura. E in fondo quando le chiamate di codice generate si dispongono su quell'oggetto, è quando scriverà il tag di chiusura. Quindi BeginForm mi fornisce un oggetto che scriverà il mio tag di apertura e la mia chiusura dal tag. Dopo di che non ti preoccupi di nulla puoi concentrarti solo su etichette e input

Problemi correlati