ASP MVC.NET3 Ошибка ссылки на локальный объект IIS7 - PullRequest
4 голосов
/ 25 января 2012

Во время разработки веб-приложения mvc у меня возникают проблемы с запуском локального экземпляра сайта. Когда я пытаюсь перезагрузить страницу, после успешной первой загрузки я вижу ошибку ниже. Если я запускаю сайт через виртуальный сервер VS, никаких проблем не возникает. Мой пул приложений работает в интегрированном режиме и работает под управлением .net 4. Есть идеи, почему это происходит? Достаточно ли этой информации?

[NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.] System.Web.HttpServerVarsCollection.Get (имя строки) +109 System.Web.Mvc.UrlRewriterHelper.WasThisRequestRewritten (HttpContextBase httpContext) +59 System.Web.Mvc.PathHelpers.GenerateClientUrlInternal (HttpContextBase httpContext, String contentPath) +213 System.Web.Mvc.PathHelpers.GenerateClientUrlInternal (HttpContextBase httpContext, String contentPath) +168 System.Web.Mvc.PathHelpers.GenerateClientUrl (HttpContextBase httpContext, String contentPath) +148 LeadManager.Web.UI.Helpers.MenuHelper.GenerateUrl (URL-адрес строки) в C: \ Development \ Hg \ LeadManager \ Web.UI \ Helpers \ MenuHelper.cs: 1132 LeadManager.Web.UI.Helpers.MenuHelper.BuildLeadManagementMenu (Меню меню, агент агента) в C: \ Development \ Hg \ LeadManager \ Web.UI \ Helpers \ MenuHelper.cs: 554 LeadManager.Web.UI.Helpers.MenuHelper.AddNavMenu (агент агента) в C: \ Development \ Hg \ LeadManager \ Web.UI \ Helpers \ MenuHelper.cs: 530 ASP._Page_Views_Shared__Layout_cshtml.Execute () в c: \ Development \ Hg \ LeadManager \ Web \ Views \ Shared_Layout.cshtml: 115 System.Web.WebPages.WebPageBase.ExecutePageHierarchy () +279 System.Web.Mvc.WebViewPage.ExecutePageHierarchy () +103 System.Web.WebPages.WebPageBase.ExecutePageHierarchy (WebPageContext pageContext, средство записи TextWriter, WebPageRenderingBase startPage) +172 System.Web.WebPages.WebPageBase.Write (результат HelperResult) +88 System.Web.WebPages.WebPageBase.RenderSurrounding (StringpartalViewName, Действие 1 body) +233 System.Web.WebPages.WebPageBase.PopContext() +233 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +377 System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +32 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func 1 продолжение) +748196 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter (фильтр IResultFilter, ResultExecutingContext preContext, фильтры Func 1 continuation) +748196 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList 1, ActionResult actionResult) +265 System.Web.Mvc.ControllerActionInvoker.InvokeAction (ControllerContext controllerContext, String actionName) +748160 System.Web.Mvc.Controller.ExecuteCore () +159 System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) +334 System.Web.Mvc. <> C_ DisplayClassb.b _5 () +62 System.Web.Mvc.Async. <> C_ DisplayClass1.b _0 () +15 System.Web.Mvc. <> C_ DisplayClasse.b _d () +52 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +437 System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое и завершено синхронно) + 354

MenuHelper используется для создания навигационных меню. Код, который терпит неудачу, является оператором возврата вне if:

private static string GenerateUrl(string url)
{
    if (instance == null)
    {
        // hack to enable using this on old web forms pages
        return UrlHelper.GenerateContentUrl(url, new HttpContextWrapper(HttpContext.Current));
    }
    return (new UrlHelper(instance.htmlHelper.ViewContext.RequestContext)).Content(url);
}

private static string GenerateUrl(string actionName, string controllerName)
{
    if (instance == null)
    {
        // hack to enable using this on old web forms pages
        return GenerateUrl(String.Format("{0}/{1}", controllerName, actionName));
    }

    if (instance.htmlHelper == null)
        throw new InvalidOperationException("htmlHelper has not been populated.");
    if (instance.htmlHelper.ViewContext == null)
        throw new InvalidOperationException("ViewContext has not been populated.");
    if (instance.htmlHelper.ViewContext.RequestContext == null)
        throw new InvalidOperationException("RequestContext has not been populated.");

    UrlHelper urlHelper = new UrlHelper(instance.htmlHelper.ViewContext.RequestContext);
    if (urlHelper == null)
        throw new InvalidOperationException("UrlHelper has not been populated.");

    if (String.IsNullOrEmpty(actionName))
        throw new InvalidOperationException("actionName has not been populated.");
    if (String.IsNullOrEmpty(controllerName))
        throw new InvalidOperationException("controllerName has not been populated.");

    return (urlHelper.Action(actionName, controllerName));
}

