How do I call a method in ApiController with an HTTP request?
I have an ApiController named Service
. I have a method named UpdatePrice
. Now I want to send an http request from another project to it, getting a 404 error code. And if I run it in a browser, I see this:
<Error>
<Message>No HTTP resource was found that matches the request URI 'http://localhost:26769/api/service/updateprice?priceId=16&cost=1234&lastUpdate=2014-10-15 11:41:54.000'.</Message>
<MessageDetail>No type was found that matches the controller named 'service'.</MessageDetail>
</Error>
This is the ApiController:
public class Service : ApiController
{
PriceApplication priceApp = new PriceApplication();
public int UpdatePrice(int priceId,int cost,DateTime lastUpdate)
{
try
{
var price = priceApp.GetByPriceId(priceId);
price.Cost = Convert.ToDecimal(cost);
price.LastUpdate = lastUpdate;
priceApp.Update(price);
return cost;
}
catch
{
return -1;
}
}
}
This is the route for him:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { controller = "service",action="updateprice", id = RouteParameter.Optional}
);
And this is the request:
string serviceUrl = string.Format("http://localhost:26769/api/service/updateprice?priceId={0}&cost={1}&lastUpdate={2}", priceId, cost, DateTime.Now);
WebRequest request = WebRequest.Create(serviceUrl);
WebResponse response = request.GetResponse();
source to share
So you have the wrong controller name (it must end with * Controller) and the wrong routes. Try renaming your controller to ServiceController
and update your routes like this:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{priceId}/{cost}/{lastUpdate}",
defaults: new { controller = "service", action="updateprice", priceId = RouteParameter.Optional, cost = RouteParameter.Optional, lastUpdate = RouteParameter.Optional}
);
And format your url like this:
string serviceUrl = string.Format("http://localhost:26769/api/service/updateprice/{0}/{1}/{2}", priceId, cost, DateTime.Now);
WebRequest request = WebRequest.Create(serviceUrl);
WebResponse response = request.GetResponse();
And add the attribute [HttpGet]
to the action UpdatePrice
:
public class Service : ApiController
{
PriceApplication priceApp = new PriceApplication();
[HttpGet]
public int UpdatePrice(int priceId,int cost,DateTime lastUpdate)
{
try
{
var price = priceApp.GetByPriceId(priceId);
price.Cost = Convert.ToDecimal(cost);
price.LastUpdate = lastUpdate;
priceApp.Update(price);
return cost;
}
catch
{
return -1;
}
}
}
source to share
-
Like others have suggested, the name for all of your controllers must end with
Controller
. This is the default convention in MVC and WebAPI. If you want to change it for WebAPI, you need to write a custom oneIHttpControllerTypeResolver
. -
You only need to have a detailed route if you want your url parameters to look good. If not,
api/{controller}/{action}/{id}
with the id option is optional. Any additional parameters you send will just end up in the query string. -
Use
HttpUtility.UrlEncode(param)
for each parameter before generating the url if you are sending objects along a route or query string. If you send them via the request body (POST
orPUT
), you can send them as they are.
source to share