Asp.Net Mvc Web Api Routing 404 - asp.net-web-api

I try to something on Web Api. First I will share my WebApiConfig
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = #"^[0-9]+$" }
);
config.Routes.MapHttpRoute(
name: "ApiCategory",
routeTemplate: "api/tales/{category}/{id}",
defaults: new { controller = "Tales", id = RouteParameter.Optional},
constraints: new { category = #"^[a-z]+$" }
);
I read this issue and I fix my apiconfig file. My purpose like this:
List GetAllTales() = api/tales/ -> 404 Not Found
Tale GetTale(int id) = api/tales/1 -> Ok!
List GetAllTalesByCategory(string categoryName) = api/tales/kids -> Ok!
Tale GetTalesByCategoryAndId(string categoryName, int id) = api/tales/kids/1 -> Ok!
İf u wonder my ApiController
[HttpGet]
public Tale GetAllTalesByCategoryAndId(string category, int id){}
[HttpGet]
public IEnumerable<Tale> GetAllTalesByCategory(string category){}
[HttpGet]
public IEnumerable<Tale> GetAllTales(){}
[HttpGet]
public Tale GetTale(int id){}
Thanks for all replies.

You need to switch the route order. Default route will handle the request when you don't specify an id (api/tales) so you need to place your custom route before that.
config.Routes.MapHttpRoute(
name: "ApiCategory",
routeTemplate: "api/tales/{category}/{id}",
defaults: new { controller = "Tales",
id = RouteParameter.Optional,
category = RouteParameter.Optional});
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = #"^[0-9]+$" }
);

Related

How do I set Route attribute in this scenario?

In MVC WEB API using C# and .Net framework 4.5.1 I have a controller name MonitoringController as bellow:
public class MonitoringController : ApiController
{
[HttpGet]
[ActionName("list")]
public IEnumerable<string> List(string collection)
{
return new String[] { "test 1", "test 2" };
}
}
and my routing config is like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.MapHttpAttributeRoutes();
config.EnsureInitialized();
The api works fine on get requests e.g. http://localhost/api/monitoring/list?collection=test
How do I apply Route attribute to make sure it works on http://localhost/api/monitoring/channels/list?collection=test
What I thought I should do was :
[RoutePrefix("api/monitoring")]
public class MonitoringController : ApiController
{
[HttpGet]
[Route("channels")]
[ActionName("list")]
public IEnumerable<string> List(string collection)
{
return new String[] { "test 1", "test 2" };
}
}
I cannot get http://localhost/api/monitoring/channels/list?collection=test working! What have I done wrong?
I want to be able to have the following routes defined in the controller:
/api/monitoring/channels/list
/api/monitoring/windows/list
/api/monitoring/doors/list
Thanks for your help
Try flipping the order in which you register the routes:
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
And also change [Route("channels")] to [Route("channels/list")] and dump the ActionName attribute.
Better still, don't mix the two approaches and go attribute routing throughout.
If you want the collection to be part of the route use a route parameter.
[Route("{collection}/list")]
See http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

something wrong with wep api route

My registered routes mapping looks like this:
config.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
And, controller looks like this:
// [Route("???????????")]
[HttpGet]
public HttpResponseMessage GetPatientProviderData([FromUri] PatientProviderIncomingDto ppDto)
{
var response = Request.CreateResponse(HttpStatusCode.OK, _claimDetailService.GetPatientProviderData(ppDto.patientId, ppDto.facilityGroupId, ppDto.claimId));
return response;
}
I'm making a GET call like this:
http://localhost:xxxx/api/claims/GetPatientProviderData?patientId=180&facilityGroupId=9&claimId=21
But, it's not hitting the URL. I was expecting it to hit the URL and that the supplied parameters get converted into DTO.

WEB API routing actions multiple

