Метод не разрешен при вызове метода DELETE; возможная проблема маршрутизации
У меня есть приложение AngularJS, которое взаимодействует с веб-API. Я реализовал методы GET (один и многие), DELETE, POST и PUT. В моем контроллере я указал два атрибутных маршрута для каждого метода, и с тех пор мне было трудно заставить некоторые методы работать. А именно, в моем методе DELETE я всегда получаю 405 - метод не разрешен. Я почти уверен, что это как-то связано с маршрутизацией, которую я выбрал. Я могу получить ожидаемые результаты, используя оба маршрута для обоих моих методов GET, так что, по крайней мере, я знаю
Мой метод 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" в ресурсе не совпадает с аргументом "id" в Api), или они строго обрабатываются позицией, которую они появиться в URL? Я думаю, что, поскольку метод 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, оно будет иметь нулевое значение, поэтому мне интересно, какая нотация правильная. Я обеспокоен тем, что он может попытаться использовать маршрут "/api/Customers/Fees/5", когда аргумент "customerID" является необязательным и передается значение NULL. Этот конкретный маршрут должен быть недействительным.
2 ответа
Теперь я понял, в чем проблема, хотя это не будет понятно в моей спецификации проблемы, потому что я не упомянул об этом...
Поскольку $resource требует, чтобы "customerID" указывался для каждого запроса (так как я использую ожидающий его маршрут), я получил метод 405 - недопустимый, потому что был предоставлен только "feeID". Это вызвало запрос перейти к "api/Customers/Fee/6", который является недопустимым маршрутом. Это происходило для всех запросов DELETE, POST и PUT.
Вы пропустили "s" $resource('http://localhost:62415/api/Customer/:customerID/Fees/:feeID'
Я предполагаю, что это должно быть '$ resource (' http://localhost:62415/api/Customers/:customerID/Fees/:feeID''