c# - 有没有办法从非 Web 应用程序处理 MVC View (aspx 文件)?

标签 c# asp.net-mvc templates

我有一个正在运行的后台服务,可以向我网站的用户发送电子邮件。我想将电子邮件模板编写为 MVC View ,以保持一致(以便可以使用相同的模型发送电子邮件和显示网页)。

不幸的是,当我尝试执行 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

似乎如果我将 MvcBuildViews 设置为 true,应该有一些简单的方法来使用编译的 View 来构建电子邮件模板,但我不知道如何做。

我从 Rick Strahl 那里找到了以下博客,它可以解决问题: http://www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp

但是,它似乎启动了整个 ASP.NET 服务器来处理请求。

是否有一种简单的方法来加载 MVC View 并渲染它?还是按照 Rick Strahl 的建议加载 ASP.NET 运行时的唯一方法?

最佳答案

默认的 asp.net View 引擎绑定(bind)到 asp.net 引擎。它与上下文相关,我认为您可以解决它,但它绝对不简单

问题出在默认 View 引擎 + asp.net 引擎组合上,其他 View 引擎不应该有这个问题。至少 Spark View 引擎没有。


编辑: OP 使用最后的提示解决了问题,但是我的版本使用了默认 asp.net mvc 项目模板的 Controller 主页索引操作:

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

...来自一个单独的项目:

    [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"));

    }

一些额外的注意事项:

  • 新 HttpRequest 中的 url 无关紧要,但必须是有效的 url
  • 它不打算从已经有上下文的 asp.net 应用程序中使用/也就是说,我不确定它是否真的会生成新的 AppDomain 并工作
  • Controller 类型的构造函数和特定实例在代码中是显式的,可以替换为要在参数中传递的内容,但需要处理 MarshalByRef 的限制/最坏的情况可以使用一些简单的反射

关于c# - 有没有办法从非 Web 应用程序处理 MVC View (aspx 文件)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3702526/

相关文章:

asp.net-mvc - MigrateDatabaseToLatestVersion 未执行

c# - LINQ Order By Descending with Null Values on Bottom

c++ - 别名模板中的模板参数推导 - 类型定义任何成员函数指针

c# - 如何在 C# 中将数据库对象转换为 int?

c# - System.TypeCode 枚举中的异常字符串类型代码

c# - 使用 httpwebrequest/httpwebresponse 从服务器到客户端的 Docx 文件传输

asp.net-mvc - 始终使用 WebDeploy on Destination 删除 Angular dist 文件夹内容

validation - 在CloudFormation模板中设置所需的参数输入

angularjs - 如何在 AngularJS 指令中使用定义的文本/ng-模板

c# - 如何获取存储过程返回的两个表