【发布时间】:2018-07-10 12:36:29
【问题描述】:
所以,我有一个使用默认路由模板 {controller}/{action}/{id} 的 MVC5 站点,它工作正常。站点中的大多数内容都需要登录(即几乎所有地方都使用 [Authorize] 属性),这很好用。
好吧,现在我需要在使用某种链接模式时允许匿名访问选择页面:App/{token}/{action}。 {token} 是一个随机字符串,与我的数据库中的某些内容相关联。我可以随意发行和停用这些令牌。
我通过实现自定义 RouteBase 来解析这些令牌的传入 URL,并且至关重要的是,将令牌值添加到 RouteData.DataTokens 中,从而使这个新的 App/{token}/{action} 路由工作我的App 控制器可以使用它而无需明确的操作参数。因此,我将这条新路由添加到默认路由的 ahead 路由表中,如下所示:
// new route here
routes.Add("AppToken", new AnonAppAccessRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
这是问题/问题:添加此 now 路由现在使我的默认路由停止工作 - 现在一切都通过 AnonAppAccessRoute 进行,这当然只适用于少数几件事。我不明白如何让我的AnonAppAccessRoute 仅适用于具有特定模式的 URL。 MapRoute 方法接受 URL 模式,但 Add 路由似乎不允许您对其进行过滤。我错过了什么?我已经浏览了很多关于路由的博客和文档,但是我没有找到关于使用 DataTokens 集合的好信息(我觉得这对我的方法很重要),而且我没有看到很好的解释Add显式路由与调用MapRoute之间的区别。
这是我自定义RouteBase的代码:
public class AnonAppAccessRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
string[] pathElements = httpContext.Request.Path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if (pathElements.Length > 0)
{
string token = TryGetArrayElement(pathElements, 1);
if (!string.IsNullOrEmpty(token))
{
result = new RouteData(this, new MvcRouteHandler());
result.DataTokens.Add("appToken", token);
result.Values.Add("controller", "App");
result.Values.Add("action", TryGetArrayElement(pathElements, 2, "Index"));
}
}
return result;
}
private string TryGetArrayElement(string[] array, int index, string defaultValue = null)
{
try
{
return array[index];
}
catch
{
return defaultValue;
}
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
【问题讨论】:
标签: asp.net-mvc-5