2010-04-15 8 views
6

In ASP.NET MVC 2, sono stati introdotti un paio di nuovi attributi del filtro azione, come "abbreviazione" per gli attributi in ASP.NET MVC 1; ad esempio, l'applicazione di HttpPostAttribute ha la stessa funzione dell'applicazione di [AcceptVerbs(HttpVerbs.Post)] a un metodo di azione.Come funzionano gli attributi httppost, httpput etc in ASP.NET MVC 2?

Inoltre, con la sintassi più dettagliata, è possibile combinare diversi metodi, per consentire ad esempio sia Post e Delete.

Ora mi chiedo: come funzionano i nuovi attributi? Se applico sia [HttpPost] e [HttpDelete], ASP.NET MVC 2 consentire entrambi o richiede entrambi (quindi non consentendo nulla)?

risposta

5

Guardando il codice per ActionMethodSelector, sembra che tutti gli attributi del metodo di azione debbano restituire true per IsValidForRequest prima che l'azione venga aggiunta all'insieme dei possibili metodi di corrispondenza. Poiché HttpPost e HttpDelete non sono in grado di restituire IsValidForRequest per la stessa richiesta, mi aspetto che l'utilizzo di entrambi impedirà a tale azione di corrispondere a qualsiasi richiesta.

Ecco un commento eloquente dal codice:

RunSelectionFilters elenco statico private (...) {//
rimuovere tutti i metodi che sono opting out di questa richiesta
// per opt-out, almeno un attributo definito sul metodo deve restituire false

(enfasi mia)

Si noti che è ancora possibile utilizzare AcceptVerbs e esplicitamente O i verbi se è necessario abbinare entrambi.

EDIT - ecco un attributo HttpPostOrDelete per te.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] 
public class HttpPostOrDeleteAttribute : ActionMethodSelectorAttribute 
{ 
    private static readonly AcceptVerbsAttribute _innerPostAttribute = new AcceptVerbsAttribute(HttpVerbs.Post); 
    private static readonly AcceptVerbsAttribute _innerDeleteAttribute = new AcceptVerbsAttribute(HttpVerbs.Delete); 

    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) 
    { 
     return _innerDeleteAttribute.IsValidForRequest(controllerContext, methodInfo) 
       || _innerPostAttribute.IsValidForRequest(controllerContext, methodInfo); 
    } 
} 
+0

So che ancora * posso * usare 'AcceptVerbs', ma penso che i nuovi attributi siano molto più belli nel codice, e speravo che il team MVC ci avesse pensato quando li implementava ... –

+0

@Tomas - fortunatamente, puoi creare il tuo secondo le necessità. Vedi il mio aggiornamento. – tvanfosson

0

Se si inserisce [HttpPost] e [HttpDelete] insieme, sarà necessario entrambi (che non è possibile), penso. Se si concatena [HttpGet], non funzionerà neanche, ecc ...

Si può facilmente testare il mio solo prendendo un metodo di azione [HttpPost] esistente e aggiungendo [HttpDelete] ad esso. Il post smetterà di funzionare.

Non ho trovato alcun esempio in cui avrei dovuto incatenarli come suggerisce il tuo suggerimento.

+0

Il motivo che mi sto chiedendo è che vorrei permettere * sia * POST e DELETE richieste, ma non altro. Speravo che gli attributi funzionassero come l'operatore di UNION set, piuttosto che l'operatore di INTERSECTION ... Ma beh, non puoi sempre ottenere quello che vuoi. Hai una fonte su questo comportamento da qualche parte? –

+0

HttpPost e HttpDelete sono abbastanza comuni Mi aspetto che se si prevede che un'azione di cancellazione funzioni sia utilizzando AJAX (Elimina) e non AJAX (Post), quando javascript è disabilitato. – tvanfosson

+0

Ho effettivamente provato un test e non sono riuscito a trovare nessuna combinazione in cui avrei potuto ottenere un attributo concatenato come il tuo esempio per funzionare. Ho preso metodi di lavoro e ho appena aggiunto degli attributi a loro e abbastanza sicuro li ha spezzati tutti. – Kelsey

4

Tutti i filtri in MVC sono - senza eccezioni - indipendenti l'uno dall'altro. Nessun filtro è con involucro speciale in nessun punto del framework MVC. Questa è stata una decisione progettuale intenzionale in modo che i componenti di framework MVC come l'invoker non possano "ingannare" e trattare i filtri posizionati nel binario MVC in modo diverso dai filtri che avresti scritto come sviluppatore di applicazioni.

Quindi, quando l'invocatore vede [HttpGet] e [HttpPost] sullo stesso metodo, non esiste un codice di involucro speciale per prendere l'unione dei due. Sono eseguiti indipendentemente. E poiché non possono mai restituire true per la stessa richiesta, [HttpGet, HttpPost] esclude in modo efficace qualsiasi metodo particolare dall'essere un metodo di azione.

3

È possibile utilizzare AcceptVerbs per il concatenamento, per esempio:

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)] 
public ActionResult Customers() { 
} 

o

[AcceptVerbs("GET","POST")] 
public ActionResult Customers() { 
} 
Problemi correlati