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

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

К сожалению, кажется, что маршрут «По умолчанию» всегда первым ловит «бла». Фактически, единственный маршрут, которым я смог добраться до маршрута "Ошибка", - это бла / бла / бла / бла.

Это так, как он должен работать, потому что я видел другие примеры, в которых маршруты «По умолчанию» и «Ошибка» настроены точно так же, и кажется, что если бы они вводили контроллер, которого не существует, он попадет в маршрут "Ошибка".

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

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

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

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


person Jeff Keslinke    schedule 25.11.2008    source источник


Ответы (4)


Маршруты MVC проверяются в порядке их ввода.

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

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

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

person Community    schedule 25.11.2008
comment
Спасибо, это понимание, к которому я пришел, но просто не хотел принимать, основываясь на том, что я видел и чего я ожидал. Но я научусь с этим справляться. - person Jeff Keslinke; 26.11.2008

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

Route Debugger

person Scott    schedule 25.11.2008

Для обработки ошибок я использовал событие 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));
    }
}
person Darin Dimitrov    schedule 25.11.2008
comment
Это неправильное место для обработки исключений, и вы также меняете значение исключения, удаляя его. Это потенциально может сделать отладку очень и очень сложной. - person Jeff Putz; 27.05.2009
comment
Я не понимаю, почему использование обработчика Application_Error затрудняет отладку. Если вы зарегистрируете исключение, у вас будет полная трассировка стека. Другая проблема с маршрутом * catchall заключается в том, что он не будет вызываться, если в действии контроллера возникает исключение, поэтому, если вы хотите обработать 500 ошибок, вам нужно будет сделать это в другом месте. Я предпочитаю, чтобы весь код обработки исключений был в одном месте. - person Darin Dimitrov; 27.05.2009
comment
Самая большая проблема заключается в том, что вы теряете большую часть своего контекста к тому времени, когда ошибка достигает Application_Error, например объект сеанса, и если вы не учитываете, что эти вещи исчезли, отладка становится кошмаром. - person Nick Larsen; 02.10.2010

Это также может помочь при решении общих проблем MVC:

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

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

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

Но не это:

/ продукты / список / сортировка / имя

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

person Chris Moschini    schedule 25.06.2012
comment
Я пробовал это и искал в Интернете, пытаясь понять это, но у меня это не работает. Если я передаю 2 сегмента в URL-адресе, я получаю ошибку 404 независимо от того, добавляю я звездочку или нет. Любой совет? - person DavidHyogo; 12.02.2013
comment
Это может быть лучше всего в качестве нового вопроса - какие значения по умолчанию вы устанавливаете (третья строка в этом примере)? Лучше всего подойдет полный образец кода, который требует отдельного вопроса. - person Chris Moschini; 12.02.2013
comment
Хорошая идея, Крис, но я обнаружил свою глупую ошибку. Я определял свои маршруты в неправильном месте для MVC 4, и они игнорировались. См. Мой ответ на stackoverflow.com/questions/7515644/ Теперь я с радостью создаю всевозможные причудливые определения маршрутов! - person DavidHyogo; 14.02.2013