NullReference в переносимой области MVC вида формы при использовании Html helper
Обновить
Думая, что виновником был некоторый конфликт между зависимостями MvcContrib и веб-приложением.NET 4.5, я попытался избежать использования PA MvcContrib, поэтому я полностью перестроил новое решение, не используя их (я экспериментирую с Autofac + MEF). Тем не менее, даже в этом решении я получил точно такую же ошибку. Закомментировав строку во время моего просмотра, выясняется, что метод-нарушитель - @Html.EditorFor для свойства Title модели. Если я заменю его на @Html.TextBoxFor, все, похоже, будет работать. Так что, похоже, это исключает любые проблемы с PA и MvcContrib. Любая идея?
Оригинальный пост
Я испытываю странную проблему с приложением MVC4 Razor с некоторыми переносимыми областями ( http://lostechies.com/erichexter/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib/), которое внезапно начал генерировать исключения при использовании помощника HTML в моем представлении области. Исключение составляет:
System.NullReferenceException не было обработано кодом пользователя HResult=-2147467261 Сообщение = ссылка на объект не установлена для экземпляра объекта. Источник =App_Web_field.master.5f132152.8jdnc_7s Трассировки стека: в ASP.views_inputbuilders_editortemplates_field_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) в http://server/Views/InputBuilders/EditorTemplates/Field.Master: строка 5 в 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(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) InnerException:
На мой взгляд соответствующий код:
@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):
а) создать новый пустой раствор. В нем создайте новый проект библиотеки классов, который содержит PA. Добавьте к этому проекту MvcContrib.Mvc3-ci, используя NuGet, и ссылки на сборки MVC (System.Web.Mvc, System.Web.Routing, System.Web.Razor и т. Д. Я просто скопировал все ссылки, связанные с MVC, с моего хоста веб-проект - см. ниже, под (б)-). Создайте папку 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 (я беру мой из веб-приложения хоста).
б) создать хост-веб-приложение, ссылающееся на проект 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.config имеет validateRequest = "false" ( http://www.myclojureadventure.com/2010/06/mvccontrib-portable-areas-part-1.html). Затем я могу указать имя области в моих маршрутах (конечно, такие инструменты, как Resharper, сообщат об ошибке в представлении, но я могу спокойно игнорировать ее), и я попаду на PA, как если бы он физически находился в главном веб-приложении.,
1 ответ
Не могли бы вы показать свою модель?
Является ли какое-либо из полей вашей модели посторонним объектом?
Не зная, как выглядит ваша модель, вы можете попробовать это:
<ol>
<li>
@if(Model.Title!=null) {
@Html.LabelFor(model => model.Title)
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
}
</li>
<li>
@if(Model.Description!=null) {
@Html.LabelFor(model => model.Description)
@Html.TextAreaFor(model => model.Description, 4, 60, null)
@Html.ValidationMessageFor(model => model.Description)
}
</li>
</ol>
Даже если вы знаете, что ваш объект не равен нулю, ваш взгляд не знает. Если ваша модель имеет ссылку на сторонний объект, например
public Description Description { get; set; }
Вы можете попробовать изменить это в
public virtual Description Description { get; set; }
и посмотрим, что получится.