Маршрутизация MVC3 только с контроллером и urlParameter — действие не указано

#asp.net-mvc #model-view-controller #asp.net-mvc-3 #routing

#asp.net-mvc #модель-представление-контроллер #asp.net-mvc-3 #маршруты

Вопрос:

Обновление: Проблема перестала возникать с нашей последней полной перестройкой, но файлы web.config и global.asax.cs не были изменены с тех пор, как я опубликовал этот вопрос. Я все еще не уверен, что было причиной поведения, которое я наблюдал.

Исходное сообщение: В веб-приложении, над которым я работаю, у нас есть два возможных пути, которые следуют за установками — один для новых установок, а другой для обновлений. В зависимости от того, какой путь выбран, начальный URL, который вызывает наш установщик, является либо <siteroot>/Install , либо <siteroot>/Install?upgrade=true . Проблема в том, что, по-видимому, наши сопоставления маршрутов неправильно обрабатывают этот второй URL, и в итоге он делает странные вещи, даже если он соответствует желаемому определению маршрута (согласно отладчику маршрутов Haack). Несколько странных вещей: URL <siteroot>/Install?upgrade=true переписывается как <siteroot>/Install/?upgrade=true . Routedebugger от Haack показывает URL, соответствующий маршруту по умолчанию, в столбце «соответствует текущему запросу» таблицы маршрутов, но там, где он сообщает «Согласованный маршрут», говорится «n / a». Также не сообщается о данных маршрута — нет контроллера, нет действия и нет urlParameter. Кроме того, сгенерированный URL, сообщаемый routedebugger, является Generated URL: <siteroot>/NotFound?upgrade=true using the route "NotFound" , и все же запрос не соответствует маршруту «Не найден», и текущая информация запроса показывает (часть) правильную информацию:

 AppRelativeCurrentExecutionFilePath is the portion of the request that Routing acts on.
AppRelativeCurrentExecutionFilePath: ~/Install/
  

Эту конкретную проблему можно легко устранить с помощью вызова <siteroot>/Install/Index?upgrade=true , но я бы предпочел получить четкое представление о том, почему это происходит, и устранить основную причину, а не работать над проблемой. Вот основной код:

Global.asax.cs:

 public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("{resource}.asp/{*pathInfo}");

    //404 error page
    routes.MapRoute("NotFound", "NotFound",
        new { controller = "Navigation", action = "NotFound" }
    );

    // 404 device not found page
    routes.MapRoute("DeviceNotFound", "DeviceNotFound",
        new { controller = "Navigation", action = "DeviceNotFound" }
    );

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
        new[] { "Nm.Web.Mvc.Controllers", "Nm.Web.UI" }
    );

}
  

InstallController.cs:

 [HttpGet]
public ActionResult Index(int? installStep = null, bool upgrade = false)
{
    var ins = DependencyResolver.Current.GetService<IInstallService>();

    if (installStep != null)
    {
        ins.InstallStep = (InstallStep)installStep;
    }

    if ((upgrade == true) amp;amp; (ins.HasDefaultAdminPassword() == false))
    {
        ins.InstallStep = InstallStep.Finished;
        return RedirectToAction("Login", "User");
    }

    if (isLocalServer() amp;amp; ins.InstallStep == InstallStep.SetAdminPassword)
    {
        return RedirectToAction("SetAdminPassword");
    }
    return RedirectToAction("SelectPath");
}
  

У меня установлена одна точка останова в методе Install controller Index, другая — в методе Application_Error в Global.asax, и ни одна из них никогда не срабатывает. Я не совсем уверен, откуда берется «не найденный» материал — у нас есть этот раздел в нашем web.config:

 <customErrors mode="Off" defaultRedirect="~/Error" redirectMode="ResponseRedirect">
  <error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
  

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

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

 routes.MapRoute(
    "Install", // Route name
    "Install/{upgrade}", // URL with parameters
    new { controller = "Install", action = "Index", upgrade = UrlParameter.Optional }, // Parameter defaults
    new[] { "Nm.Web.Mvc.Controllers", "Nm.Web.UI" }
);
  

У кого-нибудь есть какие-либо мысли или предложения?

Комментарии:

1. Вам следует подумать об изменении вашей маршрутизации; возможно, использовать <siteroot>/Install для начальных установок и <siteroot>/Upgrade для обновлений. Если вы хотите, чтобы оно отображалось с тем же методом действия, вы можете сделать это с помощью того же параметра маршрута по умолчанию.

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

3. Кроме того, самое странное во всей этой проблеме заключается в том, что это работало, и AFAIK никаких изменений маршрутизации или конфигурации, которые могли бы повлиять на это, не было сделано.

4. И теперь это снова работает, хотя я не менял файл web.config или global.asax.cs — все, что я сделал, это скомпилировал последнюю версию всего нашего внутреннего кода, который никоим образом не должен влиять на поведение веб-интерфейса, хотя, похоже, это так. Странно.

5. Код работает таинственным образом!