I have two Web Api POST calls in my project.But the problem is that api's working one at a time.So i need to comment one web api method to work anotherone.
Web Api Methods
//POST: api/ParamApi
[HttpPost]
public IHttpActionResult FirstStatus(fStatus stu)
{
// Some codes here
}
[HttpPost]
public IHttpActionResult IdReceiver(Info inf)
{
// some codes here
}
WebApi.Config
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{param1}/{param2}/{param3}/{param4}",
defaults: new { param1 = RouteParameter.Optional, param2 = RouteParameter.Optional, param3 = RouteParameter.Optional, param4 = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional }
);
no need of commenting one Http post in webApi. webApi supports any number of http post.use this route instead of using the above two config method you will write
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
Related
I have an base controller which perform few post and get on offers, below i gave an sample structure of get
[AxAuthorization(Resource = "Offers")]
[RoutePrefix("api/offer/v2/offers")]
public class OffersV2Controller : ApiController
{
[HttpGet]
[Route("{id}", Name = "OffersGetById")]
public async Task<HttpResponseMessage> GetById([FromUri(Name = "id")]string OfferId)
{
----
-----
}
}
we are calling this get method by api/offer/v2/offers/id , but some other consumer who are using our services, they like to call as api/v2/offers/id, is there any way we can override it ? the above code is kind of code generated by product which we does't want to modify the route prefix.
[Route("api/v2/offer/test")]
[Route("api/offer/v2/test")]
OR
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "route1",
routeTemplate: "test/v2/Values",
defaults: new { controller = "Values", action = "Get" });
config.Routes.MapHttpRoute(
name: "route2",
routeTemplate: "v2/test/Values",
defaults: new { controller = "Values", action = "Get" });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
in the webapiConfig.cs
I'm using Web API 2, I want to route using parameters such as (name & id).
When I try this :
config.Routes.MapHttpRoute(
name: "IDApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "NameApi",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: new { name = RouteParameter.Optional }
);
I got the route 'api/customer/getByID/5' worked fine.
But the route 'api/customer/searchByName/fawzy' didn't work.
And if I set the NameAPI route before the IDAPI route the result is the opposite.
Any ideas ?
You can use Attribute [Route("api/customer/searchByName/{name}")] from namespace System.Web.Http.Routing for searchByName action.
I solved this problem by a combination of Pattern & Route Attribute
In the WebAPIConfig file :
config.Routes.MapHttpRoute(
name: "IDApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: null,
constraints: new { id = #"^[0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}",
defaults: null
);
In the Controller :
[HttpGet]
[Route("api/customer/search/{name}")]
public IHttpActionResult Search(string name)
{
}
[HttpGet]
public IHttpActionResult Get(int id)
{
}
I have default webapi routing configuration:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
);
I want to support following scenarios:
//api/mycontroller
public IQueryable<MyDTO> Get();
//api/mycontroller/{id} where id can be anything except "customaction1" and "customaction2"
public HttpResponseMessage Get(string id);
//api/mycontroller/customaction
[HttpPost]
public void CustomAction1([FromBody] string data);
[HttpPost]
public void CustomAction2([FromBody] string data);
I have tried to apply [Route("api/mycontroller/customaction1")] to the CustomAction1 method, and similar to CustomAction2 but getting:
Multiple actions were found that match the request:
CustomAction1 on type MyProject.WebApiService.MyController
CustomAction2 on type MyProject.WebApiService.MyController
Make sure that you configured attribute routing along with your default configuration
//....
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
);
//....
If you want to do the same with out attribute routing then you will need to configure routes explicitly
//This one constrains id to be an int
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action="Get", id = RouteParameter.Optional },
constraints : new { id = #"\d" }
);
//This one should catch the routes with actions included
config.Routes.MapHttpRoute(
name: "ActionRoutes",
routeTemplate: "api/{controller}/{action}"
);
I have a controller with the following actions defined:
public IHttpActionResult Get(int id) {}
[ActionName("Orders")]
public IHttpActionResult GetOrders(int id) {}
And my routing is as follows:
config.Routes.MapHttpRoute(
name: "ControllerWithId",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = #"^[0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "ControllerWithAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "Get" },
constraints: null
);
config.Routes.MapHttpRoute(
name: "ControllerWithIdAndAction",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = #"^[0-9]+$"
};
I would like to call the GetOrders as follows:
/api/Customers/1/Orders
However, I get the exception:
Multiple actions were found that match the request: Get
What is the correct routing in this case?
That's because both of your actions are being matched with the first route template ControllerWithId! This basically has happened because you mixed verb-based routing (which is default routing mechanism in Web-Api) and action based routing. You should stick to one of them! Based on your controller and actions you can combine the first and second route templates like this:
config.Routes.MapHttpRoute(
name: "ControllerWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Get" },
constraints: null);
This will cover your scenario but if you want to address more complicated scenarios take a look at Web API: Mixing Traditional & Verb-Based Routing
Try using the 'Route' decorator rather than the 'ActionName' decorator.
[Route("{id:int}/orders")]
I am trying to make hierarchical link in my RESTapi. For example:
Following url will give me details of actor id 1:
/api/v1/actor/id/1/
Following url is expected to give me all movies of actor id 1:
/api/v1/actor/1/movies
My routes:
config.Routes.MapHttpRoute(
name: "DefaultCAApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultOneLevelNested",
routeTemplate: "api/v1/{controller}/{levelOneId}/{action}",
defaults: new { id = RouteParameter.Optional }
);
My Actions in ActorController:
[HttpGet]
public HttpResponseMessage Id(int id)
{
// logic
return Request.CreateResponse(HttpStatusCode.OK, actor);
}
[HttpGet]
public HttpResponseMessage Movies(int levelOneId)
{
// logic
return Request.CreateResponse(HttpStatusCode.OK, movies);
}
But this setup is not working for me.
/api/v1/actor/id/1/ gives me proper response
But /api/v1/actor/1/movies is throwing following error:
No action was found on the controller 'Actor' that matches the name '1'."
I did follow this thread, but it did not work for me.
Can some please suggest what wrong I am doing here? I am using MVC 4, WebAPI.
Try switching the order of your routes:
config.Routes.MapHttpRoute(
name: "DefaultOneLevelNested",
routeTemplate: "api/v1/{controller}/{levelOneId}/{action}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultCAApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Order matters when creating routes. The way you have it, it's matching the first one (the default route) first, and not finding an action with the name of "1".
You might also want to look into MVC Attribute routing, I think it's a tad easier to work with: http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
This work around did thing for me:
config.Routes.MapHttpRoute(
name: "DefaultCAApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "LevelOneNested",
routeTemplate: "api/v1/{controller}/{id}/details/{action}",
defaults: new { id = RouteParameter.Optional }
);
Basically I have added 1 more path level to my url. It finally became:
/api/v1/actor/4/details/movies
Use these routes:
config.Routes.MapHttpRoute(
name: "DefaultOneLevelNested",
routeTemplate: "api/v1/{controller}/{id}/{action}",
constraints: new { controller = "actor", action ="movies" }
);
config.Routes.MapHttpRoute(
name: "DefaultCAApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
They should match your initial urls.