Обновление: Проблема перестала возникать с нашей последней полной перестройкой, но файлы web.config и global.asax.cs не изменились с тех пор, как я опубликовал этот вопрос. Я до сих пор не уверен, что стало причиной наблюдаемого мной поведения.
Исходное сообщение :
В веб-приложении, над которым я работаю, у нас есть два возможных пути, которые следуют за установками - один для новых установок, а другой для обновлений. В зависимости от того, какой путь выбран, начальный URL, который вызывает наш установщик, будет <siteroot>/Install
или <siteroot>/Install?upgrade=true
. Проблема заключается в том, что, по-видимому, наши отображения маршрутов неправильно обрабатывают этот второй URL-адрес, и он делает странные вещи, даже если он соответствует желаемому определению маршрута (согласно отладчику маршрутов Haack). Несколько странных вещей: URL <siteroot>/Install?upgrade=true
переписывается как <siteroot>/Install/?upgrade=true
. Маршрутный отладчик Haack отображает URL-адрес, соответствующий маршруту по умолчанию, в столбце «соответствует текущему запросу» таблицы маршрутов, но там, где он сообщает «Соответствующий маршрут», он говорит «н / д». Также не сообщается никаких данных о маршруте - ни контроллера, ни действий, ни параметра urlParameter. Кроме того, созданный URL-адрес routedebugger сообщает Generated URL: <siteroot>/NotFound?upgrade=true using the route "NotFound"
, и все же запрос НЕ соответствует маршруту "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) && (ins.HasDefaultAdminPassword() == false))
{
ins.InstallStep = InstallStep.Finished;
return RedirectToAction("Login", "User");
}
if (isLocalServer() && ins.InstallStep == InstallStep.SetAdminPassword)
{
return RedirectToAction("SetAdminPassword");
}
return RedirectToAction("SelectPath");
}
У меня одна точка останова установлена в методе Index контроллера установки, другая - в методе Application_Error в Global.asax, и ни одна из них не сработала. Я не совсем уверен, откуда взялся материал "NotFound" - у нас есть этот раздел в нашем web.config:
<customErrors mode="Off" defaultRedirect="~/Error" redirectMode="ResponseRedirect">
<error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
но, как вы можете видеть, у нас отключены пользовательские ошибки, и нет никаких признаков того, что он также запускает ErrorController (у меня есть еще одна точка останова в его методе NotFound, чтобы быть уверенным).
Я попытался настроить альтернативный маршрут, чтобы посмотреть, сможет ли он его перехватить, но хотя отладчик маршрута еще раз показывает, что этот маршрут соответствует 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" }
);
У кого-нибудь есть мысли или предложения?