Frage

Ich dachte, es wäre interessant, wenn ich den neuen MVC Razor Ansicht Motor als Seriendruck-Technologie nutzen könnte. Es kann immer noch Teil einer MVC-Website sein und keine eigenständige Konsolenanwendung sein.

Beispiel:

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

Dann wird die string output = "Hello Billy Boy, How are you today?"

Die Hauptsache ist, ich die Vorlage will aus einem String angetrieben werden, anstatt einer Ansicht oder partialview.

Wer weiß, wenn dies möglich ist?

UPDATE:

Ben und Matt ein Projekt auf Codeplex gemacht: http://razorengine.codeplex.com/

War es hilfreich?

Lösung

Warnung

Dies ist einige hässliche hässliche Code, der zusammen gehackt wurde, ohne es anderen zu testen, als es immer richtig zu arbeiten.

VirtualPathProvider

Da wir nicht mit dem tatsächlichen Ansichten auf dem Server zu tun haben wir unseren eigenen Weg Provider hinzuzufügen MVC zu sagen, wo unsere dynamisch generierten Vorlagen zu erhalten. Es sollte mehr Tests sein wie die Saiten Wörterbuch zu überprüfen, ob die Ansicht hinzugefügt wurde.

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-Klasse

Diese Klasse nimmt die Vorlage als Konstruktor Parameter und fügt sie zu einem statischen Wörterbuch, das dann durch die VirtualPathProvider oben gelesen wird. Anschließend rufen Sie Render und Sie können gegebenenfalls in einem Modell übergeben. Dies wird den vollständigen Modelltyp zum @inherits und prepend, dass der Inhalt der Datei hinzuzufügen.

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

In Ihrer global.asax-Datei finden Sie die folgenden auf die Application_Start

hinzufügen müssen
System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new Controllers.StringPathProvider());

Der Aufruf der Code

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

Notizen

Das nur Arbeiten mit typisierten Modellen. Ich habe versucht, in einem neuen {Name = „Billy Boy“} passieren und es wirft Fehler. Ich bin mir nicht sicher, warum und wusste wirklich nicht zu tief hineinschauen.

Das hat Spaß gemacht, vielen Dank für diese Frage.

Andere Tipps

Razor wurde mit Standalone-Betrieb konzipiert. Es gibt nicht viel Dokumentation über diesen Modus noch (da es immer noch alle in der Entwicklung), aber einen Blick auf diesen Blog-Eintrag von Andrew Krankenschwester haben: http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of -aspnet.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top