URL 包含特定查询参数时如何绕过所有其他 MVC 路由?
How to bypass all other MVC routes when a URL contains a specific query parameter?
我需要捕获任何包含 URLToken 查询参数的请求,例如 URL:
http://test.server.com/product?URLToken=4abc4567ed...
并将其重定向到特定的控制器和操作。
我已经尝试设置各种具有约束的路线,包括下面显示的路线。
app.UseMvc(routes =>
{
routes.MapRoute(
name: "ssocapture",
template: "{*stuff}",
defaults: new { controller = "Account", action = "SingleSignOn" },
constraints: new { stuff= @"URLToken=" } );
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/{id?}");
});
SingleSignOn 开头的断点永远不会通过此规则命中(以下直接 link 操作确实命中了断点,所以我知道控制器和操作正在工作)。
http://test.server.com/account/singlesignon?URLToken=4abc4567ed...
我错过了什么/做错了什么?
路线不是为了做到这一点而设计的。要实现您的目标,只需在 UseMVC()
之前添加一个中间件
app.Use((ctx , next)=>{
var token = ctx.Request.Query["URLToken"].FirstOrDefault();
if(token!=null){
ctx.Response.Redirect($"somecontroller/specificaction/{token}"); // redirect as you like
// might be :
// ctx.Response.Redirect($"Account/SingleSignOn/{token}");
}
return next();
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
如果您不想使用中间件,我认为在您的控制器中很容易做到。您将获得的另一个好处是您可以为所有其他路由设置 RouteName 并使用 RedirectToRoute
方法简单地重定向到该路由。因此,在您的 UrlToken 操作中:
[Route("[action]"]
public IActionResult SingleSignOn(string urlToken)
{
If (!string.IsNullOrWhitespace(urlToken))
{
return RedirectToRoute("RouteName"):
}
}
要使上述工作正常,您必须通过使用 AttributeRouting 或在启动时全局定义来为其他操作指定 RouteName:
[Route("[action]", Name = "otherroute")]
public IActionResult OtherAction(string param1, string param 2)
{
//...
}
所以只需将 SingleSignOn
操作中的 "RouteName" 替换为 "otherroute" 即可。如果您需要将路由参数传递给 "otherroute",您可以使用 RedirectToRoute
方法的重载之一。希望对您有所帮助。
我需要捕获任何包含 URLToken 查询参数的请求,例如 URL:
http://test.server.com/product?URLToken=4abc4567ed...
并将其重定向到特定的控制器和操作。
我已经尝试设置各种具有约束的路线,包括下面显示的路线。
app.UseMvc(routes =>
{
routes.MapRoute(
name: "ssocapture",
template: "{*stuff}",
defaults: new { controller = "Account", action = "SingleSignOn" },
constraints: new { stuff= @"URLToken=" } );
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/{id?}");
});
SingleSignOn 开头的断点永远不会通过此规则命中(以下直接 link 操作确实命中了断点,所以我知道控制器和操作正在工作)。
http://test.server.com/account/singlesignon?URLToken=4abc4567ed...
我错过了什么/做错了什么?
路线不是为了做到这一点而设计的。要实现您的目标,只需在 UseMVC()
app.Use((ctx , next)=>{
var token = ctx.Request.Query["URLToken"].FirstOrDefault();
if(token!=null){
ctx.Response.Redirect($"somecontroller/specificaction/{token}"); // redirect as you like
// might be :
// ctx.Response.Redirect($"Account/SingleSignOn/{token}");
}
return next();
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
如果您不想使用中间件,我认为在您的控制器中很容易做到。您将获得的另一个好处是您可以为所有其他路由设置 RouteName 并使用 RedirectToRoute
方法简单地重定向到该路由。因此,在您的 UrlToken 操作中:
[Route("[action]"]
public IActionResult SingleSignOn(string urlToken)
{
If (!string.IsNullOrWhitespace(urlToken))
{
return RedirectToRoute("RouteName"):
}
}
要使上述工作正常,您必须通过使用 AttributeRouting 或在启动时全局定义来为其他操作指定 RouteName:
[Route("[action]", Name = "otherroute")]
public IActionResult OtherAction(string param1, string param 2)
{
//...
}
所以只需将 SingleSignOn
操作中的 "RouteName" 替换为 "otherroute" 即可。如果您需要将路由参数传递给 "otherroute",您可以使用 RedirectToRoute
方法的重载之一。希望对您有所帮助。