2012-07-30 8 views
6

Estoy implementando una capa REST en .NET MVC 3. Estoy buscando una manera limpia de agarrar el encabezado Aceptar para determinar si debo devolver Json o Xml.Manera más limpia de modelar Encabezado Aceptado en .NET MVC

También me gustaría poder falsificar este encabezado con un parámetro GET para la depuración (quiero que esto también persista).

Así es como estoy detectando actualmente esto:

if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json")) 

Este es el único lugar en mi código de controlador que toca directamente el objeto Request. Me gustaría una forma más limpia y comprobable de leer esto. Mi solución ideal sería un parámetro en el controlador.

Probé varias palabras clave para ver si el encuadernador de modelo predeterminado lo recogería, pero nada de lo que probé funcionó.

¿Cuál es la forma más limpia de obtener esta información? ¿Una carpeta de modelo personalizado? ¿Puede dar un ejemplo?

+0

Si no se opone a mvc4 webapi, puede hacer que esto se solucione por usted. Sin mencionar que cuando migres tu aplicación a mvc4 + en algún momento en el futuro, estarás manipulando algo que MVC ya hace por ti. Busque la negociación del tipo de contenido mvc4 para obtener más información. –

+0

Me he dado cuenta de esto y estoy muy emocionado, pero desafortunadamente no puedo entregar este proyecto en RC, y por lo que puedo decir, no hay fecha de lanzamiento para 4. – Travis

+0

http://prideparrot.com/blog/archive/2012/3/returning_data_view_from_controller_action – VJAI

Respuesta

2

Un atributo de filtro de acción sería una solución buena y limpia.

Hay un buen tutorial aquí: http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

+0

Gracias por la respuesta, pero si entiendo esto correctamente, tendré que duplicar cada acción, una para Xml y otra para Json. Eso parece un poco excesivo solo para la encapsulación y la capacidad de prueba. ¿O me estoy perdiendo algo? – Travis

+1

Puede registrarlo como un filtro de acción global y tener ambos Xml y Json manejados en un filtro ... ¿no es eso lo que busca? Aún así, necesitarás almacenarlo en ViewData/Bag, que no es tan "limpio", supongo. –

2

que no estoy viendo ningún mejores alternativas a un ligante modelo personalizado. Voy a publicar mi implementación de la carpeta aquí en caso de que alguien más vea esto. El uso de un encuadernador de modelo permite que el encabezado Accept se vincule fuertemente a una entrada directa en la acción, lo que permite realizar pruebas directas de los tipos de devolución y no lo fuerza a tener artificialmente más acciones de las que necesita, ni a los datos de vista de tipo dinámico /bolso.

Aquí está la carpeta de modelo con un soporte tipo de enumeración:

public enum RequestAcceptType 
{ 
    NotSpecified, 
    Json, 
    Xml 
} 

public class RequestAcceptTypeModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException("bindingContext"); 
     } 

     RequestAcceptType acceptType = RequestAcceptType.NotSpecified; 

     // Try for Json 
     if (controllerContext.HttpContext.Request.AcceptTypes.Contains("application/json") || controllerContext.HttpContext.Request.Url.Query.Contains("application/json")) 
     { 
      acceptType = RequestAcceptType.Json; 
     } 

     // Default to Xml 
     if (acceptType == RequestAcceptType.NotSpecified) 
     { 
      acceptType = RequestAcceptType.Xml; 
     } 

     return acceptType; 
    } 
} 

Aquí está la parte relevante en Global.asax en el método Application_Start:

ModelBinders.Binders[typeof(RequestAcceptType)] = new RequestAcceptTypeModelBinder(); 

A continuación, utilizarlo en sus acciones, al igual hacer un argumento (cualquier nombre) con el tipo de enumeración:

public ActionResult Index(RequestAcceptType acceptType) 

Si nadie responde con ab método etter en un par de días, aceptaré esto como la respuesta.

Cuestiones relacionadas