mar*_*arq 8 c# asp.net-mvc templates
我有一个后台服务运行,它向我的网站用户发送电子邮件.我想将电子邮件模板编写为MVC视图,以保持一致(以便可以使用相同的模型发送电子邮件以显示网页).
不幸的是,当我尝试执行LoadControl(只是修补到BuildManager.CreateInstanceFromVirtualPath)时,我得到以下内容:
System.NullReferenceException at
System.Web.dll!System.Web.VirtualPath.GetCacheKey() + 0x26 bytes
System.Web.dll!System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath + 0x2a bytes
System.Web.dll!System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal + 0x30 bytes
Run Code Online (Sandbox Code Playgroud)
似乎如果我将MvcBuildViews设置为true,那么应该有一些简单的方法来使用编译的视图来构建电子邮件模板,但我无法弄清楚如何.
我从Rick Strahl找到了以下博客,可能会有这样的技巧:http: //www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp
但是,它似乎启动了一个完整的ASP.NET服务器来处理请求.
有没有一种简单的方法来加载MVC视图并渲染它?或者是Rick Strahl建议的加载ASP.NET运行时的唯一方法?
egl*_*ius 11
默认的asp.net视图引擎与asp.net引擎绑定.它与上下文联系在一起,我认为你可以解决它,但它绝对不简单.
问题在于默认的视图引擎+ asp.net引擎组合,其他视图引擎不应该有这个问题.至少火花视图引擎没有.
编辑: OP解决了最后的提示,但fwiw我的版本使用默认的asp.net mvc项目模板的控制器主页索引操作:
public class MyAppHost : MarshalByRefObject
{
public string RenderHomeIndexAction()
{
var controller = new HomeController();
using (var writer = new StringWriter())
{
var httpContext = new HttpContext(new HttpRequest("", "http://example.com", ""), new HttpResponse(writer));
if (HttpContext.Current != null) throw new NotSupportedException("httpcontext was already set");
HttpContext.Current = httpContext;
var controllerName = controller.GetType().Name;
var routeData = new RouteData();
routeData.Values.Add("controller", controllerName.Remove(controllerName.LastIndexOf("Controller")));
routeData.Values.Add("action", "index");
var controllerContext = new ControllerContext(new HttpContextWrapper(httpContext), routeData, controller);
var res = controller.Index();
res.ExecuteResult(controllerContext);
HttpContext.Current = null;
return writer.ToString();
}
}
}
Run Code Online (Sandbox Code Playgroud)
......来自一个单独的项目:
[TestMethod]
public void TestIndexAction()
{
var myAppHost = (MyAppHost)ApplicationHost.CreateApplicationHost(
typeof(MyAppHost), "/", @"c:\full\physical\path\to\the\mvc\project");
var view = myAppHost.RenderHomeIndexAction();
Assert.IsTrue(view.Contains("learn more about"));
}
Run Code Online (Sandbox Code Playgroud)
一些额外的说明:
结束回答我自己的问题:)
public class AspHost : MarshalByRefObject
{
public string _VirtualDir;
public string _PhysicalDir;
public string ViewToString<T>(string aspx, Dictionary<string, object> viewData, T model)
{
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
var workerRequest = new SimpleWorkerRequest(aspx, "", tw);
HttpContext.Current = new HttpContext(workerRequest);
ViewDataDictionary<T> viewDataDictionary = new ViewDataDictionary<T>(model);
foreach (KeyValuePair<string, object> pair in viewData)
{
viewDataDictionary.Add(pair.Key, pair.Value);
}
object view = BuildManager.CreateInstanceFromVirtualPath(aspx, typeof(object));
ViewPage viewPage = view as ViewPage;
if (viewPage != null)
{
viewPage.ViewData = viewDataDictionary;
}
else
{
ViewUserControl viewUserControl = view as ViewUserControl;
if (viewUserControl != null)
{
viewPage = new ViewPage();
viewPage.Controls.Add(viewUserControl);
}
}
if (viewPage != null)
{
HttpContext.Current.Server.Execute(viewPage, tw, true);
return sb.ToString();
}
throw new InvalidOperationException();
}
}
}
public static AspHost SetupFakeHttpContext(string physicalDir, string virtualDir)
{
return (AspHost)ApplicationHost.CreateApplicationHost(
typeof(AspHost), virtualDir, physicalDir);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,渲染文件:
var host = AspHost.SetupFakeHttpContext("Path/To/Your/MvcApplication", "/");
var viewData = new ViewDataDictionary<SomeModelType>(){ Model = myModel };
String rendered = host.ViewToString("~/Views/MyView.aspx", new Dictionary<string, object>(viewData), viewData.Model);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3379 次 |
| 最近记录: |