Не могу найти пользовательскую страницу с ошибкой - PullRequest
2 голосов
/ 05 августа 2010

Вот как я это определил (локально, на моей машине разработки):

    <customErrors mode="On" defaultRedirect="Error.aspx">
        <error statusCode="404" redirect="NotFound.aspx" />
    </customErrors>

И у меня есть атрибут [HandleError]:

[Authorize]
[HandleError]
public class HomeController : Controller
{ // etc.

Тем не менее, когда я набираю http://localhost:1986/blah,, я получаю следующую ошибку:

Ресурс не найден. Описание: HTTP 404. Ресурс, который вы ищете (или одна из его зависимостей), мог быть удален, изменилось его имя или временно недоступен. Пожалуйста, просмотрите следующий URL и убедитесь, что он написан правильно.

Запрошенный URL: /NotFound.aspx

URL-адрес, по которому он пытается перейти, соответствует ожидаемому: http://localhost:1986/NotFound.aspx?aspxerrorpath=/blah

Итак, он пытается перейти к пользовательскому файлу ошибок - однако он не может его найти. У меня есть NotFound.aspx в общем каталоге - там же, где и файл Error.aspx, поставляемый Microsoft по умолчанию. Почему он не может его найти?

Ответы [ 3 ]

3 голосов
/ 05 августа 2010

Вариант первый:

- создание контроллера ошибок с представлением «NotFound» вместе с представлением «Unknown». Это займет все, что является ошибкой 500 Server или 404 NotFound, и перенаправит вас на соответствующий URL. Мне не очень нравится это решение, поскольку посетитель всегда перенаправляется на страницу с ошибкой.

http://example.com/Error/Unknown

<customErrors mode="On" defaultRedirect="Error/Unknown">
    <error statusCode="404" redirect="Error/NotFound" />
    <error statusCode="500" redirect="Error/Unknown" />
</customErrors>
  • Wwwroot /
    • Контроллеры
      • Error.cs
    • Просмотров /
      • Ошибка /
      • NotFound.aspx
      • Unknown.aspx

Вариант второй:

I Определенно не предпочитают этот метод (поскольку он в основном возвращается к веб-формам, второй вариант - просто иметь статическую страницу Error.aspx и игнорировать маршрут в MVC), но это работает, тем не менее. Здесь вы игнорируете «Статический» каталог, размещаете там страницы с вашими физическими ошибками и обходите MVC.

routes.IgnoreRoute("/Static/{*pathInfo}");  //This will ignore everything in the "Static" directory
  • Wwwroot /
    • Контроллеры /
    • Статический /
  • Views /

Вариант третий:

Третий вариант ( ЭТО МОЙ ЛЮБИМЫЙ ) - возвращать представление ошибок из любого представления, в котором обнаружена ошибка. Это потребует от вас кодирования блоков Try / Catch по пути «известных» ошибок, а затем вы можете использовать HandleError для неизвестных ошибок, которые могут появиться. Для этого нужно сохранить первоначально запрошенный URL-адрес, но вернуть представление ERROR.

Пример:
http://example.com/Products/1234 покажет страницу сведений для ProductID 1234
http://example.com/Products/9999 отобразит страницу ошибки NotFound , поскольку ProductID 9999 не существует
http://example.com/Errors/NotFound «следует» никогда не показывать, потому что вы обрабатываете эти ошибки индивидуально в своих контроллерах.

Web.Config

<customErrors mode="On">
</customErrors>

Контроллер

// Use as many or as few of these as you need
[HandleError(ExceptionType = typeof(SqlException), View = "SqlError")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "NullError")]
[HandleError(ExceptionType = typeof(SecurityException), View = "SecurityError")]
[HandleError(ExceptionType = typeof(ResourceNotFoundException), View = "NotFound")]
Public Class ProductController: Controller{
    public ViewResult Item(string itemID)
    {
        try
        {
            Item item = ItemRepository.GetItem(itemID);
            return View(item);
        }
        catch()
        {
            return View("NotFound");
        }
    }
}

Структура папок

  • Wwwroot /
    • Контроллеры /
    • Общий /
      • NotFound.aspx
      • NullError.aspx
      • SecurityError.aspx
      • SqlError.aspx
    • Views /

Вариант четвертый:

Последним вариантом будет то, что вы создадите свой собственный фильтр для таких вещей, как ResourceNotFoundException и присоедините его к своему классу контроллера. Это будет делать то же самое, что и выше, но с дополнительным преимуществом отправки кода ошибки также клиенту.

Ричард Дингвол говорит об этом в своем блоге .

3 голосов
/ 05 августа 2010

Если Error.aspx и NotFound.aspx находятся в общем каталоге, есть ли контроллер, предназначенный для их обслуживания?Если у вас не настроен какой-либо маршрут контроллера для обслуживания файлов, то тот факт, что они находятся в общей папке, не имеет значения.

У вас есть несколько вариантов, вы можете создать ErrorController, который будет обрабатывать запросыдля этих представлений и определения маршрутов, указывающих на эти действия контроллера:

[OutputCache(CacheProfile = "Default", VaryByParam = "none")]
public class ErrorController : DefaultAreaBaseController
{
    public ViewResult ServiceUnavailable() {
        Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;

        return View("ServiceUnavailable");
    }

    public ViewResult ServerError() {
        Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        return View("ServerError");
    }

    public new ViewResult NotFound() {
        Response.StatusCode = (int)HttpStatusCode.NotFound;

        return View("NotFound");
    }
}

Или, в качестве альтернативы, вы можете создать игнорирующие маршруты, указывающие на физические файлы, и размещать страницы ошибок где-то, кроме папки Views (например,корневой каталог):

routes.IgnoreRoute("Error.aspx/{*pathInfo}");
routes.IgnoreRoute("NotFound.aspx/{*pathInfo}");

Любое из этих решений жизнеспособно, однако, в зависимости от вашей конфигурации, использование IgnoreRoute () может быть более идеальным, поскольку оно откажется от необходимости передавать запрос в MVC только для обслуживания статическогостраница ошибки.

0 голосов
/ 05 августа 2010

Ваше смешивание веб-форм и концепций MVC здесь.Отключите пользовательские ошибки в файле web.config.Затем в атрибуте HandleError необязательно укажите тип и представление, по умолчанию ищется error.aspx в views \ CurrentController, а затем views \ shared.Хотя вы можете настроить обработку 404 с помощью фильтра HandleError, вы, вероятно, захотите создать фильтр только для обработки 404, причины и способы которых подробно описаны здесь:

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