【问题标题】:Method Not Allowed when calling DELETE method; possible routing issue调用 DELETE 方法时 Method Not Allowed;可能的路由问题
【发布时间】:2018-02-15 17:07:02
【问题描述】:

我有一个与 Web Api 通信的 AngularJS 应用程序。我已经实现了 GET(一个和多个)、DELETE、POST 和 PUT 方法。在我的控制器中,我为每个方法指定了两个属性路由,从那时起,我就很难让某些方法起作用。也就是说,在我的 DELETE 方法中,我总是得到 405 - Method Not Allowed。我很确定这与我选择的路由有关。对于我的 GET 方法,我可以使用两条路线获得预期的结果,所以至少我知道 h

我的 API 方法如下所示:

[HttpDelete]
[ResponseType(typeof(CustomerFee))]
[Route("~/api/CustomerFees/{id:int}")]
[Route("~/api/Customers/{customerID:int?}/Fees/{id:int}")]
public async Task<IHttpActionResult> DeleteCustomerFee(int id, int? feeID = null)
{
   ...
}

在我的 Angular 应用程序中,我创建了一个如下所示的资源:

$resource('http://localhost:62415/api/Customers/:customerID/Fees/:feeID',
{
    customerID: '@customerID',
    feeID: '@feeID'
},
{
    create: { method: 'POST' },
    get: { method: 'GET' },
    query: { method: 'GET', isArray: true },
    remove: { method: 'DELETE' },
    update: { method: 'PUT' }
});

我怀疑这可能与我在资源定义中指定参数的方式有关。我的 Api 方法有两个参数,“id”(feeID)和“customerID”。但是,在我的资源 URL 中,我有 :customerID 和 :feeID。我的问题是这些参数是否需要按名称匹配(在这种情况下,资源中的“feeID”参数与 Api 中的“id”参数不匹配),或者它们是否严格按照它们的位置处理出现在网址中?我在想,由于 API 方法有一个名为“id”而不是“feeID”的参数,所以下面的行不正确。

{ customerID: '@customerID', feeID: '@feeID' }

相反,这两个会更好吗?

{ customerID: '@customerID', feeID: '@id' }

{ customerID: '@customerID', id: '@feeID' }

假设这一点可能不正确,但使用“@”字符似乎表明这是一个占位符,例如发送到存储过程的参数,所以我认为这里基本相同,但我可能是错误的。 AngularJS 文档没有解释这一点;他们的示例始终使用相同的名称,并且没有提及资源将调用的 Api 方法中的参数。

我有一些其他控制器提供这样的路由,如果我做错了可能需要更改这些路由,因为我基本上都遵循相同的模式。当我运行我的 DELETE 请求时,Fiddler 在响应标头中说只允许 GET 操作,很明显 Api 中的路由规范有问题。

这是我的其他操作:

[HttpGet]
[ResponseType(typeof(CustomerFee))]
[Route("~/api/CustomerFees/{id:int}")]
[Route("~/api/Customers/{customerID:int?}/Fees/{id:int}")]
public async Task<IHttpActionResult> GetCustomerFee(int id, int? customerID = null)
{
    ...
}

[HttpGet]
[Route("~/api/CustomerFees")]
[Route("~/api/Customers/{customerID:int?}/Fees")]
public IQueryable<CustomerFee> GetCustomerFees(int? customerID = null)
{
    ...
}

[HttpPost]
[ResponseType(typeof(CustomerFee))]
[Route("~/api/CustomerFees")]
[Route("~/api/Customers/{customerID:int?}/Fees")]
public async Task<IHttpActionResult> PostCustomerFee(CustomerFee customerFee, int? customerID = null)
{
    ...
}

[HttpPut]
[ResponseType(typeof(void))]
[Route("~/api/CustomerFees/{id:int}")]
[Route("~/api/Customers/{customerID:int?}/Fees/{id:int}")]
public async Task<IHttpActionResult> PutCustomerFee(int id, CustomerFee customerFee, int? customerID = null)
{
    ...
}

我的另一个问题是,在我的 API 方法中,“customerID”参数是可选的,第二个路由应该包括“{customerID:int?}”还是“{customerID:int}”?基本上,如果我尝试使用第二条路线但不指定 customerID 值,它将作为 null 出现,所以我想知道哪种表示法是正确的。我担心当“customerID”参数是可选的并且传递了 null 时,它可能会尝试使用路由“/api/Customers/Fees/5”。该特定路线应该是无效的。

【问题讨论】:

    标签: asp.net-web-api2 url-routing angularjs-resource


    【解决方案1】:

    你错过了's'是$resource('http://localhost:62415/api/Customer/:customerID/Fees/:feeID'

    我想应该是 '$resource('http://localhost:62415/api/Customers/:customerID/Fees/:feeID''

    【讨论】:

    • 谢谢@theAnubhav,我在帖子中输入错误,但在我的代码中是正确的。这不是我遇到的问题的原因。我会在我的帖子中修正那个错字。
    【解决方案2】:

    我现在意识到问题出在哪里,尽管在我的问题说明中并不清楚,因为我没有提到它......

    由于 $resource 要求为每个请求指定“customerID”(因为我使用的是预期的路由),所以我得到了 405 - Method not allowed 因为只提供了“feeID”。这导致请求转到“api/Customers/Fee/6”,这是一个无效的路由。所有 DELETE、POST 和 PUT 请求都会发生这种情况。

    【讨论】:

    • 完美的 RCA。
    猜你喜欢
    • 2016-12-10
    • 2021-12-02
    • 2014-04-09
    • 2019-10-08
    • 2018-07-09
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多