#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. Код работает таинственным образом!