题
我认为这将是有趣的,如果我可以使用新的MVC Razor视图引擎作为邮件合并技术。它仍然是一个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?"
主要的是我想要的模板从字符串而不是视图或partialview驱动。
有谁知道这是否可能?
更新:
本和马特CodePlex上制成的项目: http://razorengine.codeplex.com/
解决方案
警告
这是被黑在一起而不测试它比得到它的正常工作的其他一些难看丑陋的代码。
的VirtualPathProvider
由于我们不处理,我们必须添加自己的路提供商来告诉MVC从哪里得到我们的动态生成的模板的服务器上实际的看法。应该有更多的测试,如检查串词典,以查看是否该视图已经被添加。
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
备注
此的仅强>作品与输入模式。我试图在一个新的{名称=“比利小子”}通过,它抛出的错误。我不知道为什么,并没有真正看的太深入了。
这很有趣,感谢问这个问题。
其他提示
剃刀设计时考虑到独立操作。没有关于该模式多文档,但(因为它是所有仍在开发中),但看看安德鲁护士这个博客帖子:的 http://vibrantcode.com/blog/2010/7/22/using-the-razor-parser-outside-of -aspnet.html
不隶属于 StackOverflow