2010-04-15 9 views
6

En ASP.NET MVC 2, se introdujeron un par de nuevos atributos de filtro de acción, como "taquigrafía" para los atributos en ASP.NET MVC 1; por ejemplo, aplicar HttpPostAttribute hace lo mismo que aplicar [AcceptVerbs(HttpVerbs.Post)] a un método de acción.¿Cómo funcionan los atributos de httppost, httpput, etc. en ASP.NET MVC 2?

Además, con la sintaxis más detallada, es posible combinar diferentes métodos, para permitir, por ejemplo, Post y Delete.

Ahora me pregunto: ¿cómo funcionan los nuevos atributos? Si aplico ambos [HttpPost] y [HttpDelete], ¿ASP.NET MVC 2 permitirá ambos o requieren ambos (permitiendo así nada)?

Respuesta

5

Al observar el código de ActionMethodSelector, parece que todos los atributos del método de acción deben volverse verdaderos para IsValidForRequest antes de que esa acción se agregue al conjunto de posibles métodos de coincidencia. Dado que no es posible que HttpPost y HttpDelete devuelvan IsValidForRequest para la misma solicitud, esperaría que el uso de ambos evitará que esa acción coincida con alguna solicitud.

Aquí es un comentario revelador del código:

RunSelectionFilters lista estática privadas (...) {//
elimina todos los métodos que están optando por salir de esta solicitud
// Para optar por no, al menos un atributo definido en el método debe devolver falsa

(énfasis mío)

Tenga en cuenta que aún puede usar AcceptVerbs y explícitamente O los verbos si necesita hacer una coincidencia.

EDIT - aquí hay un atributo HttpPostOrDelete para usted.

[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

Sé que todavía * puedo * usar 'AcceptVerbs', pero creo que los nuevos atributos se ven mucho mejor en el código, y esperaba que el equipo de MVC hubiera pensado en esto al implementarlos ... –

+0

@Tomas - afortunadamente, puedes hacer tu propia como sea necesario. Ver mi actualización – tvanfosson

0

Si pones [HttpPost] y [HttpDelete] juntos, necesitarás ambos (lo cual no es posible), creo. Si encadena [HttpGet] tampoco funcionará, etc ...

Puede probarlo fácilmente simplemente tomando el método de acción existente [HttpPost] y añadiéndole [HttpDelete]. La publicación dejará de funcionar.

No he encontrado ningún ejemplo en el que necesite encadenarlos como sugiere.

+0

La razón por la que estoy pidiendo es que me gustaría permitir que tanto * * POST y DELETE peticiones, pero sin otro. Tenía la esperanza de que los atributos funcionarían como el operador de conjunto UNION, en lugar del operador INTERSECTION ... Pero bueno, no siempre se puede obtener lo que se quiere. ¿Tienes alguna fuente sobre este comportamiento en alguna parte? –

+0

HttpPost y HttpDelete es bastante común. Es de esperar que espere que una acción de eliminación funcione tanto con AJAX (Eliminar) como sin AJAX (Publicar), cuando javascript está deshabilitado. – tvanfosson

+0

De hecho, probé una prueba y no pude encontrar ninguna combinación donde pudiera obtener un atributo encadenado como el ejemplo para que funcione. Tomé métodos de trabajo y simplemente agregué atributos a ellos y, efectivamente, los rompió a todos. – Kelsey

4

Todos los filtros en MVC son, sin excepción, independientes entre sí. Ningún filtro tiene carcasa especial en ninguna parte del marco MVC. Esta fue una decisión de diseño intencional para que los componentes del framework MVC como el invocador no puedan "engañar" y tratar los filtros ubicados en el binario MVC de forma diferente a los filtros que usted como desarrollador de la aplicación habría escrito.

Así que cuando el invocador ve [HttpGet] y [HttpPost] en el mismo método, no hay un código de envoltura especial para tomar la unión de los dos. Se ejecutan de forma independiente. Y dado que nunca pueden volverse verdaderas para la misma solicitud, [HttpGet, HttpPost] excluye efectivamente cualquier método particular de ser un método de acción.

3

Puede utilizar AcceptVerbs para encadenar, por ejemplo:

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

o

[AcceptVerbs("GET","POST")] 
public ActionResult Customers() { 
} 
Cuestiones relacionadas