c# - 使用 IPageRouteModelConvention 时获取版本
问题描述
前段时间我问如何添加某种本地化的 url,IPageRouteModelConvention
对我来说,这是一种完美的方式。
有了它,我就可以拥有不同语言/名称的路线。
如果我使用www.domain.com/nyheter
(swedish) 或www.domain.com/sistenytt
(norwegian),我仍然只能在 中发现使用RouteData
了该News
路线 ( RouteData.Values["page"]
)。
我如何获得哪个版本?
我知道我可以检查/解析,context.Request.Path
但我想知道是否有一个内置属性可以代替它。
在startup
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddRazorPagesOptions(options =>
{
options.Conventions.Add(new LocalizedPageRouteModelConvention(new LocalizationService(appsettings.Routes)));
});
appsettings.Routes
从appsettings.json
"Routes": [
{
"Page": "/Pages/News.cshtml",
"Versions": [ "nyheter", "sistenytt" ]
},
and so on....
]
班上
public class LocalizedPageRouteModelConvention : IPageRouteModelConvention
{
private ILocalizationService _localizationService;
public LocalizedPageRouteModelConvention(ILocalizationService localizationService)
{
_localizationService = localizationService;
}
public void Apply(PageRouteModel model)
{
var route = _localizationService.LocalRoutes().FirstOrDefault(p => p.Page == model.RelativePath);
if (route != null)
{
foreach (var option in route.Versions)
{
model.Selectors.Add(new SelectorModel()
{
AttributeRouteModel = new AttributeRouteModel
{
Template = option
}
});
}
}
}
}
解决方案
要检索一个RouteData
值,您可以在模板中为路由指定一个标记。例如,路由{version}
会添加一个取自 URL 的第一段的RouteData
值。version
在您的示例中,您没有指定令牌version
,因此正如您所描述的那样,它没有任何RouteData
价值。
针对您的特定问题的解决方案分为两部分:
- 在创建新
SelectorModel
s 时不要使用特定的值,而是使用如上所述的标记。 - 有了这个,您现在可以从 访问一个
version
值RouteData
,但新问题是可以提供任何值,无论它是否在您的配置中指定。
要解决第二个问题,您可以转向IActionConstraint
. 这是一个实现:
public class VersionConstraint : IActionConstraint
{
private readonly IEnumerable<string> allowedValues;
public VersionConstraint(IEnumerable<string> allowedValues)
{
this.allowedValues = allowedValues;
}
public int Order => 0;
public bool Accept(ActionConstraintContext ctx)
{
if (!ctx.RouteContext.RouteData.Values.TryGetValue("version", out var routeVersion))
return false;
return allowedValues.Contains((string)routeVersion);
}
}
VersionConstraint
获取允许值的列表(例如nyheter
, sistenytt
)并检查值是否version
RouteData
匹配。如果不匹配,“动作”(此时它实际上是一个页面)将不匹配,并以 404 结束。
有了该实现,您可以将LocalizedPageRouteModelConvention
's的实现更新Apply
为如下所示:
var route = _localizationService.LocalRoutes().FirstOrDefault(p => p.Page == model.RelativePath);
if (route != null)
{
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Template = "{version}"
},
ActionConstraints =
{
new VersionConstraint(route.Versions)
}
});
}
这个实现添加了一个新SelectorModel
的,它设置了一个Version
RouteData
值,并且被限制为只允许配置中指定的值。
推荐阅读
- asp.net-mvc - 500 - 没有详细信息的内部服务器错误
- java - Spring gradle build jar 找不到带有 NoClassDefFoundError 的主类
- python - Python获取类但排除继承的属性和方法
- python - django 的多个子域
- python-3.x - ValueError:未知损失函数:triplet_loss
- angularjs - 避免对 Angular JS 的 XSS 攻击
- reactjs - redux 状态更改后组件不重新渲染
- coq - Coq:证明 < 和 ≤ 之间的关系
- vue.js - Vue 的“v-model”容易受到 XSS 攻击吗?
- python - 有没有办法可以将这些公式组合到一个单元格中?