ASP.NET MVC 5–Binding de parámetros dinámicos

Estando trabajando en un proyecto con ASP.NET MVC 5 surgió la “necesidad” (impulsada por la pereza) de tener un controlador MVC (ojo, no WebApi) que recibiese datos en JSON via POST y que devolviese una vista parcial. Hasta ahí nada raro (eso se soporta de serie desde MVC3), donde la pereza intervino es que queríamos que el parámetro del controlador fuese dynamic en lugar de un tipo en concreto. Y eso, en MVC5 no está soportado. Veamos por qué y como podemos solucionarlo 😉

Nota: Todo lo dicho en este post afecta solo a MVC5. En WebApi y en MVC6 (ASP.NET Core) las cosas funcionan distinto.

Continúa leyendo ASP.NET MVC 5–Binding de parámetros dinámicos

Atributos con comportamiento: un mal diseño

Tarde o temprano, todo desarrollador ya se de ASP.NET MVC o WebApi necesita hacer sus propios filtros para validaciones propias de peticiones, logging, comprobación de precondiciones… En fin, lo habitual para lo que se usan los filtros, vamos.

Y tarde o temprano este desarrollador se da cuenta de que su filtro debería acceder a un determinado servicio de su aplicación: quizá necesita hacer una consulta a la bbdd, o a un determinado elemento de negocio, o acceder al sistema de logging o cualquier cosa más. Y este desarrollador, que conoce (y usa) la inyección de dependencias se encuentra con que no es posible inyectar dependencias en un filtro. Algunos desarrolladores buscaran cualquier otra alternativa, algunas mejores que otras, pero ninguna satisfactoria: crear un singleton, una clase estática o instanciar directamente el objeto en lugar de obtenerlo como una dependencia (y rompiendo cualquier abstracción realizada). Otros desarrolladores continuarán en su búsqueda. En esta fase de terquedad que nos caracteriza, pensaran “no, no es posible. Tiene que ver alguna manera”.

Creando formateadores de salida en asp.net core

Cuando salió WebApi lo hizo con la negociación de contenido incorporada de serie en el framework. Eso venía a significar, básicamente, que el framework intentaba suministrar los datos en el formato en que el cliente los había pedido. La negociación de contenido se basa (generalmente) en el uso de la cabecera accept de HTTP: el cliente manda en esa cabecera cual, o cuales, son sus formatos de respuesta preferidos. WebApi soporta de serie devolver datos en JSON y XML y el sistema es extensible para crear nuestros propios formatos.

“MVC clásico” (es decir hasta MVC5) no incluye soporte de negociación de contenido: en MVC si queremos devolver datos en formato JSON, debemos devolver explícitamente un JsonResult y si los queremos devolver en XML debemos hacerlo también explícitamente.

En ASP.NET Core tenemos a MVC6 que unifica a WebApi y MVC clásico en un solo framework. ¿Como queda el soporte para negociación de contenido en MVC6? Pues bien, existe soporte para ella, pero dependiendo de que IActionResult devolvamos en nuestros controladores. Así, si en WebApi la negociación de contenido se usaba siempre y en MVC clásico nunca, en MVC6 la negociación de contenido aplica solo si la acción del controlador devuelve un ObjectResult (o derivado). Esto nos permite como desarrolladores decidir sobre qué acciones de qué controladores queremos aplicar la negociación de contenido. Es evidente que aplicarla siempre no tiene sentido: si devolvemos una vista Razor su resultado debe ser sí o sí un HTML que se envía al cliente. No tendría sentido aplicar negociación de contenido sobre una acción que devolviese una vista. De hecho la negociación de contenido tiene sentido en APIs que devuelvan datos (no vistas) y en MVC6 para devolver datos tenemos a ObjectResult, así que es lógico que sea sobre este resultado donde se aplique la negociación de contenido.

En WebApi la negociación de contenido estaba gestionada por los formateadores (formatters). Básicamente a cada content-type se le asociaba un formateador. Si el cliente pedía datos en un determinado content-type se miraba que formateador podía devolver datos en dicho formato. Si no existía se usaba por defecto el formateador de JSON. En MVC6 se ha mantenido básicamente dicho esquema.

Continúa leyendo Creando formateadores de salida en asp.net core