Может ли область ASP.NET MVC отображать собственный набор страниц ошибок?

Я объединил некоторые из своих веб-приложений в один основной проект ASP.NET MVC; назначение некоторых из них в отдельные Области, чтобы к ним можно было получить доступ через поддомены.

Используя этот (весьма полезный) ресурс (https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging), я установил customErrors и httpErrors в Web.config, чтобы отображались настраиваемые страницы ошибок. Работает хорошо.

Я буду использовать разный макет / стиль для каждой области / субдомена, поэтому мне интересно: Как я могу заставить область отображать собственный набор страниц ошибок?

При текущей настройке все поддомены будут отображать основной набор настраиваемых ошибок, которые добавляются в разделы customErrors и httpErrors (403.html, 404.html и т. Д.); но я бы предпочел специальные страницы ошибок для некоторых поддоменов. (Например, если одна из областей полностью обрабатывается отдельным доменом, обслуживать обычные страницы ошибок будет непрактично.)

Обновление: вот сценарий с кодом в соответствии с запросом. Спасибо Бену Фостеру, который дал здесь хорошее руководство: http://benfoster.io/blog/aspnet-mvc-custom-error-pages 2. Я поместил код customErrors, но не соответствующие httpErrors ... оставил его для краткости.

  <system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
      <error statusCode="404" redirect="~/404.aspx" />
      <error statusCode="500" redirect="~/500.aspx" />
    </customErrors>
  </system.web>

  <location path="MyArea1">
    <system.web>
      <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea1/500.aspx">
        <error statusCode="404" redirect="~/Areas/MyArea1/404.aspx" />
        <error statusCode="500" redirect="~/Areas/MyArea1/500.aspx" />
      </customErrors>
    </system.web>
  </location>

  <location path="MyArea2">
    <system.web>
      <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea2/500.aspx">
        <error statusCode="404" redirect="~/Areas/MyArea2/404.aspx" />
        <error statusCode="500" redirect="~/Areas/MyArea2/500.aspx" />
      </customErrors>
    </system.web>
  </location>

Приведенный выше код работает хорошо:

  • Если я перейду к «example.com/does/not/exist», я получу страницу с ожидаемой ошибкой на ~/404.aspx.
  • Если я перейду на «example.com/MyArea1/does/not/exist», я получу страницу с настраиваемой ошибкой на ~/Areas/MyArea1/404.aspx.

Соревнование:

Теперь я бы хотел, чтобы область (MyArea2) обслуживалась полностью отдельным доменом (например, exampleOnMyOtherDomain.com) с использованием HostDomainConstraint (как рекомендовано @TetsuyaYamamoto, в комментарии ниже). Ссылка, которая была доступна через «example.com/MyArea2/validlink», теперь будет доступна следующим образом: «exampleOnMyOtherDomain.com/validlink».

Теперь, если я попробую "exampleOnMyOtherDomain.com/does/not/exist", я получу 404 верхнего уровня (~/404.aspx). Вероятно, это связано с тем, что «MyArea2» больше не находится в пути, поэтому местоположение с путем «MyArea2» не будет выбрано.

Как я могу заставить область (MyArea2) обслуживать собственные страницы ошибок?


