【问题标题】:webapi 5.2.3 Multiple controller types were found that match the URL - Attribute Routingwebapi 5.2.3 找到与 URL 匹配的多个控制器类型 - 属性路由
【发布时间】:2016-01-11 12:14:15
【问题描述】:

我遇到了 webapi 属性路由的问题。我正在调用以下路线:assessment/assessments/assessmenttypes 作为HttpPost。我收到多个控制器类型与 url 匹配的错误。问题是它们绝对不匹配。最初,当我第一次遇到这个问题时,我使用了不同的路由前缀,但是我读到 webapi 可以忽略路由前缀,所以我更改了所有路由以使它们唯一,所以“匹配控制器”中唯一的 HttpPosts定义如下:

[Route("assessments"), HttpPost] public async Task<System.Int32> PostCreate([FromBody]Assessment assessment)

[Route("assessments/assessmenttypes"), HttpPost] public async Task<System.Int32> PostCreate([FromBody]AssessmentType assessmentType)

两个控制器的 RoutePrefix 相同:[RoutePrefix("assessment")]

谁能帮忙,这很令人沮丧。

提前致谢!

【问题讨论】:

    标签: c# asp.net-web-api2


    【解决方案1】:

    您首先需要了解的是路由是如何工作的,这是解决您问题的关键。如果您给我更多信息,我可以稍后更新我的答案(目前看来您没有发布所有必需的信息)

    如您所知,路由是将请求与路由匹配的过程。 发挥神奇作用的处理程序是 HttpRoutingDispatcher 并借助一些额外的库,但基本上调度程序会解析请求。处理路由的最终目标是识别两个元素:

    • 路线
    • 价值观

    您有两种不同的方式来解析路由,基于约定(模板)或通过属性。特别是在应用程序增长时,保持一致以避免混淆是一个好主意。 路由有两个不同的部分,固定段(它们必须完全匹配)和变量(用 {} 表示)

    请求动词有两种不同的匹配方式,带有属性 [HttpGet] [HttpPost] [HttpPut] 或者在我看来使用方法的第一部分令人困惑,如果你有 3 个不同的方法没有用属性标记,WebApi 假设第一个字母试图指示动词:

    • GetList --> List的HttpGet
    • GetDetail --> HttpGet 的详细信息
    • PostDetail --> HttpPost 的详细信息

    如果您尝试以下模板,请参阅官方文档:

    routeTemplate: "api/{controller}/{id}"
    

    然后您从 Ajax 发出如下请求:

    $.ajax("/api/today/dayofweek", {
    

    以下控制器将失败(几乎总是)

    公共类 TodayController : ApiController {

    [HttpGet]
    public string DayOfWeek() {
       return DateTime.Now.ToString("dddd");
    }
    
    [HttpGet]
    public int DayNumber() {
       return DateTime.Now.Day;
    }
    

    因为几乎不可能确定哪个是正确的(人类当然可以,但不幸的是机器需要更多的编程来处理模糊逻辑):)

    在您的情况下,问题不是都从相同的固定路线开始,问题是无法确定您是说第二部分属于变量还是固定部分(含糊不清) 举个例子;我们如何确定它的含义?

    • /segmenta/segmentb
    • /segmenta/segmentb/segmentc(c段是固定路线还是参数?)

    从架构的角度来看,我不认为 /assesmenttypes 是 /assesment 的从属资源(基于 Api 设计)。如果您想设计一个 RESTful ROA Api,那么如果类型取决于评估(作为子项,而不是属性),则评估类型被正确地指示为资源。 我建议你也检查一下你的路径。

    【讨论】:

    • 嗨,谢谢。我没有使用路由模板,只使用属性路由,所以我没有设置默认路由routeTemplate: "api/{controller}/{id}"。两个 URL 中都没有参数,这是 webapi 的一个非常糟糕的标准用法。正如您从路线中看到的那样,它们并不相同,这就是我为此苦苦挣扎的原因,因为我有其他路线工作得很好。
    • 即使您不使用路由,我认为主要问题还是路由重叠。当您声明属性时,它们会添加到路由集合中,并且两者都非常相似,因此路由系统在建立正确的属性时存在冲突。
    • 那么您的意思是 webapi 只查看 URL 的第一部分,而不评估完整路径?因此,例如地址:users/books 的 HttpGet 和 users/groups 的一个 HttpGet 的评估结果相同并会导致冲突?
    • 不,webapi 在评估作为另一个子集的路径时存在一些问题。例如,users/books 和 users/books/new。我正在考虑一条适合您的路线。
    • 嗨 Maximiliano,我已将多个控制器合并到 less 中,从而解决了这个问题。我认为 webapi 不评估完整路径是很糟糕的,这看起来很奇怪,感觉就像一个 bug tbh。感谢您的帮助,我会将其标记为已回答。我宁愿不合并几个逻辑上分离的控制器,但我没有时间用这个把我的头撞到墙上:-)
    猜你喜欢
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    相关资源
    最近更新 更多