ASP.NET Web API REST Service: HTTP ERROR 405 - c#

I have an ASP.NET Web API REST Service. It has been build using standard ASP.NET Framework 4.5 and Web API 2.2 (version 5.2.3) on Visual Studio 2013 IDE.
Using Fiddler tool I am trying to check the api methods but I get http error 405. Below some screenshots from Fiddler:
Headers tab information:
Raw tab information:
Basically it says:
The requested resource does not support http method 'POST'."
Below some code snippet from my ASP.NET Web API REST Service.
WebApiConfig.cs :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "WarehouseApi",
routeTemplate: "api/{controller}/{action}/{data}"
);
}
}
Controller:
[RoutePrefix("api/Warehouse")]
public class WarehouseController : ApiController
{
public HttpResponseMessage GetOkResponse()
{
return Request.CreateResponse(HttpStatusCode.OK);
}
[HttpPost]
[Route("DumpIntoFile/{data}")]
public HttpResponseMessage DumpIntoFile(string data)
{
// Stuff here
}
}
To test it using Fiddler, from the composer I do:
However If I call GetOkResponse action method from Fiddler using GET method and url: wstestDumpFile.my.domain/api/Warehouse then it works.

Change from this: [Route("DumpIntoFile/{data}")] to [Route("DumpIntoFile")], you are passing the data as a post and therefore are not passing the data as a route parameter. Then you can add: [FromBody] to your method parameter like: ([FromBody] string data)

Related

Not able to find Web API route?

I’m struggling to figure out why I can’t get to an API end point. I’m building a Web API that will be calling another local API and from everything I see it should be getting to the end point and I’m looking for any ideas.
This is the code in the originating API. I’m using RestSharp to make the call.
string jsonToSend = JsonConvert.SerializeObject(m);
var request = new RestRequest("CheckForDuplicateID", Method.POST);
request.AddParameter("application/json; charset=utf-8", jsonToSend, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
request.AddParameter("CandidateID", m.CandidateID);
request.AddParameter("FirstName", m.FirstName);
request.AddParameter("LastName", m.LastName);
var client = new RestClient("http://localhost:60077/api/IDM/");
var content = client.Execute(request).Content;
This is the end point in the secondary API where I'm trying to get to.
[HttpPost]
public static DuplicateCheck CheckForDuplicateID([FromBody] DuplicateCheck m)
{
....code
}
This is my RouteConfig.cs file. I've tried both routes and neither one works.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
);
}
When I fire up the secondary API locally it is running on localhost:60077 which I hard coded above. The name of my controller is IDMController and this is the message I get but the URL looks correct to me.
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:60077/api/IDM/CheckForDuplicateID'.","MessageDetail":"No type was found that matches the controller named 'IDM'."}
Actions must be instance members of the ApiController, not static.
[HttpPost]
public DuplicateCheck CheckForDuplicateID([FromBody] DuplicateCheck m) {
....code
}
Since attribute routing is enabled with
config.MapHttpAttributeRoutes();
consider using attribute routing on the API controller to get the desired behavior
[RoutePrefix("api/IDM")]
public class IDMController : ApiController {
//...
//POST api/IDM/CheckForDuplicateID
[HttpPost]
[Route("CheckForDuplicateID")]
public DuplicateCheck CheckForDuplicateID([FromBody] DuplicateCheck m) {
....code
}
}
Reference Attribute Routing in ASP.NET Web API 2

Unable to connect to ASP.NET web api when I add additional parameters

I am trying understand Web Api 2 (MVC project in Visual Studio).
The method is
[HttpPost]
public string Post(int id, string e, bool o)
///code removed
Using Postman, I can query using Post and the path http://localhost:62093/api/Demo/5. This works and returns the expected value.
Now I want to add more parameters and this is where it goes wrong!
I have updated my method to
[HttpPost]
public string Post(int id, string e, bool o)
Now when I attempt to query this using (again) Post and the path http://localhost:62093/api/Demo/5 I see
"Message": "The requested resource does not support http method 'POST'."
I then try to change the URL, so when I use Post and the new path http://localhost:62093/api/Demo/5/a/false I see an HTML file response of
The resource cannot be found
This has been mentioned before on Stackoverflow and from what I've understood is about the URL being 'incorrect'
Thinking this could be an issue with routes I updated mine to
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{s}/{o}",
defaults: new { id = RouteParameter.Optional, s = RouteParameter.Optional, o = RouteParameter.Optional }
);
But the same issue persists. I'm not sure what I've done wrong.
This is a routing issue. you have not configured your routes correctly.
First let us update the WebApiConfig.cs file
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 }
);
}
}
Now with that configured I would suggest using Attribute routing
public class DemoController : ApiController {
[HttpPost]
[Route("api/Demo/{id:int}/{e}/{o:bool}")] //Matches POST api/Demo/5/a/false
public IHttpActionResult Post(int id, string e, bool o) {
return Ok();
}
}
I would finally suggest reading up on Attribute Routing in ASP.NET Web API 2 to get a better understanding on how to properly route to your API controllers

