Web API routing issue - c#

I have a VideoController and inside of it there are 2 methods like the following:
[Route("api/Video/{id:int}")]
public Video GetVideoByID(int id){ do something}
[Route("api/Video/{id}")]
public Video GetVideoByTitle(string id) {do something}
The WebApiConfig.cs is like the following:
public const string DEFAULT_ROUTE_NAME = "MyDefaultRoute";
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: DEFAULT_ROUTE_NAME,
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
So, when I comment out any of the method, the other one works, like if you totally comment out the 1st one, the 2nd method works, but both doesn't work when implemented. I used an Empty Web API template.
So any thoughts regarding why this is happening would be great.

You have to enable the attribute routing calling MapHttpAttributeRoutes during configuration.
Example:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
...
}
I've tested it and worked for me correctly:
http://localhostapi/Video/1 // goes for the first method
http://localhostapi/Video/foo // goes for the second method

Change your routeTemplate from
routeTemplate: "api/{controller}/{id}",
to
routeTemplate: "api/{controller}/{action}/{id}",
So you'd call something like api/Video/GetVideoByTitle/x or api/Video/GetVideoByID/x
You may want to read this, under Routing Variations > Routing by Action Name

Related

How to structure Web API code such that the link will support api/values/{id}/name

I am new to learning Web API code in C# and was wondering how to create the following link that gets the name for a specific value ID.
The provided code below does not work as I want it to with the "/name" behind it.
// GET api/values/{id}/name
public string Get(int id)
{
return getNameValue(id);
}
You can use custom route like:
[Route("{id:int}/name")]
public string Get(int id)
{
return getNameValue(id);
}
Update:
In WebApiConfig, modify register method to have custom routes
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id:int}/name",
defaults: new { id = RouteParameter.Optional }
);
You can directly use attribute routing without defining the route in route config.
Add the below code which enable attribute routing(This feature is only applicable to Web API 2).
Attribute routing Web API 2
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes(); //**enabling attribute routing here.**
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
then you can make use of:
[Route("{id:int}/name")]
public string Get(int id)
{
return getNameValue(id);
}

Routes and the dreaded 405

I've got a simple web API that registers on one route. At the moment I've got two because only one of them does what I need.
My application only has one controller and one Post method in that Controller. I've registered a single Route which always returns a 405 (method not allowed)
The two routes are configured in the RouteConfig.cs:
routes.MapHttpRoute(
name: "app-events",
routeTemplate: "events",
defaults: new { controller = "Events" },
handler: new GZipToJsonHandler(GlobalConfiguration.Configuration),
constraints: null
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
The Controller method is essentially this...
public class EventsController : ApiController
{
public EventsController()
{
_sender = new EventHubSender();
}
public async Task<HttpResponseMessage> Post(HttpRequestMessage requestMessage)
{
// doing fun stuff here…
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
If I only configure the first route and post a request to http://devbox/events I will get a 405. However, if I add the second, default, route, and post to http://devbox/api/events I get back my expected 201.
With both routes configured at the same time, the same pattern, the route explicitly bound to the Controller receives a post request and fails with a 405, but the other URL will work.
I've spent a long time looking around before conceding to ask the question. Most things I read have a lot to do with Webdav and I think I've followed every one of them to fix the issue. I am not very experienced with this stack, so nothing is very obvious to me.
You mentioned RouteConfig File. This is used for configuring the MVC routes not Web API routes.
So it would appear you are configuring the wrong file which would explain why the api/... path works as it is probably mapping to the default configuration in WebApiConfig.Register, which would look like
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
You would need to update that file with the other desired route
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "app-events",
routeTemplate: "events",
defaults: new { controller = "Events" },
handler: new GZipToJsonHandler(GlobalConfiguration.Configuration),
constraints: null
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Web API routes are usually registered before MVC routes which explains why it was not working with your original configuration.
You should also adorn the action with the respective Http{Verb} attribute.
In this case HttpPost so that the route table knows how to handle POST requests that match the route template.
[HttpPost]
public async Task<IHttpActionResult> Post() {
var requestMessage = this.Request;
// async doing fun stuff here….
return OK();
}

Api Controller Method not calls

I have MVC project, I have added one API controller.in this API controller I have created methods in it.but when I am trying to call this API from postman or localhost with "http://localhost:10133/api/BedfordBrownstoneApi/GetAgentId?username=dgsdgsdgsd&password=sdgsdgs" Url its gives following response.
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:10133/api/BedfordBrownstoneApi/GetAgentId?username=dgsdgsdgsd&password=sdgsdgs'.",
"MessageDetail": "No type was found that matches the controller named 'BedfordBrownstoneApi'."
}
My API controller is like following.
public class BedfordBrownstoneApi : ApiController
{
// GET api/<controller>
public int GetAgentId(string username,string password)
{
DataContext db = new DataContext();
var data = db.Set<AgentLogin>().Where(a => a.UserName==username && a.Password==password).SingleOrDefault();
return data.AgentId;
}
}
}
My WebApiConfig class is like following.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "GetAgentId" }
);
}
}
Check Below Question that that similar problem as yours.
Check Accepted Answer of 'Benoit74B'. It clearly explains problem in details. Actual problem is regarding parameters you are passing -
"No HTTP resource was found that matches the request URI" here?
Remove "API" from controller name BedfordBrownstoneApi.
Change it from
http://localhost:10133/api/BedfordBrownstoneApi/GetAgentId?username=dgsdgsdgsd&password=sdgsdgs
to
http://localhost:10133/api/BedfordBrownstone/GetAgentId?username=dgsdgsdgsd&password=sdgsdgs
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "GetAgentId",id = RouteParameter.Optional }
);
add Id parameter in your routeTemplete in webapiconfig.
Have you enabled attribute routing in api config? config.MapHttpAttributeRoutes();
With your current route, you should hit it via query string "http://localhost:10133/api/BedfordBrownstoneApi/GetAgentId?username=dgsdgsdgsd&password=sdgsdgs" and decorate the parameters with [FromUri]
[HttpGet]
[Route("api/BedfordBrownstoneApi/GetAgentId/")]
public int GetAgentId(string username,string password)
{
//api stuff
}
or to hit the api via route parameters - http://localhost:10133/api/BedfordBrownstoneApi/GetAgentId/yourusername/yourpassword
[HttpGet]
[Route("api/BedfordBrownstoneApi/GetAgentId/{username}/{password}")]
public int GetAgentId(string username,string password)
{
//api stuff
}
Hope this helps you. Thanks!!
There are two issues.
Controller name - Change the name, add Controller in the name (BedfordBrownstoneApiController).
You missed calling 'config.MapHttpAttributeRoutes()' in Register function.
Please update your 'Register' function in 'WebApiConfig' as below.
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "GetAgentId" }
);
}
I have just change my code to following and now its work.
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "BedfordBrownstoneApi",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "GetAgentId" }
);
}

