以不同的方式使用该剃刀视图发动机 [英] Using the Razor view engine in a different way

查看:151
本文介绍了以不同的方式使用该剃刀视图发动机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这将是有趣的,如果我可以使用新的MVC的Razor视图引擎作为邮件合并技术。它仍然是一个MVC的网站的一部分,并不一定是独立的控制台应用程序。

I thought it would be interesting if I could use the new MVC Razor View engine as a mail merge technology. It can still be part of an MVC website and does not have to be stand-alone console app.

例如:

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

然后字符串输出=你好比利小子,今天你怎么样?

更主要的是我想要的模板从一个字符串,而不是一个视图或partialview驱动。

The main thing is I want the template to be driven from a string rather than a view or partialview.

有谁知道这是可能的吗?

Does anyone know if this is possible ?

更新:

本和马特对作了codePLEX项目: HTTP://razorengine.$c$cplex.com/

Ben and Matt made a project on codeplex: http://razorengine.codeplex.com/

推荐答案

这是被黑客入侵在一起,没有测试它比其他的得到它正常工作的一些丑丑code。

Warning

This is some ugly ugly code that was hacked together without testing it other than getting it to work properly.

由于我们不处理我们必须添加自己的路提供商告诉MVC从哪里得到我们的动态生成的模板的服务器上实际的看法。应该有更多的像检查串词典,以查看是否视图已经被加入测试

Since we're not dealing with actual views on the server we have to add our own path provider to tell MVC where to get our dynamically generated templates. There should be more tests like checking the strings Dictionary to see if the view has been added.

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)]));
        }
    }
}

渲染类

本类需要你的模板作为构造函数的参数,并将其添加到一个静态的字典,然后通过的VirtualPathProvider 如上。然后调用渲染键,你可以选择性地传入的典范。这将完全合格的模型类型添加到 @inherits 和prePEND,为文件的内容。

Render Class

This class takes your template as a constructor parameter and adds it to a static Dictionary that is then read by the VirtualPathProvider above. You then call Render and you can optionally pass in a model. This will add the fully qualified model type to the @inherits and prepend that to the file contents.

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

在您的Global.asax文件,你必须添加下面的的Application_Start

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

调用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

注释

此的适用于类型化的模式。我试图在一个新的{名称=比利小子}传递,它的投掷的错误。我不知道为什么,并没有真正看太深入了。

Notes

This only works with typed Models. I attempted to pass in a new { Name = "Billy Boy" } and it's throwing errors. I'm not sure why and didn't really look too deeply into it.

这很有趣,感谢问这个问题。

This was fun, thanks for asking this question.

这篇关于以不同的方式使用该剃刀视图发动机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