Renvoyer une vue HTML grâce au moteur de vue « RazorEngine » avec WEB API

Pour une raison quelconque, vous pouvez être amené pour un projet WEB API de renvoyer une vue HTML avec des paramètres plutôt que du JSON classique.

Il vous suffit pour cela d'utiliser le moteur de vue RazorEngine directement dans le code. L'idée est de récupérer la vue HTML (le cshtml) et de le parser afin de remplacer ses différents paramètres (ViewBag, Model, etc...).

J'ai développé une petite extension pour l'ApiController qui fait le travail et voici ce que cela pourrait nous donner avec la v3 de razorEngine :

using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using RazorEngine.Templating;

namespace RazorView.Helpers
{
    public static class Razor
    {
        public static HttpResponseMessage ReturnViewRazor(this ApiController apiController, HttpStatusCode httpStatusCode, string pathView, object model = null, DynamicViewBag viewBag = null)
        {
            var response = new HttpResponseMessage(httpStatusCode);
            var templatePath = HttpContext.Current.Server.MapPath(pathView);
            var template = File.ReadAllText(templatePath, Encoding.UTF8);

            var result = RazorEngine.Engine.Razor.RunCompile(template, "templateKey", null, model, viewBag);

            response.Content = new StringContent(result, Encoding.UTF8, "text/html");

            return response;
        }
    }
}

Ici, "templateKey" permet l'exploitation du cache pour une utilisation future de cette même vue en cas de besoin (évite la recompilation et l'appel direct de la méthode Engine.Razor.Run() suffira)

Un simple exemple d'utilisation :

using System.Net;
using System.Net.Http;
using System.Web.Http;
using RazorEngine.Templating;
using RazorView.Helpers;

namespace RazorView.Controllers
{
    public class ValuesController : ApiController
    {
        public HttpResponseMessage Get()
        {
            var model = new { Test = "Test model !!!" };
            var viewbag = new DynamicViewBag();
            viewbag.AddValue("Test", "Test du viewBag !!!!");
            return this.ReturnViewRazor(HttpStatusCode.OK, "~/Views/Home/TestRazor.cshtml", model, viewbag);
        }
    }
}

Vous pouvez télécharger ce petit projet que j'ai mis en place pour illustrer cette fonctionnalité : RazorView