Web Api路由:找到多个与参数VS恒定路径的URL相匹配的控制器类型

问题描述 投票:-1回答:1

我的问题类似于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匹配的控制器类型。

没有人知道如何修改属性路由以某种方式表现出来,就像它们在同一控制器中一样,还是要在控制器之间优先于参数优先通过常量?

asp.net-web-api asp.net-web-api-routing attributerouting
1个回答
0
投票

要保留两个单独的控制器并且仍然具有此类路由,可以使用正则表达式路由约束。这样,您可以为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}")]

© www.soinside.com 2019 - 2024. All rights reserved.