2012-08-02 15 views
8

Estoy creando un servicio web RESTful utilizando ASP.NET MVC 4 Web API. Para el acceso a la API, estoy devolviendo JSON, aunque una vez que todo funcione correctamente, la negociación de contenido debería funcionar para XML y JSON por defecto.ASP.NET MVC 4/API web - inserte el procesador Razor para Acepta: text/html

Como estoy trabajando para un servicio web realmente RESTful centrado en los recursos, mi URI indicará los recursos reales. Me gustaría aprovechar eso al devolver una representación HTML del recurso si Accepts: text/html viene en la solicitud (como lanzar el enlace en un navegador).

Me gustaría poder aprovechar la negociación de contenido de MVC 4 Web API para insertar un representador de texto/html que use plantillas Razor. ¿Hay algún ejemplo de trabajo para hacer esto?

Sí, esto es un puente entre las páginas "normales" de MVC y la API web. Básicamente, me gustaría crear un renderizador que use un enfoque basado en convenciones para encontrar y renderizar vistas Razor como MVC "regular". Puedo pensar en la lógica de búsqueda basada en convenciones. Simplemente estoy buscandoa) inserción a nivel mundial mi procesador text/html en el negotation contenido y b) utilizando el motor de la maquinilla de afeitar manual para hacer mi modelo a HTML.

+0

¿Sería aceptable el redireccionamiento a un controlador normal para Html (o la ejecución de otra acción a través de HttpRequest y el envío de los resultados al cliente)? –

+0

@KyleTrauberman, preferiría conectarme a la negociación de contenido. Al menos desde mi entendimiento limitado, desde el punto de vista arquitectónico, este sería el más sabio en el futuro. Supongo que la API web y el MVC regular se unirán en el futuro y colocaría mis apuestas en la infraestructura de la API web, por lo que construir sobre el marco de negociación de contenido parece ser el camino correcto. Redirigir a un controlador diferente podría funcionar, pero mi experiencia me lleva a creer que será antinatural y causará problemas en el futuro. Pero no me opongo a entender cómo funcionaría :) – MikeJansen

Respuesta

3

Fredrik Normen tiene una entrada de blog sobre este mismo tema:

http://weblogs.asp.net/fredriknormen/archive/2012/06/28/using-razor-together-with-asp-net-web-api.aspx

Básicamente, es necesario crear un MediaTypeFormatter

using System; 
using System.Net.Http.Formatting; 

namespace WebApiRazor.Models 
{ 
    using System.IO; 
    using System.Net; 
    using System.Net.Http.Headers; 
    using System.Reflection; 
    using System.Threading.Tasks; 

    using RazorEngine; 

    public class RazorFormatter : MediaTypeFormatter 
    { 
     public RazorFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xhtml+xml")); 
     } 

     //... 

     public override Task WriteToStreamAsync(
               Type type, 
               object value, 
               Stream stream, 
               HttpContentHeaders contentHeaders, 
               TransportContext transportContext) 
     { 
      var task = Task.Factory.StartNew(() => 
       { 
        var viewPath = // Get path to the view by the name of the type 

        var template = File.ReadAllText(viewPath); 

        Razor.Compile(template, type, type.Name); 
        var razor = Razor.Run(type.Name, value); 

        var buf = System.Text.Encoding.Default.GetBytes(razor); 

        stream.Write(buf, 0, buf.Length); 

        stream.Flush(); 
       }); 

      return task; 
     } 
    } 
} 

y luego registrarla en Global.asax:

GlobalConfiguration.Configuration.Formatters.Add(new RazorFormatter()); 

el código anterior se copió de la publicación del blog y no es mi trabajo

+0

Perfecto, gracias! Mucho más simple de lo que esperaba. – MikeJansen

0

Puede consultar WebApiContrib.Formatting.Razor. Es muy similar a la respuesta de Kyle, sin embargo, es un proyecto de código abierto en toda regla con más características, pruebas unitarias, etc. También puede get it on NuGet.

Diré que definitivamente necesita más funciones, pero parece que lo han diseñado bien, por lo que sería muy fácil contribuir a ello.