问题描述
编辑: 我需要重新打开我的问题,因为它不是RegEx问题!问题出在正斜杠上。即使RegEx匹配,我在控制器操作中也无法获得理想的结果。如果路径段包含正斜杠,则ASP.NET Core不会映射路径段。我正在寻找一种中间件,路由选项(无论是否存在)方面的解决方法。
我正在寻找一种解决方案,可以从控制器动作中的调用URL中获取多个路径段,包括通过RegEx约束进行正斜杠。
示例:
用户致电:PUT api/v1/model/elements/elementCollection1/subElement1/subSubElement2/value
现在elements/
和/value
之间的所有内容都应通过类似...的函数传递给名为elementPath
的动作参数。
[HttpPut("api/v1/model/elements/{elementPath}/value")]
public IActionResult PutElementValue(string elementPath,[FromBody] Value value)
{
//Here is code
}
您是否知道如何RegEx并将tge匹配映射到elementPath参数(包括正斜杠)?像这样:
[HttpPut("api/v1/model/elements/{elementPath:regex(<Here shall be the right RegEx>)}/value")]
值得注意的是,我也尝试使用*包罗万象的参数,虽然有点不合常规,但它工作了片刻。问题是我在api / v1 / model / elements / {elementPath}上有另一个Put-Operation,没有附录“ / value”。因此,我不得不正确地获取elementPath。另外,我想从Controller自动生成一个Swagger Doc,并且其中的所有内容和hack都不会被解析。
请帮助我,这是我对StackOverflow的第一个问题。
解决方法
来自docs:
您可以使用星号(*)或双星号(**)作为路由参数的前缀,以绑定到URI的其余部分。这些称为全部参数。例如,blog / {** slug}匹配以/ blog开头且后跟任何值的所有URI,该URI被分配给slug路由值。 Catch-all参数也可以匹配空字符串。
当 route用于生成URL,包括路径分隔符(/) 字符。例如,路由foo / {* path}的路由值为{ path =“ my / path”}生成foo / my%2Fpath。注意向前逃跑 削减。要往返路径分隔符,请使用** route 参数前缀。路径foo / {** path}和{path =“ my / path”} 生成foo / my / path。
按如下所示更改代码:
[HttpPut("api/v1/model/elements/{**value}")]
public void PutElementValue(string value,[FromBody] string data)
{
value = value.Replace("/value","");
}
,
我找到了另一个解决方案,即使用URL编码的元素路径创建并注册自己的中间件。克服了不将正斜杠映射到任何路由模板的问题。
解决方案:
app.Use((context,next) =>
{
string requestPath = context.Request.Path.ToUriComponent();
if (requestPath.Contains("elements/"))
{
Match valueMatch = Regex.Match(requestPath,"(?<=elements/)(.*)(?=/value|/invoke)");
if(valueMatch.Success)
{
string elementPath = HttpUtility.UrlEncode(valueMatch.Value);
requestPath = requestPath.Replace(valueMatch.Value,elementPath);
context.Request.Path = new PathString(requestPath);
}
else
{
Match baseMatch = Regex.Match(requestPath,"(?<=elements/)(.*)");
if(baseMatch.Success)
{
string elementPath = HttpUtility.UrlEncode(baseMatch.Value);
requestPath = requestPath.Replace(baseMatch.Value,elementPath);
context.Request.Path = new PathString(requestPath);
}
}
}
return next();
});
它可以工作,但仍然感觉很平庸。如果您有任何想法如何在其他方法中执行此操作-仍推荐使用Action-Route-Template中的RegEx-请让我知道;-)