2015-02-28 13 views
10

Sono molto molto nuovo a MVC il modello di progettazione e anche il Framework. Inoltre, non sono estremamente esperto in base ai moduli ASP.NET. Tuttavia, comprendo le basi dello sviluppo web e di HTTP Post e GET.Comprensione dei parametri [HttpPost], [HttpGet] e Complex Actionmethod in MVC

Ora, ho eseguito alcuni tutorial MVC e ho pensato a come funziona MVC e anche a come funziona "Routing Engine". Poi, all'improvviso, mi sono imbattuto in un codice che assomiglia folloing:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return Content("Thanks", "text/html"); 
    } 
} 

ho alcune domande a guardarla:

  • mia comprensione di motore di routing è che il controllo è passato a un particolare ActionMethod in base all'URL e normalmente gli URL sono fondamentalmente tipo Controller/ActionMethod/Id in cui i parametri per l'azione sono piuttosto tipi primitivi. In questo esempio sopra che tipo di URL sarebbe necessario per chiamare "

ActionResult pubblica Index (modello MyViewModel)?"

Poiché NyViewModel è un tipo complesso, non è possibile passarlo come parte dell'URL. Come puoi chiamarlo?

  • Perché questo secondo metodo è adornato con [HttpPost] quando il primo metodo non richiede alcun attributo? Ci sono delle linee guida su quando utilizzare gli attributi [Http] e quando no?

Penso che mi manca un grande pice nel puzzle e entrambe le domande sono interrelate. Tuttavia, hanno bisogno di un certo aiuto a dare un senso al rapporto

risposta

12

L'attributo [HttpPost] indica al motore di routing di inviare qualsiasi richiesta POST a quel metodo di azione a un metodo rispetto all'altro. Questo è un tipo di sovraccarico.

Perché questo secondo metodo è adornato con [HttpPost] quando il primo metodo non richiede alcun attributo?

Il valore predefinito per un metodo è [HttpGet]. Per questo motivo, non è necessario alcun attributo.

Esistono linee guida su quando utilizzare gli attributi [Http] e quando no?

Idealmente, gli attributi dovrebbero essere su ogni metodo, al fine di evitare confusione. Man mano che acquisisci familiarità con il funzionamento delle cose, spesso utilizzi scorciatoie (come qualsiasi altra cosa) e le ometti quando sai che non sono necessarie.

Dato che MyViewModel è un tipo complesso, non è possibile passarlo come parte dell'URL. Come puoi chiamarlo?

I dati verranno trasformati nel modello dai dati nel corpo della richiesta. Questo può venire sia come oggetto JSON, sia come dati del modulo. (Esistono trucchi per rendere l'oggetto inizializzato dall'URL, ma possono essere un po 'complicati e avanzati.)

+2

Mi piace questa risposta perché risponde direttamente alle domande e corregge anche l'idea sbagliata secondo cui gli oggetti complessi non possono essere trasmessi tramite URL. Il binding del modello di .NET è davvero abbastanza robusto! Ecco un buon esempio del perché @krillgar dice che può diventare complicato (I.E. strano!) Http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ – Vassi

+0

Bella spiegazione. Ma, quindi, non importa se non usiamo [HttpPost] nel codice sopra? –

+0

@AntiMafia Non sono sicuro di cosa intendi. '[HttpGet]' è l'unico facoltativo perché GET è il metodo HTTP predefinito. Ogni volta che vuoi fare un POST, devi decorare l'azione con l'attributo. – krillgar

1

Best Practice - la gestione delle richieste

E 'buona norma utilizzare solo metodi pubblici in vostro controller che stanno per essere servito sia con una vista o con jSON. Per tutti i metodi pubblici nel controller, è consigliabile contrassegnarli con uno [HttpGet] o con uno [HttpPost] o con uno degli altri tipi che non coprirò in quanto sono uno scenario con più margini.

Questi attributi Http limitano il metodo solo alla manutenzione di quei tipi specifici di richieste. Mentre l'impostazione predefinita è [HttpGet], ho riscontrato che non contrassegnare [HttpGet] in tutti gli scenari può a volte comportare un comportamento imprevisto quando si verificano conflitti di denominazione.

Best Practice - PRG

Post-Redirect-get è un modello di progettazione che prevede in sostanza che ogni volta che si sta per essere l'invio di una risposta che veniva da una richiesta POST, si dovrebbe reindirizzare ad un get per inviare la risposta. Questo protegge da una serie di scenari, tra cui non pubblicare nuovamente se si utilizza il pulsante Indietro.

Il reindirizzamento di solito si presenta sotto forma di [HttpPost] ActionResult utilizzando return RedirectToAction("MyHttpGetAction");.

Diffusione di modelli complessi

Ci sono diversi modi che è possibile inviare un modello complesso. La differenza principale è che se si sta utilizzando una richiesta GET è nell'URL e se si utilizza una richiesta POST è presente nelle intestazioni della richiesta. Se usi ajax, la differenza diventa sfocata poiché quasi sempre la invierai nel corpo.

3

In genere, gli oggetti complessi vengono passati nel corpo HTTP con i verbi che lo supportano come POST e PUT. Il contenuto del corpo deve superare la convalida del modello Binding. Ciò significa fondamentalmente che se si tratta di una richiesta POST con Content-Type: application/json, deve deserializzare da JSON a MyViewModel. Se il contenuto è XML, deve deserializzare come XML.

Per convenzione generale è necessario avere tutti i tipi primitivi che possono essere trovati nel percorso URL, nella query e nelle intestazioni, quindi un tipo complesso dal corpo POST (o PUT) dopo quello. Credo che sia possibile inserire tipi complessi altrove, ma in questo caso si sta entrando in convertitori di tipi e attributi personalizzati che probabilmente dovresti tenere a bada se sei un principiante.

Perché questo secondo metodo è adornato con [HttpPost] quando il primo metodo non richiede alcun attributo? Ci sono delle linee guida su quando utilizzare gli attributi [Http] e quando no?

"[HttpPost]" sta dicendo il motore di routing che questo metodo sovraccarico è solo disponibili via HTTP POST. Il tentativo di PUT/home/index con un corpo fallirà con 404 Not Found, in questo caso. La versione senza parametri di Index() non lo richiede perché può funzionare con qualsiasi verbo HTTP, inclusi GET, POST e PUT.

Problemi correlati