Ответы [ 3 ]

4 голосов
/ 29 февраля 2012

Я обнаружил проблему, это был модуль перезаписи URL IIS7. Я не уверен, почему или как, но я решил проблему, удалив ее.

1 голос
/ 07 августа 2013

У меня тоже возникла эта проблема, и действительно, удаление IIS7 URL Rewrite Module помогло бы ее исправить.Проблема в том, что у нас всегда был установлен модуль Rewrite на всех наших серверах, что заставляло меня немного нервничать.Так что я заглянул в это немного больше, чтобы увидеть, что я изменил, чтобы вызвать это, и оказалось, что это я.Фактически, я делал это несколько раз раньше и, похоже, не учусь, потому что это легко сделать.

Мой класс воспринял UrlHelper как зависимость через конструктор, такой как

public class MyClass : IMyInterface
{
   private readonly UrlHelper _url;

   public MyClass(UrlHelper url)
   {
      _url = url;
   }

   public RedirectResult RedirectMeSomewhere()
   {
      return new RedirectResult(_url.Action("MyAction", "MyController"));
   }
}

и моя привязка Ninject выглядела следующим образом:

Bind<IMyInterface>()
   .To<MyClass>()
   .InSingletonScope();

, где, как это и должно было выглядеть, она обслуживает правильный UrlHelper для запроса вместо уже расположенного, созданного какСинглтон, когда сайт впервые появился.

Bind<IMyInterface>()
   .To<MyClass>()
   .InRepositoryScope();

Требуется некоторое время, чтобы заметить эти вещи, мне нужно придумать тест, чтобы убедиться, что UrlHelper не обслуживается в синглтоне.

tl: dr

Привязка My Ninject для класса, который принял UrlHelper в качестве зависимости через своего конструктора, была установлена ​​на SingletonScope() вместо RequestScope(), то естьочень плохо по понятным причинам ..

В любом случае, надеюсь, что это поможет кому-то (или мне в будущем).

0 голосов
/ 26 февраля 2012

Итак, это строка с ошибкой:

return (new UrlHelper(instance.htmlHelper.ViewContext.RequestContext)).Content(url);

Мы знаем, что экземпляр не является нулевым из-за строки выше, которая уже проверяет на нулевое значение.Исключения с нулевой ссылкой являются наиболее распространенными необработанными исключениями и их также проще всего избежать.В общем, вы никогда не должны предполагать, что свойства или параметры, которые могут иметь тип nullЯ думаю, что instance.htmlHelper это ваша проблема.Я предполагаю, что htmlHelper является экземпляром System.Web.Mvc.HtmlHelper.Следовательно, ViewContext и RequestContext должны не быть нулевыми, если это действительный HtmlHelper, созданный MVC.

Простое решение состоит в том, чтобы проверять наличие нулей следующим образом:

if (instance.htmlHelper == null)
{
    throw new InvalidOperationException("htmlHelper has not been populated.");
}

return (new UrlHelper(instance.htmlHelper.ViewContext.RequestContext)).Content(url);

Очевидно, что вы могли бы повторить это для ViewContext и RequestContext от MVC должен заполнить их.

Теперь, предполагая, что htmlHelper равен нулю (наиболее вероятная ситуация), у вас есть небольшая проблема проектирования.Что вы действительно должны делать - это расширять класс HtmlHelper, а не использовать статический метод.Кроме того, вы, кажется, используете какой-то статический экземпляр, который, вероятно, также недопустим в MVC.MVC обычно создает экземпляры контроллеров и представлений для каждого запроса.Вы все еще можете использовать статический метод для реализации веб-форм, но для MVC вы должны расширить HtmlHelper следующим образом:

public static MvcHtmlString GenerateUrl(this htmlHelper, string url)
{
    return (new UrlHelper(htmlHelper.ViewContext.RequestContext)).Content(url);
}

Убедитесь, что вы всегда используете текущий активный HtmlHelper из MVC, а не какой-то статический экземпляр.Я не совсем уверен, что ViewContext или RequestContext могут быть нулевыми после завершения запроса.Я никогда не пытался сохранить HtmlHelper после одного запроса.Даже если они не равны NULL, в противном случае они могут быть недействительными и стать причиной вашей проблемы в конвейере MVC.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...