person cyrotello    schedule 10.10.2016    source источник
comment
Возможно, вам могут помочь настройки местоположения, см. Ссылку: msdn.microsoft.com/en- us / library / ms178692.aspx. Он может содержать различное содержимое внутри элемента <system.web> в каждом месте, что позволяет устанавливать customErrors и httpErrors для разных областей путем указания относительного пути к области.   -  person Tetsuya Yamamoto    schedule 13.10.2016
comment
Спасибо @TetsuyaYamamoto; это был довольно полезный комментарий. Я попробовал элемент location, и когда мои области являются подпутьем моего основного домена (например, example.com/MyArea ) элемент location работает нормально (path="MyArea")! Но вот проблема: когда моя зона обслуживается отдельным доменом, я не могу использовать ту же стратегию (например, myotherexample.net).   -  person cyrotello    schedule 13.10.2016
comment
Какая ошибка отображается при доступе к myotherexample.net? Вероятно, это потребует дополнительной настройки маршрутизации с HostNameContraint внутри модуля маршрутизации Global.asax (также включает перезапись URL-адресов в эту область). Кроме того, вы можете отредактировать свой вопрос, включив в него код зоны и код маршрута.   -  person Tetsuya Yamamoto    schedule 14.10.2016
comment
Спасибо @TetsuyaYamamoto; отредактировал вопрос.   -  person cyrotello    schedule 14.10.2016
comment
Посмотрев на настройки области web.config, я предполагаю, что вы можете использовать Application_Error для обработки ошибок с myotherexample.net на MyArea2 с помощью Request.Url.Host. Кроме того, вы можете настроить MapRoute для обработки MyArea2 как части пути к области перенаправления, за которым следует модуль перезаписи URL-адресов IIS: iis.net/expand/URLRewrite.   -  person Tetsuya Yamamoto    schedule 15.10.2016
comment
Я добавил ответ @TetsuyaYamamoto; прошу поделиться своими мыслями по этому поводу.   -  person cyrotello    schedule 18.10.2016


Ответы (1)


Основываясь на некоторых исследованиях и полезных указателях от @TetsuyaYamamoto, я применил следующую стратегию.

Я обрабатываю событие Application_Error в Global.asax, используя следующий код:

protected void Application_Error(object sender, EventArgs e)
{
    string hostName = Request.Headers["host"].Split(':')[0];
    if (hostName.Contains("exampleOnMyOtherDomain"))
    {
        Exception exception = Server.GetLastError();
        Response.Clear();
        HttpException httpException = exception as HttpException;
        Response.TrySkipIisCustomErrors = true;

        switch (httpException.GetHttpCode())
        {
            case 404:
                Response.StatusCode = 404;
                Server.Transfer("~/Errors/MyArea2_404.htm");
                break;
            case 500:
            default:
                Response.StatusCode = 500;
                Server.Transfer("~/Errors/MyArea2_500.htm");
                break;
        }
        Server.ClearError();
    }
}

На заметку:

  • hostName.Contains("exampleOnMyOtherDomain") следует сравнить имя хоста с областью, в которой я заинтересован. Я добавлю else...if утверждения для других областей;
  • Response.TrySkipIisCustomErrors = true должен предотвратить попытки IIS обработать ошибку;
  • Response.StatusCode устанавливает код состояния соответствующим образом ('404', '500' ...);
  • Server.Transfer() читает файл, который я хотел бы отобразить как страницу с ошибкой;
  • Server.ClearError() должен сигнализировать о том, что ошибка уже обработана.

Я хочу, чтобы _9 _ / _ 10_ продолжал обрабатывать обычные ошибки. Когда выполнение проходит через блок Application_Error без обработки (т.е. Server.ClearError() не вызывается), _13 _ / _ 14_ обработает ошибку.

Кажется, что это достойная стратегия для обработки ошибок для областей, обслуживаемых другим доменом.

person cyrotello    schedule 18.10.2016
comment
IMHO эта стратегия смогла выполнить отдельную обработку домена для настраиваемых страниц ошибок, однако вам нужно следить за тем, чтобы TrySkipIisCustomErrors работал правильно. Если перенаправление на страницу ошибки области не работает, убедитесь, что <httpErrors errorMode="Custom" existingResponse="PassThrough" /> на месте, если IIS был установлен в интегрированный режим, см. Эту ссылку: msdn.microsoft.com/en-us/library/ms690576 (v = vs.90) .aspx. - person Tetsuya Yamamoto; 19.10.2016
comment
Сделаю. Спасибо @TetsuyaYamamoto за вашу помощь! - person cyrotello; 19.10.2016
comment
У меня аналогичная проблема, я пытаюсь установить разные пользовательские страницы 404 для каждой области? У меня это есть в моем web.config httpErrors ‹error statusCode = 404 path = / Error / NotFound / responseMode = ExecuteURL /› Это направляет основную страницу 404, но я пытаюсь показать другую страницу 404, если маршрут имеет область myhost / area / notfound / route должен отображать myhost / myArea / Error / NotFound. Стоит ли мне задать новый вопрос, если нет, как мне изменить это решение? - person MSK; 25.03.2018