类型或名称空间'Mvc'名称在名称空间'System.Web'中不存在

问题描述 投票:1回答:3

我有一个使用RazorEngine生成电子邮件的类库。 RazorEngine使用Mvc。我在库类中引用了System.Web.Mvc,将其设置为本地复制,并且它存在于Bin文件夹中。但是,我仍然收到此异常。

[使它起作用的唯一方法是,在调用RazorEngine之前,实际上是从Mvc命名空间中调用MvcHtmlString test = new MvcHtmlString("test");之类的东西(找到here的解决方案]

我想这不是世界末日,但我仍然想解决这个问题(或至少了解是什么原因造成的)。干杯

asp.net-mvc razorengine
3个回答
3
投票

好,所以我可以将问题归结为以下内容:您有类似自托管的WebAPI /控制台应用程序的内容,并且想要使用Razor进行以下操作:创建HTML页面。这些Razor模板使用Sytem.Web.WebPages中的一些类或System.Web.Mvc等,它们捆绑在各自的程序集中。

但是这些类在视图中使用only。在调试模式下启动时,您会看到运行时不会not加载那些程序集,无论它们是否添加到项目中是否引用。在编译剃刀文件时出现,编译器仅看到名称空间从已加载的程序集中获取,因此您将获得那些X-notfound异常。您将必须加载所需的手动组装(并确保找到兼容的版本)。

一个简短的例子:

我们有一个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)都是由以下对象注入的对象:直接使用Razor时ASP.NET管道不可用。 (我不知道是否或如何除了模型之外,还可以将对象传递给Razor。因此,大多数类和函数从System.Web.Mvc或System.Web.WebPages命名空间可能无法访问(不重建ASP.NET的各个部分)。

使用的@Layout和@RenderBody()通常也是ASP.NET的一些帮助器。但是由于它们很常见,因此看来作者在RazorEngine解析器中手动重新创建了它们的功能。


1
投票

RazorEngine具有类CompilerServicesUtility。这负责在编译视图时加载程序集并使它们可用。默认情况下,它返回当前AppDomain中加载的所有程序集。

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

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


0
投票

更简单的解决方法(现在)是在顶部添加以下内容:

@using RazorEngine.Text

然后在您的模板中使用:

@(new RawString(Model.RawHtmlContents))

@(new RawString("<h3>This is custom <b>HTMLM/b></h3>"))
© www.soinside.com 2019 - 2024. All rights reserved.