.Net MVC Routing Catchall не работает

Я не могу понять это. Я экспериментирую с MVC Beta и пытаюсь реализовать универсальный маршрут, так что если пользователь вводит mysite.com/blah вместо mysite.com/home/index, он попадет в маршрут "Ошибка".

К сожалению, кажется, что маршрут "По умолчанию" всегда ловит "бла". На самом деле единственным способом, с которым я смог добраться до маршрута "Ошибка", является blah/blah/blah/blah.

Так ли это должно работать, потому что я видел другие примеры, которые имеют маршрут "По умолчанию" и "Ошибка", настроенный так же, как и это, и кажется, что если они должны были ввести контроллер, t существует, он попадет в маршрут "Ошибка".

Есть ли что-то, что мне не хватает (очень возможно), или мне просто нужно создать конкретный маршрут для каждого контроллера?

Код, который я использую:

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

        routes.MapRoute(
            "Error",
            "{*catchall}",
            new { controller = "Base", action = "Error", id = "404" }
        );

Спасибо, Джефф

Ответы

Ответ 1

Трассы MVC проверяются в том порядке, в котором они введены.

Mysite/blah будет найден по умолчанию. Контроллер будет blah, а действие - индексом.

Когда вы вошли в маршрут mysite/blah/blah/blah/blah, вы дали ему маршрут, на который он не смог сопоставить маршрут по умолчанию, а затем вызывается ваш общий маршрут.

В других примерах вы заметили, были ли установлены фильтры ошибок? Я уверен, что у сайта asp.net mvc по умолчанию есть некоторые атрибуты обработки ошибок на страницах.

Ответ 2

Ваш первый маршрут будет захватывать большинство URL-адресов, поскольку у вас есть значения по умолчанию для элементов, вы можете визуализировать это с помощью отладчика маршрута от Phil Haack, см. ссылку:

Отладчик маршрутов

Ответ 3

Для обработки ошибок я использовал событие Application_Error в одном из моих проектов:

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "HttpError500");

            if (httpException.GetHttpCode() == 404)
            {
                routeData.Values["action"] = "HttpError404";
            }

        Server.ClearError();
        Response.Clear();
        IController errorController = new ErrorController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
}

Ответ 4

Это также может помочь при работе с основными задачами MVC:

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{*id}",                          // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

То есть, где он говорит {id}, измените его на {*id}. Это позволяет окончательному параметру id потреблять столько дополнительного пути, сколько может быть передано. Правило по умолчанию принимает это:

/человек/имя/джо

Но не это:

/Продукты/список/SortBy/имя

Второй URL-адрес будет вызывать 404 без этой модификации маршрута.