ASP.NET Web API Route Controller Not Found

I am trying to post to the following Web API:
http://localhost:8543/api/login/authenticate
LoginApi (Web API) is defined below:
[RoutePrefix("login")]
public class LoginApi : ApiController
{
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Here is the error I get:
Request URL:http://localhost:8543/api/login/authenticate
Request Method:POST
Status Code:404 Not Found
Remote Address:[::1]:8543
Your controller name "LoginApi" needs to end in "Controller" in order for the framework to find it. For example: "LoginController"
Here is a good article which explains routing in ASP.NET Web API: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
You are using login as your route prefix on your controller so trying to call
http://localhost:8543/api/login/authenticate
will not be found as this code
[RoutePrefix("login")]
public class LoginApi : ApiController
{
//eg:POST login/authenticate.
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
will only work for
http://localhost:8543/login/authenticate
You need to change your route prefix to
[RoutePrefix("api/login")]
public class LoginApi : ApiController
{
//eg:POST api/login/authenticate.
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
Notice you are using both attribute routing on the controller/action and convention routing with config.Routes.MapHttpRoute.
config.Routes.MapHttpRoute will map the routes as per your definition "api/{controller}/{id}".
While attribute routing, will map the routes based on how you've defined them: /login/authenticate.
Also, since you are using both attribute routing and convention routing, attribute routing takes presendence. I would stick to using one or the other. Having both adds a bit of confusion as to what route will be used to access an action method.

Calling ASP.Net Web API From ASP.NET Website Webforms

For the last couple of hours i'm trying to execute web api action hosted in asp.net webforms website.
I know its wired but due to old project design i have to do this.each time i call the action in Controller i got
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:3049/api/chart/test?id=58'.","MessageDetail":"No action was found on the controller 'Chart' that matches the request."}
My Project structure as follows:-
My Classes code looks very simple:-
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
}
My Controller:-
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ChartController : ApiController
{
[HttpGet]
public static string test(string id)
{
return id;
}
}
What i miss ?
Make your action method non-static. In Microsoft's documentation, they say this:
Which methods on the controller are considered "actions"? When selecting an action, the framework only looks at public instance methods on the controller.
Also, your routing is in the form of api/{controller}/{id} but the URL you're accessing is in the form of /api/controller/action?id=string. Notice the mismatch? You can change your action method to match your route.
[HttpGet]
public string Get(string id)
{
return id;
}
And then access it at /api/chart/58.
With the default routing structure in Web API, your route tells it what controller, the selected action method is based on the HTTP Method (GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH) and the parameters, and then other segments of the URL become the parameters.
Learn more detail about Web API Routing on MSDN.

MVC 4 Web Api 404

I have looked all over for some kind of soultion for this and it seems I have it setup correctly and followed all corrections in other questions.
When calling "http://localhost/en/api/cart/get" I get:
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost/en/api/cart/get'.","MessageDetail":"No type was found that matches the controller named 'cart'."}
...when trying to access a ApiController setup in an EPiServer CMS/Commerce 7.5+ solution.
The Controller looks like this:
public class CartController : ApiController
{
[HttpGet]
public string Get()
{
return "OK";
}
}
In Global.asax.cs i have this:
protected void Application_Start()
{
RegisterApis(GlobalConfiguration.Configuration);
And the RegisterAPis looks like this:
public static void RegisterApis(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
"Api", // Route name
"api/{controller}/{action}/{id}", // URL with parameters
new { id = RouteParameter.Optional } // Parameter defaults
);
config.Routes.MapHttpRoute(
"LanguageAwareApi", // Route name
"{language}/api/{controller}/{action}/{id}", // URL with parameters
new { id = RouteParameter.Optional } // Parameter defaults
);
// We only support JSON
var appXmlType = GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
On the same machine I have the EPiServer Commerce starterkit running i IIS and the code for registering the api controllers is the same. That site runs fine and the api calls can be made correctly but on my site all I get is 404.
So I am probably missing some configuration but I can't for my life figure out what it is. The weird part is that on my site I'm running the EPiServer ServiceApi which creates the /episerverapi Web Api mapping and that works just fine.
Anyone got any clues on why I can't get my APiControllers to work?
In Web API the http verb help the framework to find the right action to be executed and return a result. For sample, in a case of a get method, you just call the controller by get http verb:
http://localhost/en/api/cart
It will bind a Get action method in the Cart controller class. It is valid for a Post, Put, Delete methods too. Keep the default route of asp.net web api
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Try calling just
http://localhost/en/api/cart
In WebAPI if the name of the method matches a HTTP verb then it calls that method when that verb is used on that controller.

Categories

Resources