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; }

и посмотрим, что получится.

Другие вопросы по тегам