Pregunta

pensé que sería interesante si podía usar el nuevo motor MVC Razor Ver como una tecnología de combinación de correspondencia. Todavía puede ser parte de una página web MVC y no tiene que ser aplicación de consola independiente.

Ejemplo:

string  myTemplate = "Hello @Name,  How are you today?";
ViewModel.Name = "Billy Boy";
string output = RazorViewEngineRender( myTemplate, ViewModel );

A continuación, el string output = "Hello Billy Boy, How are you today?"

Lo más importante es que quiero la plantilla para ser conducido de una cadena en lugar de una vista o PartialView.

¿Alguien sabe si esto es posible?

ACTUALIZACIÓN:

Ben y Matt hicieron un proyecto en CodePlex: http://razorengine.codeplex.com/

¿Fue útil?

Solución

Advertencia

Esto es código fea fea que fue hackeado sin probarlo aparte de conseguir que funcione correctamente.

VirtualPathProvider

Debido a que no estamos tratando con verdaderos puntos de vista en el servidor tenemos que añadir nuestro propio proveedor de ruta para contar MVC donde conseguir nuestras plantillas generadas dinámicamente. No debe haber más pruebas como la comprobación de las cadenas del diccionario para ver si el punto de vista ha sido añadido.

public class StringPathProvider : VirtualPathProvider {
    public StringPathProvider()
        : base() {
    }

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) {
        return null;
    }

    public override bool FileExists(string virtualPath) {
        if (virtualPath.StartsWith("/stringviews") || virtualPath.StartsWith("~/stringviews"))
            return true;

        return base.FileExists(virtualPath);
    }

    public override VirtualFile GetFile(string virtualPath) {
        if (virtualPath.StartsWith("/stringviews") || virtualPath.StartsWith("~/stringviews"))
            return new StringVirtualFile(virtualPath);

        return base.GetFile(virtualPath);
    }

    public class StringVirtualFile : System.Web.Hosting.VirtualFile {

        string path;

        public StringVirtualFile(string path)
            : base(path) {
            //deal with this later
                this.path = path;
        }

        public override System.IO.Stream Open() {
            return new System.IO.MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(RazorViewEngineRender.strings[System.IO.Path.GetFileName(path)]));
        }
    }
}

Render Clase

Esta clase tiene su plantilla como un parámetro de constructor y lo añade a una estructura estática diccionario que luego es leído por el VirtualPathProvider anteriormente. A continuación, llama a Render y se puede pasar opcionalmente en un modelo. Esto añadirá el tipo de modelo completa al @inherits y anteponer a que el contenido del archivo.

public class RazorViewEngineRender {
    internal static Dictionary<string, string> strings { get; set; }

    string guid;

    static RazorViewEngineRender() {
        strings = new Dictionary<string, string>();
    }

    public RazorViewEngineRender(string Template) {
        guid = Guid.NewGuid().ToString() + ".cshtml";
        strings.Add(guid, Template);
    }

    public string Render() {
        return Render(null);
    }

    public string Render(object ViewModel) {
        //Register model type
        if (ViewModel == null) {
            strings[guid] = "@inherits System.Web.Mvc.WebViewPage\r\n" + strings[guid];
        } else {
            strings[guid] = "@inherits System.Web.Mvc.WebViewPage<" + ViewModel.GetType().FullName + ">\r\n" + strings[guid];
        }

        CshtmlView view = new CshtmlView("/stringviews/" + guid);

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        System.IO.TextWriter tw = new System.IO.StringWriter(sb);

        ControllerContext controller = new ControllerContext();

        ViewDataDictionary ViewData = new ViewDataDictionary();
        ViewData.Model = ViewModel;

        view.Render(new ViewContext(controller, view, ViewData, new TempDataDictionary(), tw), tw);
        //view.ExecutePageHierarchy();

        strings.Remove(guid);

        return sb.ToString();

    }
}

Global.asax

En el archivo Global.asax que tendrá que añadir lo siguiente a la Application_Start

System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new Controllers.StringPathProvider());

Llamando el código

string Template = "Hello, @Model.Name";
Models.User user = new Models.User() { Name = "Billy Boy" };
RazorViewEngineRender view = new RazorViewEngineRender(Template);
string Results = view.Render(user); //pass in your model

Notas

Este sólo los trabajos con modelos mecanografiadas. Me trató de pasar en una nueva {Name = "Billy Boy"} y se está lanzando errores. No estoy seguro de por qué y en realidad no mirar demasiado profundamente en ella.

Esto fue muy divertido, gracias por hacer esta pregunta.

Otros consejos

Razor fue diseñado con funcionamiento autónomo en mente. Todavía no existe mucha documentación acerca de ese modo (ya que todo todavía en desarrollo), pero echar un vistazo a esta entrada del blog de Andrew Enfermera: http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of -aspnet.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top