【问题标题】:Controller + View in a separate assembly - The name 'ViewBag' does not exist in the current context控制器 + 在单独的程序集中查看 - 当前上下文中不存在名称“ViewBag”
【发布时间】:2014-05-13 08:14:17
【问题描述】:

致模组:不是重复的,其他答案(主要是“检查 Views 文件夹中的 web.config”)不起作用。

我有一个主要的 asp.net MVC 应用程序,它在单独的程序集中发现控制器和视图:具有 MEF 和自定义 ControllerFactory 的控制器,具有自定义 VirtualPathProvider 的视图,它发现嵌入在同一(控制器的)程序集中的视图。

这两个部分的发现都很好:控制器工厂找到控制器并使用 Ninject 对其进行初始化,VirtualPathProvider 认识到它必须在程序集中查找视图并加载它。

单独程序集Views文件夹下的web.config是VS2013新建asp.net mvc项目时生成的那个:

<?xml version="1.0"?>

<configuration>
    <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="Fos.WS.DemoCustomization" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>
  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>

  <system.webServer>
    <handlers>
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
</configuration>

控制器:

public ActionResult Index()
    {
        var dll = "~/Plugins/" + this.AssemblyName; //"~/Plugins/" is to instruct the custom viewpathprovider to discover the view from the assembly
        return View(dll + "/Fos.WS.DemoCustomization.Views.Demo.Index.cshtml"); 
    }

查看:

@{
ViewBag.Title = "Demo";
}

<h2>Hi, Demo</h2>

我不断收到的错误是

Compiler Error Message: CS0103: The name 'ViewBag' does not exist in the current context

Source Error:




Line 38:         public override void Execute() {
Line 39:   
Line 40:     ViewBag.Title = "Demo";
Line 41: 
Line 42: BeginContext("~/Plugins/Fos.Ws.DemoCustomization.dll/Fos.WS.DemoCustomization.Views.Demo.Index." +


Source File: c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\482869c5\3f1d4579\App_Web_fos.ws.democustomization.views.demo.index.cshtml.41ce77d0.bg7gacz2.0.cs    Line: 40 

谢谢

编辑:试图删除 viewbag 部分并只保留 ,现在错误不同了: '~/Plugins/Fos.Ws.DemoCustomization.dll/Fos.WS.DemoCustomization.Views.Demo.Index.cshtml' 处的视图必须派生自 WebViewPage 或 WebViewPage。

看起来 web.config 不存在。

【问题讨论】:

    标签: asp.net-mvc razor mef


    【解决方案1】:

    回答有点晚了,但我想我可以补充一点见解。所以我没有在这个确切的场景中工作过,但我已经分别使用过 MEF 和动态视图渲染。

    很明显

    因此,如果我正确阅读了您的设置,那么一个明显的问题是您依赖于上面定义的 web.config,但它位于远程程序集中。我不相信您的 IOC 容器能够从远程配置访问程序集定义。

    您甚至意识到它没有获取您问题中的网络配置值。我知道您说过您曾尝试过其他 Web 配置解决方案但没有成功,但我认为这将是您最好的选择,因为它需要以某种方式提取这些定义,而尝试手动定义这些定义将是一个 hack。

    不太明显

    您看到这些异常的原因是 ViewData 对象是由 WebViewPage 基类定义的,您可以看到您的配置将其定义为所有视图的基类。没有那个基类,它就不是一个视图,也不是可解析的。

    我认为在显式访问 ViewBag 时隐藏此错误的原因是 ViewBag 是 ViewContext 中的包装器,将 ViewData 传递给 DynamicViewDataDictionary。如果您传入 null ViewData,ViewContext 将不会构建,我认为通过在 null ViewContext 上显式调用 ViewBag 它只是在链的早期爆炸,或者更确切地说,编译器以这种方式识别了这个问题。

    实用助手

    很抱歉,我无法为这个问题提供灵丹妙药。只是更多指向 web.config 的信息没有被引入。我将添加一个有趣的助手,这也是获取远程/动态 Razor 视图以从文件中手动解析的技巧。您还可以使用它来确保远程视图的格式正确并查看它们将如何输出。如果您将其插入,我敢打赌,因为它定义了一个 RazorView,在这种情况下管理 WebPageView 初始化。它适用于您的远程视图。值得注意的是,这是一种 hack,并不适合处理所有视图渲染,但在一些棘手的角落情况下肯定很方便。

    using System.IO;
    using System.Web.Mvc;
    
    namespace Utils
    {
        public class RazorUtility
        {
            /// <summary>
            /// Takes a file path to a Razor View and a controller context and renders the the View to a string
            /// </summary>
            /// <param name="path">file path to view</param>
            /// <param name="context">controller context to render against</param>
            /// <returns></returns>
            public static string RenderView(string path, ControllerContext context)
            {
                //You need to include the Model in the ViewDate of the context passed in.
                var st = new StringWriter();
                var razor = new RazorView(context, path, null, false, null);
                razor.Render(new ViewContext(context, razor, context.Controller.ViewData, context.Controller.TempData, st), st);
                return st.ToString();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-25
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多