我的问题类似于Web Api Routing : Multiple controller types were found that match the URL,但我想将它们保留在单独的控制器中。
从评论中,有2个预先存在的答案是不错的解决方法,但不能解决我要解决的实际问题。
我正在组成的URL与文件系统中的嵌套目录相似,或者与Firebase URL非常相似。
/BiggestSet/{BiggestSetCode}/Subset1/{Subset1Code}/SubsetOfSubset1/{SubsetOfSubset1}
...一直到树停下来的地方。将其视为数据树。
/Collection/{Instance}/Collection/{Instance}
我的问题是,在/ Collection级别,我还想提供特定的集合级别的操作。像添加和搜索以及其他特定于集合的操作集合/过程数据
Collection Controller:
/Collection/Add
/Collection/ProcessDataOnTheColleciton
Instance Controller:
/Collection/{InstanceCode}
/Collection/{InstanceCode}/ProcessOnTheInstance
我遇到的问题是Collection / ProcessData与实例Collection / {InstanceCode}发生冲突
注意:1是一个参数,另一个是常数。
如果您设置控制器,以使集合和实例位于同一控制器中。 / {InstanceCode}与/ ProcessData不冲突
BUT
如果设置为将控制器拆分为逻辑功能,WebAPI将给出错误消息,发现多个与URL匹配的控制器类型。
没有人知道如何修改属性路由以某种方式表现出来,就像它们在同一控制器中一样,还是要在控制器之间优先于参数优先通过常量?
要保留两个单独的控制器并且仍然具有此类路由,可以使用正则表达式路由约束。这样,您可以为instanceCode
指定您接受除来自另一个控制器的动作之外的所有内容。
这里是如何配置路由的样例:
public class CollectionController : ApiController
{
[HttpGet]
[Route("Collection/Add")]
public string Add()
{
return $"CollectionController = Collection/Add";
}
[HttpGet]
[Route("Collection/Process")]
public string Process()
{
return $"CollectionController = Collection/Process";
}
}
public class InstanceController : ApiController
{
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}")]
public string Get(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}";
}
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}/Process")]
public string Process(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}/Process";
}
}
这里也是示例中使用的post that explains the regular expression的链接。
一个更好的选择是,如果您具有instanceCode
的特定格式,并将正则表达式设置为仅接受此特定格式。然后,您无需为添加的每个新操作修改正则表达式。我还包括指向documentation for all available Route constraints的链接。在那里您可以看到所有可用的选项。例如,如果您的实例代码是数字,则您甚至都不需要正则表达式,就可以使用int约束进行限制,例如[Route("Collection/{instanceCode:int}")]
。