May I define a Route for an specific Controller ?
The 3th Route, route to a Controller with somes Actions, but the Route only work fine if is placed before the rest.
Some suggestions , please?
// ex: api/groups/Collective1/john01
config.Routes.MapHttpRoute(
name: ControllerAndCollectiveAndUserID,
routeTemplate: "api/{controller}/{collective}/{userid}",
defaults: null, //defaults: new { id = RouteParameter.Optional }
constraints: new
{
collective = #"^[a-zA-Z\d]+$",
userid = #"^[a-zA-Z\d]+$"
}
);
// ex: api/groups/Collective1
config.Routes.MapHttpRoute(
name: ControllerAndCollective,
routeTemplate: "api/{controller}/{collective}",
defaults: null, //defaults: new { id = RouteParameter.Optional }
constraints: new
{
collective = #"^[a-zA-Z\d]+$"
}
);
// ex: api/users/pending
config.Routes.MapHttpRoute(
name: ControllerAction,
routeTemplate: "api/{controller}/{action}"
);
// ex: api/persons
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: ControllerOnly,
routeTemplate: "api/{controller}"
);

Custom routing for GET/POST/DELETE does not match

What I'm trying to do is to use similar route template in my custom route as the default route template uses, but getting 405 - METHOD NOT ALLOWED.
First one matches the GET request # api/accounts/abc123/contacts but that's about it. Other two don't match, where as the default route # api/{controller}/{id} matches all four verbs.
EDIT: Updated route definitions
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ContactsApi",
routeTemplate: "api/{controller}/{id1}/contacts"
);
config.Routes.MapHttpRoute(
name: "AddressesApi",
routeTemplate: "api/{controller}/{id2}/addresses"
);
config.Routes.MapHttpRoute(
name: "CoverageApi",
routeTemplate: "api/{controller}/{id3}/coverage"
);
config.Routes.MapHttpRoute(
name: "AccountsApi",
routeTemplate: "api/{controller}/{id4}/accounts"
);
I'm trying to map above routes to below actions:
EDIT: Updated with {id1} parameter as per above route definition.
[HttpGet]
public List<Contact> GetContacts(string id)
{
return accounts.GetContacts(id);
}
[HttpPost]
public void PostContacts(string id1, [FromBody]IEnumerable<Contact> contacts)
{
bool success = accounts.AssignContacts(id, contacts);
}
[HttpDelete]
public void DeleteContacts(string id1, [FromBody]IEnumerable<Contact> contacts)
{
bool success = accounts.RemoveContacts(id, contacts);
}
I just want to keep my routes consistent...
You only need to have the one route to match the actions given above:
config.Routes.MapHttpRoute(
name: "ApiContacts",
routeTemplate: "api/{controller}/{id}/contacts"
);
Because your actions start with the relevant http verb, the corresponding action will be called.

how to route this in mvc web api?

I have this requirement to map the url
api/v1/Contact/12/tags
in the above url the Contact is the controller, and 12 is the contactId and tags is the action is want to be called.
The method is like this
[HttpGet]
public List<TagModel> Tags([FromUri]int contactId)
I have did like this
config.Routes.MapHttpRoute(
name: "RouteForHandlingTags",
routeTemplate: "api/v1/{controller}/{id}/{action}",
defaults: new { },
constraints: new { id = #"\d+" }
);
I am getting the error "No HTTP resource was found that matches the request URI http://localhost:4837/api/v1/contact/12/tags"
I have tried
[HttpGet]
public List<TagModel> Tags(int contactId)
and
config.Routes.MapHttpRoute(
name: "RouteForHandlingTags",
routeTemplate: "api/v1/{controller}/{id}/{action}"
);
But all are giving the same error. But when I do a call like this
api/v1/Contact/12/tags?contactid=12
everything works fine. But this is not what I want. The contactId is specified after contact. Can anyone please tell me how to route this?
The parameter names in your action and route must match.
You can either change your action to:
[HttpGet]
public List<TagModel> Tags(int id)
Or change your route to:
config.Routes.MapHttpRoute(
name: "RouteForHandlingTags",
routeTemplate: "api/v1/{controller}/{contactId}/{action}",
defaults: new { },
constraints: new { id = #"\d+" }
);
Note: you do not need [FromUri] with a primitive type like an int.

Resources