C# 使用花括号时,管线变换不起作用
我有以下代码C# 使用花括号时,管线变换不起作用,c#,asp.net-core-mvc,.net-5,C#,Asp.net Core Mvc,.net 5,我有以下代码 Startup.cs public void配置服务(IServiceCollection服务) { services.AddMvc(选项=> { options.Conventions.Add(新的RouteTokenTransformerConvention(新的SlugifyParameterTransformer()); }); } 其中slagifyParameterTransformer实现IOutboundParameterTransformer并将URL转换为SE
Startup.cs
public void配置服务(IServiceCollection服务)
{
services.AddMvc(选项=>
{
options.Conventions.Add(新的RouteTokenTransformerConvention(新的SlugifyParameterTransformer());
});
}
其中slagifyParameterTransformer
实现IOutboundParameterTransformer
并将URL转换为SEO友好的URL
在我的家庭控制器中
,我有这些
public IActionResult Index()
{
返回视图();
}
[路由(“{controller}/{action}”)]//路由转换仅在使用方括号时有效。
公共IActionResult SomeTestPage()
{
返回视图();
}
在我的Index.cshtml
中,我有这些
@addTagHelper*,Microsoft.AspNetCore.Mvc.TagHelpers
一些测试页面
在构建和运行网站时,SomeTestPage
的URL是localhost\Home\SomeTestPage
,而不是通过slagifyParameterTransformer
转换。但是,在我将RouteAttribute
装饰SomeTestPage
操作方法中的花括号替换为方括号后,URL被正确地转换为localhost\home\SomeTestPage
使用属性路由定义路由模板时,花括号和方括号之间有什么区别
使用属性路由定义路由模板时,花括号和方括号之间有什么区别
在中,我们可以发现它通常使用带有方括号的[controller]
、[action]
、[area]
作为控制器名称、操作名称和区域名称,并使用{id}
等作为属性路由中的其他通用路由参数
此外,正如中提到的@serpent5,当与属性路由一起使用时,IOutboundParameterTransformer
似乎只处理[
和]
使用提供的值和路由令牌转换器替换模板中的令牌
//
///使用提供的值和路由令牌转换器替换模板中的令牌。
///
///模板。
///要使用的标记值。
///路由令牌转换器。
///包含替换值的新字符串。
公共静态字符串替换令牌(字符串模板、IDictionary值、IOOutboundParameterTransformer routeTokenTransformer)
{
var builder=新的StringBuilder();
var state=TemplateParserState.Plaintext;
int?tokenStart=null;
var范围=0;
//我们将使用'null'额外运行一次循环,以检测字符串的结尾。
对于(var i=0;i您的项目的.NET Core版本是哪个?@FeiHan我使用ASP.NET Core 5.0感谢您将问题提交给github。我碰巧使用了花括号作为路由模板,因为我在属性路由之前在学习路径上偶然发现了传统路由。传统路由似乎不支持方括号,所以我坚持使用c我想知道ASP.NET核心团队是否可以使其更加一致?Hi@NoctisTong,我们可以发现Rick确实帮助我报告的github问题添加了文档增强
标记,我们可以跟踪问题并检查文档团队是否会帮助更新文档。Hi@NoctisTong,关于此官方文档中的“路由模板[controller]、[action]、[area]中的令牌替换”已更新:为方便起见,属性路由通过将令牌括在方括号中来支持令牌替换([
,]
)。
/// <summary>
/// Replaces the tokens in the template with the provided values and route token transformer.
/// </summary>
/// <param name="template">The template.</param>
/// <param name="values">The token values to use.</param>
/// <param name="routeTokenTransformer">The route token transformer.</param>
/// <returns>A new string with the replaced values.</returns>
public static string ReplaceTokens(string template, IDictionary<string, string> values, IOutboundParameterTransformer routeTokenTransformer)
{
var builder = new StringBuilder();
var state = TemplateParserState.Plaintext;
int? tokenStart = null;
var scope = 0;
// We'll run the loop one extra time with 'null' to detect the end of the string.
for (var i = 0; i <= template.Length; i++)
{
var c = i < template.Length ? (char?)template[i] : null;
switch (state)
{
case TemplateParserState.Plaintext:
if (c == '[')
{
scope++;
state = TemplateParserState.SeenLeft;
break;
}
else if (c == ']')
{
state = TemplateParserState.SeenRight;
break;
}
else if (c == null)
{
// We're at the end of the string, nothing left to do.
break;
}
else
{
builder.Append(c);
break;
}
case TemplateParserState.SeenLeft:
if (c == '[')
{
// This is an escaped left-bracket
builder.Append(c);
state = TemplateParserState.Plaintext;
break;
}
else if (c == ']')
{
// This is zero-width parameter - not allowed.
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_EmptyTokenNotAllowed);
throw new InvalidOperationException(message);
}
else if (c == null)
{
// This is a left-bracket at the end of the string.
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_UnclosedToken);
throw new InvalidOperationException(message);
}
else
{
tokenStart = i;
state = TemplateParserState.InsideToken;
break;
}
case TemplateParserState.SeenRight:
if (c == ']')
{
// This is an escaped right-bracket
builder.Append(c);
state = TemplateParserState.Plaintext;
break;
}
else if (c == null)
{
// This is an imbalanced right-bracket at the end of the string.
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_ImbalancedSquareBrackets);
throw new InvalidOperationException(message);
}
else
{
// This is an imbalanced right-bracket.
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_ImbalancedSquareBrackets);
throw new InvalidOperationException(message);
}
case TemplateParserState.InsideToken:
if (c == '[')
{
state = TemplateParserState.InsideToken | TemplateParserState.SeenLeft;
break;
}
else if (c == ']')
{
--scope;
state = TemplateParserState.InsideToken | TemplateParserState.SeenRight;
break;
}
else if (c == null)
{
// This is an unclosed replacement token
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_UnclosedToken);
throw new InvalidOperationException(message);
}
else
{
// This is a just part of the parameter
break;
}
case TemplateParserState.InsideToken | TemplateParserState.SeenLeft:
if (c == '[')
{
// This is an escaped left-bracket
state = TemplateParserState.InsideToken;
break;
}
else
{
// Unescaped left-bracket is not allowed inside a token.
var message = Resources.FormatAttributeRoute_TokenReplacement_InvalidSyntax(
template,
Resources.AttributeRoute_TokenReplacement_UnescapedBraceInToken);
throw new InvalidOperationException(message);
}
case TemplateParserState.InsideToken | TemplateParserState.SeenRight:
if (c == ']' && scope == 0)
{
// This is an escaped right-bracket
state = TemplateParserState.InsideToken;
break;
}
else
{
// This is the end of a replacement token.
var token = template
.Substring(tokenStart.Value, i - tokenStart.Value - 1)
.Replace("[[", "[")
.Replace("]]", "]");
if (!values.TryGetValue(token, out var value))
{
// Value not found
var message = Resources.FormatAttributeRoute_TokenReplacement_ReplacementValueNotFound(
template,
token,
string.Join(", ", values.Keys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase)));
throw new InvalidOperationException(message);
}
if (routeTokenTransformer != null)
{
value = routeTokenTransformer.TransformOutbound(value);
}
builder.Append(value);
if (c == '[')
{
state = TemplateParserState.SeenLeft;
}
else if (c == ']')
{
state = TemplateParserState.SeenRight;
}
else if (c == null)
{
state = TemplateParserState.Plaintext;
}
else
{
builder.Append(c);
state = TemplateParserState.Plaintext;
}
scope = 0;
tokenStart = null;
break;
}
}
}
return builder.ToString();
}