更新
考虑到罪魁祸首是 MvcContrib 依赖项和 .NET 4.5 Web 应用程序之间存在一些冲突,我试图避免使用 MvcContrib PA,所以我完全重建了一个新的解决方案而不使用它们(我正在试验 Autofac + MEF)。然而,即使在这个解决方案中,我也得到了完全相同的错误。通过在我的视图中注释掉一行,事实证明,有问题的方法是模型的 Title 属性的 @Html.EditorFor 。如果我用@Html.TextBoxFor 替换它,一切似乎都正常。所以这似乎排除了 PA 和 MvcContrib 的任何问题。任何想法?
原帖
我在使用带有一些便携式区域(http://lostechies.com/erichexter/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib/)的 MVC4 Razor 应用程序时遇到了一个奇怪的问题,其中在我的区域视图中使用 HTML 助手时突然开始抛出异常。例外情况如下:
System.NullReferenceException 未被用户代码处理 H结果=-2147467261 Message=对象引用未设置为对象的实例。 来源=App_Web_field.master.5f132152.8jdnc_7s 堆栈跟踪: 在 http://server/Views/InputBuilders/EditorTemplates/Field.Master:line 5 中的 ASP.views_inputbuilders_editortemplates_field_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) 在 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter 作家,ICollection 孩子) 在 System.Web.UI.Control.RenderChildren(HtmlTextWriter 作家) 在 System.Web.UI.Control.Render(HtmlTextWriter 编写器) 在 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器) 在 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器) 在 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器) 在 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter 作家,ICollection 孩子) 在 System.Web.UI.Control.RenderChildren(HtmlTextWriter 作家) 在 System.Web.UI.Page.Render(HtmlTextWriter 编写器) 在 System.Web.Mvc.ViewPage.Render(HtmlTextWriter 编写器) 在 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器) 在 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器) 在 System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器) 在 System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,布尔 includeStagesAfterAsyncPoint) 内部异常:
我认为相关的代码是:
@using Cad.Web.Areas.Assets
@model Cad.Web.Areas.Editing.Models.ItemEditModel
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>@StringResources.NewItem</legend>
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.AuthorId)
<ol>
<li>
@Html.LabelFor(model => model.Title)
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</li>
<li>
@Html.LabelFor(model => model.Description)
@Html.TextAreaFor(model => model.Description, 4, 60, null)
@Html.ValidationMessageFor(model => model.Description)
</li>
</ol>
@Html.AntiForgeryToken()
<input type="submit" value="@StringResources.Create" />
</fieldset>
}
如果我注释掉两个li的内容,一切正常。如果我取消注释它们,只要操作方法返回其结果,我就会得到异常。我可以确认传递给视图的模型不为空,我什至可以无错误地访问其字段,例如通过添加带有@Model.Title的段落。我尝试在任何@Html...行中设置断点,但它没有被命中,并且抛出了相同的异常。
看起来我的便携式区域(包括视图)有问题,但我没有从这个异常中得到任何线索。这是我用 PA 构建整个架构的过程,至少这对像我这样的新手有用(VS2012、C#、MVC4):
a) 创建一个新的空白解决方案。在其中,创建一个包含 PA的新类库项目。使用 NuGet 将MvcContrib.Mvc3-ci添加到此项目,以及对MVC 程序集的引用(System.Web.Mvc、System.Web.Routing、System.Web.Razor 等:我刚刚从我的主机复制了所有与 MVC 相关的引用网络项目 - 见下文 (b)-)。创建您的PA 文件夹,其中包含控制器、模型和视图的子文件夹。将视图设置为嵌入式资源,并添加一个派生自PortableAreaRegistration的区域注册类(在 PA 文件夹的同一命名空间中),如下所示:
public class EditingAreaRegistration : PortableAreaRegistration
{
public override string AreaName { get { return "Editing"; } }
public override void RegisterArea(AreaRegistrationContext context, IApplicationBus bus)
{
base.RegisterArea(context, bus);
context.MapRoute(
"Editing_default",
"Editing/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
此外,在 Areas 文件夹中添加一个最小的 web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
</configuration>
在 Views 文件夹中,我放置了一个 _ViewStart.cshtml(我从主机 Web 应用程序中获取)。
b) 创建一个主机 Web 应用程序,引用 PA 项目和相同的 MvcContrib。在global.asax中添加对PortableAreaRegistration.RegisterEmbeddedViewEngine()的调用,使其看起来像这样:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
PortableAreaRegistration.RegisterEmbeddedViewEngine();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
我还在这个 Web 应用程序中添加了一个(非便携式)区域(用于管理目的);在那里,在 Areas 文件夹中,我确保 web.config 中的 pages 元素具有 validateRequest="false" (http://www.myclojureadventure.com/2010/06/mvccontrib-portable-areas-part-1.html)。然后我可以在我的路线中指定区域名称(当然,Resharper 之类的工具会在视图中发出错误信号,但我可以放心地忽略它)并且我被带到 PA,就好像它实际位于主机 Web 应用程序中一样.