【问题标题】:Using the Razor view engine in a different way以不同的方式使用 Razor 视图引擎
【发布时间】:2010-09-27 21:34:04
【问题描述】:

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

例子:

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

然后string output = "Hello Billy Boy, How are you today?"

主要是我希望模板从字符串而不是视图或部分视图驱动。

有谁知道这是否可行?

更新:

Ben 和 Matt 在 codeplex 上做了一个项目:http://razorengine.codeplex.com/

【问题讨论】:

    标签: c# asp.net-mvc razor


    【解决方案1】:

    警告

    这是一些丑陋丑陋的代码,除了让它正常工作之外,未经测试就被破解了。

    虚拟路径提供者

    由于我们不处理服务器上的实际视图,我们必须添加我们自己的路径提供程序来告诉 MVC 从哪里获取我们动态生成的模板。应该有更多的测试,比如检查字符串 Dictionary 以查看是否已添加视图。

    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 读取。然后你调用Render,你可以选择传入一个模型。这会将完全限定的模型类型添加到 @inherits 并将其添加到文件内容中。

    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());
    

    调用代码

    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
    

    注意事项

    适用于类型化模型。我试图传入一个新的 { Name = "Billy Boy" } 并抛出错误。我不知道为什么,也没有真正深入研究它。

    这很有趣,感谢您提出这个问题。

    【讨论】:

    • 干得好!我试过了,它对我很有用。这实际上是制作报告和自定义电子邮件等非常强大的工具......
    • 我创建了一个不使用 MVC 的示例,您可以在我的博客上找到它,因为添加另一个帖子实在是太多了。 buildstarted.com/2010/09/29/…
    • @这里定义了 CshtmlView 类?我不能它或它的任何文档,并且 RazorView 类似乎不兼容。
    • MVC3 的一部分。我认为它已被WebFormView 弃用,但不要引用我的话:)
    【解决方案2】:

    Razor 的设计考虑了独立操作。目前还没有太多关于该模式的文档(因为它仍在开发中),但请查看 Andrew Nurse 的这篇博文:http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of-aspnet.html

    【讨论】:

    猜你喜欢
    • 2017-10-15
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多