I am working on PATCH method of my controller but I am constantly receiving error
The requested resource does not support http method patch
RouteConfig.cs
// GET http://localhost:28888/v1/panels/
// PATCH http://localhost:28888/v1/panels/1
routes.MapHttpRoute(
name: "Panel",
routeTemplate: "v1/panels/{id}",
defaults: new { controller = "Panel",
id = RouteParameter.Optional,
},
constraints: null,
handler: handler
);
PanelController.cs
[HttpPatch]
public HttpResponseMessage Patch(int panelId)
{
if (panelId <= 0)
{
throw new ArgumentNullException(nameof(panelId), "Can't be less or equal 0.");
}
panelTasks.SetPanelModified(panelId);
return Request.CreateResponse(HttpStatusCode.NoContent);
}
The Patch method is actually allowed. In Global.asax are below lines of codes
Context.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS");
Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
I am testing the url from Postman. The url is localhost:28888/v1/panels/2902901
#stephen.vakil
If you want it to map your route correctly automatically, the
parameter names need to match. It won't automatically map id to
panelId
Are you using IIS? If so, try to remove the WebDav map:
Open IIS and go to the site in question.
Click on "Handler Mappings"
Find the handler named "WebDAV"
Remove it
web.config on web api side configure allowed methods in sections httpProtocol,
<add name="Access-Control-Allow-Methods" value="GET,HEAD,PUT,PATCH,POST,DELETE" />
Is not there some conflict (with settings in code) or missing setting?
Related
I am new to MVC. Actually, I am trying to handle the bad request for my application. I have added Application_Error method in Global.asax and also created a controller to handle the 404-page error. Now this works fine when my URL is like following.
https://localhost:44397/t/t/t
It shows proper 404 page I have set for the bad URL
But It shows again 404 page when my URL is something like following
https://localhost:44397/t/t/t/e
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Can anyone help me how I can restrict above URL? Following is my route.config code.
routes.MapRoute(
"ErrorHandler",
"ErrorHandler/{action}/{errorMSG}/",
new { controller = "ErrorHandler", action = "Index", errMsg = UrlParameter.Optional }
,
namespaces: new[] { "MyProject.Web.Controllers" }
);
You need to register an additional route at the end of all valid routes which would match any URL. Sample code below. This will handle all invalid requests to your application.
routes.MapRoute(
"AllInvalidRoutes",
"{*.}",
new { controller = "InvalidRoutesController", action = "Index" }
);
I want to create a method for the update in a particular field of my record.
I'm new with Web API 2 in ASP.Net. I created a method but always get's an error
{"Message":"The requested resource does not support http method 'GET'."}
I want to create a custom method like this:
[HttpPut]
public string AddDeviceID(string deviceID)
{
User user = db.Users.Single(x => x.MobileUserName == "Dev" && x.MobilePassword == "123");
user.MobileDeviceId = deviceID;
db.SaveChanges();
return "success";
}
Here is my route config:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{deviceId}",
defaults: new { deviceId = RouteParameter.Optional }
);
I don't know what am i missing on this code I'm just following the concept of ASP.Net MVC of creating a method for update.
Anybody could provide some ideas? Thanks in advance.
You need to call your api with a HTTP PUT Request. You get this error, because you do a HTTP GET Request.
Even if you accepted the other answer, you realy should use the HttpPut Attribute, because it is more correct in the meaning.
From wikipedia:
GET
The GET method requests a representation of the specified resource. Requests using GET should only retrieve data and should have
no other effect. (This is also true of some other HTTP methods.)[1]
The W3C has published guidance principles on this distinction, saying,
"Web application design should be informed by the above principles,
but also by the relevant limitations."
PUT
The PUT method requests that the enclosed entity be stored under the supplied URI. If the URI refers to an already existing resource,
it is modified; if the URI does not point to an existing resource,
then the server can create the resource with that URI.
Just google about how to send a HTTP PUT Request with the library/software you are testing.
By the way: Postman is a good tool for testing.
This error happened because you executed HTTP GET request but your action is decorated with [HttpPut] attribute and can accept only HTTP PUT. To fix this you can implement functionality to execute HTTP PUT request or you can decorate your action with [HttpGet] attribute like in the following example:
[HttpGet]
public string AddDeviceID(string deviceID)
{
User user = db.Users.Single(x => x.MobileUserName == "Dev" && x.MobilePassword == "123");
user.MobileDeviceId = deviceID;
db.SaveChanges();
return "success";
}
How you made the request? Please note that browser will makes HTTP GET request.
I checked other sulotion sugessions that asked and answered here, but still couldn't find what's wrong with my own code.
I have a 'members' and 'fals' (means something like blogpost) controllers. every member has its own multiple 'fals' records, so I wanted to list 'fals' belongs to spesific member.
I wanted to add a custom action to my Web API to do this job, here is it:
[HttpGet, ActionName("fals"), Route("members/{id}/fals")]
public IQueryable<Fal> fals(int id)
{
Member member = db.Members.Find(id);
return member.Fals();
}
So, here is WebApiConfig customization:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{id}/{action}"
);
I know there are two Route, even if I comment or uncomment the second Route it changes nothing.
When I try to call http://localhost:51601/api/members/1/fals URL it says:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:51601/api/members/1/fals'.",
"MessageDetail": "No action was found on the controller 'Members' that matches the name 'fals'."}
ID 1 existed, as I pasted the code fals existed, but couldn't figured it out.
Thanks!
I'm not sure if you are using attribute routing or not, but try removing the Route attribute from the controller action.
[HttpGet, ActionName("fals")]
If the route is "interfering" with the conventional routing I expect this would work, or you could also try calling the URL without the /api/ part because that it missing from the Route you have specified in the attribute.
I have built a service in .NET 4.5 and Entity Framework 6, using the ASP.NET Web API template. When I make a GET request to the service and omit a required parameter, it is returning a 404 - Not Found, instead of a 400 - Bad Request. I tried checking to see if the required parameters are null, but it's not even reaching the code inside the method (see code below). My question is how do I change the default response or make it return 400 for missing required parameters.
[Route("item")]
[HttpGet]
public IHttpActionResult GetItem(string reqParam1, string reqParam2)
{
if (reqParam1 == null || reqParam2 == null)
throw new HttpResponseException(HttpStatusCode.BadRequest);
//remainder of code here
}
Here is the webAPI.config file. I don't think that I have modified it from the default.
public static class WebApiConfig
{
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 }
);
}
}
Just a note: the API isn't accessing information such as item/electronics/tvs but more like items where item is green and is square, where those descriptions are mandatory to pass in - so the query is like /item?color=green&shape=square.
The server returns a 404 because it cannot find the route you are trying to access. Actually the arguments should be a part of your route, as optionals or not: Route("items/{reqParam1}/{reqParam2}")
If you defined them as optionals the route should still be called if you use just items and you can throw the BadRequest. If not optionals then probably the NotFound will still be thrown.
You should also post the webApi config, so that we can see the base route mapping.
EDIT
take the following route example:
config.Routes.MapHttpRoute(
name: "RunsWithParams",
routeTemplate: "api/{controller}/{project}/{skip}/{take}",
defaults: new { take = RouteParameter.Optional, skip = RouteParameter.Optional }
);
the project param is mandatory, the remaining are optional. you can call with just the project, or the remaining, and if you use just one of the Optionals then 404 is thrown, because the route is not defined.
This is the same as using the decorators, so it does not exactly solve your issue, but explains a bit better the routing. Still, I don't see why you need a BadRequest in particular.
Yet another edit:
To use the request url parameters as you mention at the end of the post, you just need to use the [FromUri] decorator, see this page for more details, and a breef example follows:
// POST api/files/{project}?target={target}
public HttpResponseMessage Post(string project, string target, [FromUri]string fname){...}
So, we're developing a webapi-heavy application that serves multiple types of clients (including a website that's a JavaScript client and multiple C# clients), and we'd like to use attribute routing to make friendlier urls. Something like this:
[RoutePrefix(Constants.RoutePrefixes.Api + "foo")]
[HttpPut]
FooController : ApiController
{
[Route("{fooId}/sub/{subFooId}")]
[HttpPut]
public HttpResponseMessage UpdateAFoo(int fooId, int subFooId)
{
return Request.CreateResponse(HttpStatusCode.OK);
}
}
And a request to /api/foo/1/sub/2 would hit this controller, as expected.
However, we have a message handler built into one of our default routes for processing identity tokens, and requests coming from clients that require that special behavior still have to use that route, or at least something that runs the appropriate message handler, and the following request (which uses that other route):
/integration/foo?fooId=1&subFooId=2
..gives me an error that no suitable controller could be found to handle the request. If I remove the route attribute, this second request hits my action method as expected.
I've read in several places that you can use both default and attribute routes, and I have both working in the application, but I haven't been able to use both for a specific action.
My route config looks like this:
public static void RegisterHttpRoutes(HttpConfiguration configuration)
{
var routes = configuration.Routes;
configuration.MapHttpAttributeRoutes();
routes.MapHttpRoute(
name: Constants.RouteNames.Api,
routeTemplate: Constants.RoutePrefixes.Api + "{controller}/{id}/{p}",
defaults: new { id = RouteParameter.Optional, p = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: Constants.RouteNames.IntegrationApi,
routeTemplate: Constants.RoutePrefixes.IntegrationApi + "{controller}/{id}/{p}",
defaults: new { id = RouteParameter.Optional, p = RouteParameter.Optional },
constraints: null,
handler: new SuperDuperAuthenticationHandler())
);
}
Is that just how it works? Do I need a separate action without the route attribute? Is there a way to specify message handlers for attribute routes? Can I have both attribute and convention routing apply to the same action method? I'm not really clear on what my options are.
Controllers/Actions which are decorated with attribute routes cannot be reached via routes matched by conventional routing...so the behavior that you are seeing is expected...
Per-route message handlers are not supported for attribute routes.
Can you use AuthenticationFilterAttribute for your scenario?...if you need this filter for a set of controllers, then you could probably create a base controller decorated with this filter and let all these set of controller derive from it...