警告
这是一些丑陋的代码,除了让它正常工作之外,未经测试就被黑客攻击在一起。
虚拟路径提供者
由于我们不处理服务器上的实际视图,我们必须添加我们自己的路径提供程序来告诉 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)]));
}
}
}
渲染类
此类将您的模板作为构造函数参数并将其添加到静态 Dictionary 中,然后由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();
}
}
全球.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" } 并抛出错误。我不知道为什么,也没有真正深入研究它。
这很有趣,谢谢你提出这个问题。