命名空间“System.Web”中不存在类型或命名空间“Mvc”名称

时间:2014-03-25 10:01:21

标签: asp.net-mvc razorengine

我有一个使用RazorEngine生成电子邮件的类库。 RazorEngine使用Mvc。 我在我的库类中引用了System.Web.Mvc,将其设置为copy local,它存在于Bin文件夹中。但是我仍然得到这个例外。

我实现它的唯一方法是在调用RazorEngine之前实际调用Mvc命名空间中的某些内容,例如MvcHtmlString test = new MvcHtmlString("test");(找到解决方案here

我想这不是世界末日,但我仍然想解决这个问题(或者至少了解是什么导致了这个问题)。干杯

2 个答案:

答案 0 :(得分:3)

好的,所以我能够将问题归结为以下问题: 您有类似自托管的WebAPI /控制台应用程序,并希望使用Razor 创建HTML页面。那些Razor模板使用Sytem.Web.WebPages中的一些类 或System.Web.Mvc等,它们捆绑在它们自己的程序集中。

但是这些类在视图中仅使用 。在调试模式下启动时,您将看到 运行时加载这些程序集,无论它们是否已添加到项目中 参考与否。在编译剃刀文件时,编译器只会看到命名空间 从加载的程序集中,您可以获得那些X-not-found异常。你将不得不加载所需的 手动组装(并确保找到兼容的版本)。

一个简短的例子:

我们有一个layout.cshtml和一个index.cshtml。我们使用一些HTML帮助函数来创建表单。 layout.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
</head>
<body>
  <div class="main-content">
    @RenderBody()
  </div>
</body>
</html>

index.cshtml:

@using System.Web.Mvc;
@{
  Layout = "layout";
}
<div class="box-body">
  <h1>Hello!</h1>
  <p>
    Got Html? @MvcHtmlString.Create("<b>FooBarBaz</b>")
  </p>
</div>

解析剃刀文件并处理HTML输出的源代码。为简单起见 假设所有文件都在可执行文件附近;您可能需要适应您的存储结构:

//load required assembly. By using the short name here the runtime uses
//the the first one that matches. See MSDN for further information
System.Reflection.Assembly.Load("System.Web.Mvc");
//cache the template before the actual page to avoid a null reference exception
RazorEngine.Razor.GetTemplate(File.ReadAllText("layout.cshtml"), "layout");
var result = RazorEngine.Razor.Parse(File.ReadAllText("index.cshtml"));
Console.Write(result);

然后,您需要将程序集添加到项目中(在此示例中可以通过nuget,Microsoft.AspNet.Mvc),也可以手动添加引用(如果未自动添加)。这样就可以将(希望)正确的版本与可执行文件一起复制。

最后一点:

ASP.Net MVC视图(例如@Html)中几乎所有可用的东西都是注入的对象 ASP.NET管道,因此在直接使用Razor时不可用。 (我不知道是否或如何 除了模型之外,还可以将对象传递给Razor)所以大多数类和函数都是如此 从System.Web.Mvc或System.Web.WebPages命名空间可能无法访问 (不重构ASP.NET的部分)。

使用过的@Layout和@RenderBody()通常也是一些ASP.NET助手。但是因为它们很常见,所以作者似乎在RazorEngine解析器中手动重新创建了它们的功能。

答案 1 :(得分:1)

RazorEngine有一个班级CompilerServicesUtility。这负责在编译视图时加载和制作程序集。它默认返回当前AppDomain中加载的所有程序集。

当您实例化该程序集中的任何类时,程序集将自动加载到AppDomain中,这就是在调用RazorEngine之前实例化MvcHtmlString test = new MvcHtmlString("test");的原因。

对于查看代码的人来说,这有点不直观,但另一种确保Razor编译并且您可以使用MvcHtmlString的方法是将System.WebSystem.Web.Mvc程序集加载到在执行/编译视图之前使用AppDomain.Current.Load("<assemblyname>")的当前AppDomain。当然,您可以指定配置文件中所需的程序集列表,并以动态方式加载它。