Asp.Net 如果 url 参数未定义则重定向到主页的路由
Asp.Net routing which redirects to homepage if url parameter is not defined
我有两条路线
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Home",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
当用户进入主页时,他必须选择两个链接:
<a href="/loc1/Products/index">Location 1</a>
<a href="/loc2/Products/index">Location 2</a>
我还有 ActionFilterAttribute
,我在其中检查 location
参数,如果 url 没有,我将用户重定向到主页。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string location = (string)filterContext.RouteData.Values["location"];
if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" }
});
}
SessionUtils.SetLocationName(location);
}
基于 location
变量,我将从数据库中查询不同的记录,因此当用户未在 url 中提供任何位置并尝试访问 Products/index/5
我希望他们被重定向到主页,他们必须在其中选择位置并单击其中一个链接。
但是我收到错误消息:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Products/index
如果url中没有位置参数,应该如何正确配置路由,以便将用户重定向到主页?
尝试在 Default
路线
之前添加自定义 route
routes.MapRoute(
name: "Location1Route",
url: "{location}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
这将符合您的需要。
您的 "Default" 路线(包括位置)是唯一会被击中的路线。 controller
、action
和 id
参数都是可选的,因此 /Products/Index
之类的请求实际上会被您的 "Default" 路由和 location
参数将被赋予 "Products" 而你的 controller
参数将被赋予 "Index" 作为值。 action
参数将是 "Index" 的默认值,而 id
参数将被忽略。由于您显然没有带有 Index
操作的 IndexController
,因此您会得到 404.
为了区分路由,您需要让您的 "Default" 路由需要某种硬编码前缀,即
routes.MapRoute(
name: "Default",
url: "location/{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
然后,/Products/Index
路线将直达您的 "Home" 路线,并被正确解释为通往 ProductsController.Index
的路线。或者,您可以将路由约束应用于 location
参数,因此它不匹配 everything,即:
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional },
constraints: new { location = @"^(loc1|loc2)$" }
);
然后,除非 URL 的第一部分匹配 loc1
或 loc2
,否则它将落入 "Home" 路由。
您是否考虑过硬编码默认值和故障安全路由?
routes.MapRoute("Home", "", new { controller = "Home", action = "Index" });
/* Normal routing logic here */
routes.MapRoute("FailSafe", "{*url}", new { controller = "Home", action = "Index"}); // !=Last Line=!
结合所有答案,尤其是解释,我得出了这个配置
路线配置:
routes.MapRoute(
name: "DefaultShort",
url: "{location}/",
defaults: new { controller = "Products", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultHome",
url: "{controller}/{action}/",
defaults: new { controller = "Home", action = "LandingPage"}
);
OnActionExecuting
中的一些逻辑
if (string.IsNullOrEmpty(location)
&& cookie != null
&& !string.IsNullOrEmpty(cookie.Values["location"])
&& filterContext.ActionDescriptor.ActionName == "LandingPage"
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName == "Home")
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "location", cookie.Values["location"]},
{ "controller", "Measurements" },
{ "action", "Index" }
}
);
}
else if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "LandingPage" }
}
}
如果只提供位置,那么它将使用第一个路由,该路由将重定向到 Products
控制器。
如果 location
、controller
和 action
三个参数在路由中都匹配,则将使用第二个路由。我没有提供默认的 controller
和 action
。这允许在重定向到 HomeController
.
时使用最后一条路线
第三条路线将有两个参数 - controller
和 action
,这使我可以进入 HomeController
中的默认视图。使用 OnActionExecuting
我将重定向到此默认视图和控制器,如果它未指向 HomeController
和 LandingPage
.
我有两条路线
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Home",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
当用户进入主页时,他必须选择两个链接:
<a href="/loc1/Products/index">Location 1</a>
<a href="/loc2/Products/index">Location 2</a>
我还有 ActionFilterAttribute
,我在其中检查 location
参数,如果 url 没有,我将用户重定向到主页。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string location = (string)filterContext.RouteData.Values["location"];
if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" }
});
}
SessionUtils.SetLocationName(location);
}
基于 location
变量,我将从数据库中查询不同的记录,因此当用户未在 url 中提供任何位置并尝试访问 Products/index/5
我希望他们被重定向到主页,他们必须在其中选择位置并单击其中一个链接。
但是我收到错误消息:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Products/index
如果url中没有位置参数,应该如何正确配置路由,以便将用户重定向到主页?
尝试在 Default
路线
route
routes.MapRoute(
name: "Location1Route",
url: "{location}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
这将符合您的需要。
您的 "Default" 路线(包括位置)是唯一会被击中的路线。 controller
、action
和 id
参数都是可选的,因此 /Products/Index
之类的请求实际上会被您的 "Default" 路由和 location
参数将被赋予 "Products" 而你的 controller
参数将被赋予 "Index" 作为值。 action
参数将是 "Index" 的默认值,而 id
参数将被忽略。由于您显然没有带有 Index
操作的 IndexController
,因此您会得到 404.
为了区分路由,您需要让您的 "Default" 路由需要某种硬编码前缀,即
routes.MapRoute(
name: "Default",
url: "location/{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
然后,/Products/Index
路线将直达您的 "Home" 路线,并被正确解释为通往 ProductsController.Index
的路线。或者,您可以将路由约束应用于 location
参数,因此它不匹配 everything,即:
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional },
constraints: new { location = @"^(loc1|loc2)$" }
);
然后,除非 URL 的第一部分匹配 loc1
或 loc2
,否则它将落入 "Home" 路由。
您是否考虑过硬编码默认值和故障安全路由?
routes.MapRoute("Home", "", new { controller = "Home", action = "Index" });
/* Normal routing logic here */
routes.MapRoute("FailSafe", "{*url}", new { controller = "Home", action = "Index"}); // !=Last Line=!
结合所有答案,尤其是解释,我得出了这个配置
路线配置:
routes.MapRoute(
name: "DefaultShort",
url: "{location}/",
defaults: new { controller = "Products", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultHome",
url: "{controller}/{action}/",
defaults: new { controller = "Home", action = "LandingPage"}
);
OnActionExecuting
if (string.IsNullOrEmpty(location)
&& cookie != null
&& !string.IsNullOrEmpty(cookie.Values["location"])
&& filterContext.ActionDescriptor.ActionName == "LandingPage"
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName == "Home")
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "location", cookie.Values["location"]},
{ "controller", "Measurements" },
{ "action", "Index" }
}
);
}
else if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "LandingPage" }
}
}
如果只提供位置,那么它将使用第一个路由,该路由将重定向到 Products
控制器。
如果 location
、controller
和 action
三个参数在路由中都匹配,则将使用第二个路由。我没有提供默认的 controller
和 action
。这允许在重定向到 HomeController
.
第三条路线将有两个参数 - controller
和 action
,这使我可以进入 HomeController
中的默认视图。使用 OnActionExecuting
我将重定向到此默认视图和控制器,如果它未指向 HomeController
和 LandingPage
.