Remove "api" prefix from Web API url

I've got an API controller
public class MyController : ApiController { ... }
By default it is mapped to URL mysite/api/My/Method, and I'd like it to have URL without "api" prefix: mysite/My/Method
Setting controller attribute [RoutePrefix("")] didn't help me.
Are there any other ways to achieve that?
The default Registration is usually found in WebApiConfig and tends to look like this
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
You need to edit the routeTemplate in the convention-based setup.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Do note that if this project is shared with MVC that the reason for the api prefix was to avoid route conflicts between the two frameworks. If Web API is the only thing being used then there should be no issue.

ASP.net web api 2 Route-Attribute not working

I've the following problem, my route attribute is not working.
I have the following action:
[HttpGet]
[Route("~api/admin/template/{fileName}")]
public HttpResponseMessage Template(string fileName)
{
return CreateHtmlResponse(fileName);
}
and i want to access the action like .../api/admin/template/login.html, so that Template get login.html passed as the file name.
But i alsways get: No HTTP resource was found that matches the request URI 'http://localhost:50121/api/admin/template/login.html'.
The following request works: /api/admin/template?fileName=login.html
Does anyone know, what i am doing wrong with my routing?
EDIT:
My route configuration
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{action}",
new { id = RouteParameter.Optional });
You have to call MapHttpAttributeRoutes() so that the Framework will be able to walk through your attributes and register the appropriate routes upon application start:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
// you can add manual routes as well
//config.Routes.MapHttpRoute(...
}
}
See MSDN
Check your Route attribute's namespace. It should be System.Web.Http instead of System.Web.Mvc.
try adding a forward slash after the tilde
[HttpGet]
[Route("~/api/admin/template/{fileName}")]
public HttpResponseMessage Template(string fileName)
{
return CreateHtmlResponse(fileName);
}
Verify that you are using System.Web.Http.RouteAttribute and not System.Web.Mvc.RouteAttribute
Try this routing in your WebApiConfig
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
You have to add RoutePrefix.
With my Web API 2 project I had to add a [RoutePrefix("events")] to the controller for it to pickup the action route attribute.
In my case, I added Route("api/dashboard") to api controller.
Changed it to RoutePrefix("api/dashboard") . And it works perfectly.
Also you need config.MapHttpAttributeRoutes(); in webapiconfig.cs

Categories

Resources