I have an AngularJS application that communicates with a Web Api. I've implemented the GET (one and many), DELETE, POST, and PUT methods. In my controller I have specified two attribute routes for each method and ever since then, I've had difficulty getting some of the methods to work. Namely, in my DELETE method, I always get 405 - Method Not Allowed. I am pretty certain that this has something to do with the routing I've chosen. I can get the expected results using both routes for both my GET methods so at least I know h
My API method looks like this:
[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)
{
...
}
In my Angular app, I've created a resource which looks like this:
$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' }
});
I suspect this might have something to do with how I've specified the arguments in my resource definition. My Api method has two arguments, "id" (the feeID) and "customerID". However, in my resource URL I have :customerID and :feeID. My question is whether these arguments need to match up by name (which in this case the "feeID" argument in the resource doesn't match up with the "id" argument in the Api), or are they strictly processed by the position they appear in the URL? I am thinking that since the API method has an argument named "id" instead of "feeID" the line below isn't correct.
{ customerID: '@customerID', feeID: '@feeID' }
Instead, would either of these be better?
{ customerID: '@customerID', feeID: '@id' }
or
{ customerID: '@customerID', id: '@feeID' }
It may be incorrect to assume this, but the use of the "@" character seems to indicate that this is a placeholder such as parameters sent into a stored procedure so I would think that's basically the same here, but I could be wrong. The AngularJS documentation doesn't explain this; their examples always use the same name and make no mention of the arguments in the Api method the resource will be calling.
I have a few other controllers that provide routes like this and may need to change those if I'm doing this wrong because I've basically followed the same pattern for each. When I run my DELETE request, Fiddler says in the response headers that only GET operations are allowed so clearly something is wrong with the route specifications in the Api.
Here are the my other operations:
[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)
{
...
}
Another question I have is that in my API method the "customerID" argument is optional, should the second route include "{customerID:int?}" or "{customerID:int}"? Basically, if I try want to use the second route but don't specify a customerID value it will come in as null so I am wondering which notation is correct. I'm concerned that it might attempt to use the route "/api/Customers/Fees/5" when the "customerID" argument is optional and null is passed. That particular route should be invalid.
You have missed 's' is
$resource('http://localhost:62415/api/Customer/:customerID/Fees/:feeID'I guess it should be '$resource('http://localhost:62415/api/Customers/:customerID/Fees/:feeID''