I am new to WebApi and we have a requirement to create\maintain a token issuing web service. A colleague of mine provided his solution (beta) which he has allowed me to use. If I run the web service from my dev environment (VS 2012) I am able to query it and get the token back from a web browser (Chrome). I then wrote a test app to use HttpClient to query the service and get the token. This works fine from the service hosted in my dev environment but if I try to query it when hosted in IIS using my little test app I get a '404 Not Found' exception. But what is puzzling me is if I connect to the web service hosted in IIS from chrome it works?
My controller method is as follows:
[HttpGet]
public IHttpActionResult GetToken(string username, string password, string realm)
{
return Json("TOKEN-STRING");
}
And my config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,PUT,DELETE,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,PUT,DELETE,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
</handlers>
I have set my application pool to 'Integrated' within IIS.
My logic says to me that if I am able to retrieve the token from Chrome but not from my app, then there should be nothing wrong with IIS but rather a config\setting\programming error in my app.
Here is the little method I wrote to get the token:
async private void GetToken()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost/TokenServer/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("/api/TokenServer/GetToken/name/password/realm").Result;
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
//Error handling
return;
}
//Extract token from response
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
Token = DeserializeJsonToken(result);
}
I have read and tried many suggestions but none seem to work for me. I have been stuck with this for two days now and the deadline is creeping :)
Tx
The issue here is with the Url where you have a leading / which causes the TokenServer part of the baseaddress Url to be not considered. So modify the call like the following:
client.GetAsync("api/TokenServer/GetToken/name/password/realm").Result;
A tip: Tools like Fiddler can be of great use in situations like these. It helps in diagnosing the raw requests that are sent to the service.
Related
I am a little puzzled with issue here.
I have enabled CORS by adding the following code in startup
var enableCorsAttribute = new EnableCorsAttribute("*",
"Origin, Content-Type, Accept",
"GET, PUT, POST, DELETE, OPTIONS");
config.EnableCors(enableCorsAttribute);
And request to /token is working correctly. I get the correct token, and I have tested using postman.
When I try to request to other API controllers it fires 404 error saying
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I understand that's the header is missing but I am not sure how to configure this other than the code I have posted above.
I am running angular 2 app to perform the request.
Any help would be much appreciated!
I finally got it working after spending about 2 days... hopefully this answer helps other who might have the same problem.
One thing to note - if you implement or extend simple auth code,
inside this method GrantResourceOwnerCredentials you will have the following line of the code.
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
This is causing the inconsistency between /token request headers and request to other API controllers.
Long story short, comment this line so same request header is applied.
I have made changes to the web.config as the following
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="WebDav" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="None" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
</handlers>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
</customHeaders>
</httpProtocol>
And just in case you still have problems with options request, you can go to global.asax.cs file and modify the response as the following:
if ((HttpContext.Current.Request.HttpMethod == "OPTIONS"))
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
I really hope this answer saves someone else's time!
I am attempting to publish code to my company test web server and I'm getting a multitude of errors returned from IIS when attempting to call any methods using the PUT or DELETE verb. I've researched this particular issue, and all of the results that I've attempted either do nothing, or generate a new error. When I try with the default system.webServer configuration I receive the general 405 method not allowed error, here's that portion of the web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
From digging through Google and several stack articles, the majority of accepted answer specify to remove WebDAV through the web config file, which I've done, and here's that updated code:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
When I try using just removing the WebDAV handler, I continue to get the 405 method not allowed error, but as soon as I remove the WebDAVModule, my error becomes a 500 Internal Server Error, and viewing from the server doesn't actually give me any further information.
I've also attempted suggestions revolving around removing and adding the "ExtensionlessUrlHandler-ISAPI-4.0_32bit" & "ExtensionlessUrlHandler-ISAPI-4.0_64bit" handlers, with the same results (405 when don't remove the WebDAVModule or 500 when I do remove it).
Here's the methods on my WebApi controller that I'm attempting to call, maybe this is the problem, though it works just fine in my development environment:
public string PutRegistrationBatch(RegistrationBatch Model) {
// Code to save the model to our database
}
public string DeleteRegistrationBatch(RegistrationBatch Model) {
// Code to delete the item from the database
}
UPDATE
I ran a trace on the application and I'm seeing GET and POST commands get through to the site, however none of the PUT or DELETE commands get through to the site:
1/10/2017 1:22:41 PM /api/RegistrationBatch/ 200 GET
1/10/2017 1:22:55 PM /api/RegistrationBatch/ 200 POST
It seems as though the PUT and DELETE commands are being filtered out and refused at the host level and never making into my application.
UPDATE
It seems that WebDAV is the underlying issue, but we run a web service that utilizes this technology, so removing it is not an option until we can update that service. In the mean time, I've found that a work around outlined by Scott Hanselman here (http://www.hanselman.com/blog/HTTPPUTOrDELETENotAllowedUseXHTTPMethodOverrideForYourRESTServiceWithASPNETWebAPI.aspx) allows for me to send PUT and DELETE requests as a POST request.
I wouldn't suggest that is is an answer to the problem, but it at least allows me to work around the problem until such a time as we can uninstall WebDAV and hopefully that will allow my Web Api 2 application(s) to work properly.
You need to apply the [HttpPut] and [HttpDelete] attributes on the respective actions
[HttpPut]
public string PutRegistrationBatch(RegistrationBatch Model) { ... }
[HttpDelete]
public string DeleteRegistrationBatch(RegistrationBatch Model) { ... }
And in the config file you should also try to use the specific verbs you want to allow
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
If you have the WebDAV IIS feature installed, it can cause conflicts with Put, Delete, and Patch requests (maybe more... can't remember). You can either uninstall the feature server-wide or manually remove the HttpModule and HttpHandlers from the system.webServer element to target this specific application. See https://stackoverflow.com/a/26003440/179223
I remember getting into similar ditch sometime ago. Eventually this worked for me.
Reset all module configurations of 'Default Web Site' and your website to default values in IIS. You can do this by
1. Select your website, double click "Modules"
2. Click on "Revert to Parent" link under Actions panel on right side
Use the following into your Web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" runManagedModulesForWebDavRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Error
This operation requires IIS version 7.5 or higher running in
integrated pipeline mode.
This comes up anytime I try to access my WebApi page. The [HttpPost] decorated method is never hit. I understand Cassini does not allow integrated mode. However, I'm using code that's very similar to other projects in our code base that also use Cassini and we do not get this error.
I don't know what I'm using that requires integrated pipeline mode. My guess is something in global.asax is causing the issue. I'm using SimpleInjector.
I have boiled my global.asax down to this:
public class WebApiApplication : SimpleInjectorApiApplication<GenericExceptionPolicy>
{
protected override Assembly GetVersionAssembly()
{
return Assembly.GetExecutingAssembly();
}
protected override void RegisterServices()
{
base.RegisterServices();
Container.Register<IEntityCache, EntityCache>();
Container.Register<ICacheProvider, HttpCacheProvider>();
Container.Verify();
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
WebApiConfig.Register(RouteTable.Routes);
}
}
My Controller:
public class GenericController : ApiController
{
[HttpPost]
public HttpResponseMessage Get( /*PocoObjectName item*/)
{
throw new NotImplementedException();
}
}
And the web.config contains this relevant part:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
All this code exists in other projects and works as it is..so I'm at a total loss for what the problem is here. The issue only occurs in Cassini (IIS Express runs the code fine). Other projects are using Cassini without this error.
I updated Microsoft.AspNet.WebApi.WebHost. In the package manager console for NuGet I went from:
Install-Package Microsoft.AspNet.WebApi.WebHost -Version 5.1.0.0
to
Install-Package Microsoft.AspNet.WebApi.WebHost -Version 5.1.2.0
And the problem went away.
I know this is a commonly addressed issue, and I've done everything that many posts here on SO suggest. When I try to delete a record using WebAPI (version 2) from my MVC5 front end running under local IIS, I get a 404 Not Found response. Here are the things I've tried:
I've added the following under <system.webServer /> in my WebAPI web.config:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
I've followed the instructions at: http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx, which basically say to modify the ExtensionlessUrlHandler-Integrated-4.0 in IIS "Handler Mappings". It says to double click on the handler, click "Request Restrictions", and "Allow PUT and DELETE verbs". I've done this, and I still get the 404 error.
I've done an IIS reset.
Here's my MVC5 front end code that calls the WebAPI delete method - please note that when I manually navigate to api/bulletinboard/get/{0} where {0} is an integer, I get a valid JSON response. Below, contactUri is http://localhost/SiteName/api/bulletinboard/get/53 which returns valid JSON:
[HttpPost, ActionName("Delete")]
public ActionResult Delete(string appId, int id)
{
response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("MessageList", new { appId = appId });
}
else
{
LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
"Cannot delete message due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
return View("Problem");
}
}
Here's my WebAPI delete method:
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
BulletinBoard bulletinBoard = db.BulletinBoards.Find(id);
if (bulletinBoard == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.BulletinBoards.Remove(bulletinBoard);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, bulletinBoard);
}
Here's my WebApiConfig.cs in my WebAPI project:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ApiWithActionName",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Formatters.Add(new PlainTextFormatter());
}
QUESTION: What else can I try to resolve this error? This works fine when deployed from my local environment to my company's development servers.
for those who still looking for enable DELETE & PUT The below code solve my problem
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<!--This will enable all Web API verbose-->
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
I've followed the instructions at: https://forums.asp.net/t/1961593.aspx?DELETE+PUT+verbs+result+in+404+Not+Found+in+WebAPI+only+when+running+locally
That says to only change this piece of code in your Web.config, and works fine for me!
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
If you are using IIS, make sure you have the HTTP Verb set to allowed in Request Filtering. If its not there, you can set it to allow it on the side.
We were struggling with DELETE/PUT returning 404 errors on IIS 8. We did all of the above answers changing web.config to accept all Verbs, enabling put/delete in the request filtering. We had also disabled webDAV multiple ways. We found that the application pool was set to classic verses integrated (what it should have been). Now DELETE/PUT verbs work fine.
Mark Jensen solution worked for me.
Just changed my Application Pool from "Classic" to "Integrated" and my requests worked.
This issue can be fixed by IIS level configuration-
Open IIS->select your website->IIS (section) ->Request Filtering ->HHTP Verbs
Remove DELETE verb/ OR allow DELETE verb
Issue will get resolved.
What I did was just switch from using local IIS to IIS Express via the project properties on my WebAPI project, as a workaround. Doing this and deleting a record then resulted in a 405 Method Not Allowed error. I then changed the lines of code:
response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;
To:
response = client.DeleteAsync(string.Format("api/bulletinboard/delete/{0}", id)).Result;
This is very strange because I have another project that runs the first block of code and it deletes records just fine. Anyways, this resolved my local problem. I understand this doesn't really resolve my main issue which was using local IIS, but this workaround worked for me.
If your project is working under IIS and not under IISExpress, try to set IISExpress Managed Pipeline Mode to Integrated.
PUT and DELETE verbs seems to have problem under Classic Managed Pipeline mode.
Good luck..
Roberto.
For me it was an ISAPI module called UrlScan which I had to completely remove from the application.
I have been trying to get DELETE working now for over an hour and I am a little frustrated. I have tried every recommendation I can find. I have removed EVERY reference to ANYTHING WEBDAV from my applicationconfig as well as copying my whole webserver section over. I did it in steps and tried different variations and I still cannot get it to work. Yes my method is called DELETE and I added the [HttpDelete] to further make sure it knew I wanted delete support. Any other suggestions? :/
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
<remove name="FormsAuthenticationModule" />
<remove name="WebDAVModule" />
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Tried these and more:
Asp.NET Web API - 405 - HTTP verb used to access this page is not allowed - how to set handler mappings
Web API Put Request generates an Http 405 Method Not Allowed error
http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html
Kinda ridiculous, if M$ is going to release a product they should make sure its configured to work as expected out of the box.
Here is the controller code, it doesn't even break in it though as the application "doesnt understand the DELETE verb". The HttpDelete I slapped on there is from System.Web.Http not the mvc one. The name is by convention but I was hoping if I stuck the attribute on it would understand anyways.
// DELETE api/product/5
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
HttpResponseMessage response = null;
var product = _uow.Repository<Product>().ById(id);
if (product == null)
response = Request.CreateResponse(HttpStatusCode.NotFound);
_uow.Repository<Product>().Delete(id);
try
{
_uow.Save();
}
catch (DbUpdateConcurrencyException ex)
{
response = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
var model = Mapper.Map<ProductModel>(product);
return response ?? Request.CreateResponse(HttpStatusCode.OK, model);
}
This is in my angularJs controller
$scope.deleteProduct = function (product) {
product.$delete();
dismiss();
//$scope.products = _.without($scope.products, product);
};
This is in my angular service using $resource. (The rest of my crud is working)
minopApp.services.factory("ProductSvc", ['$resource',
function ($resource) {
return $resource('/api/product/:id',
{ productId: '#id' },
{
update: { method: 'PUT' }
});
}]).value('version', '0.1');
This is my routing inside the app.js
minopApp.config(
['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/products', {
templateUrl: 'areas/product/product-list.html',
controller: 'ProductCtrl'
}).
when('/products/new', {
templateUrl: 'areas/product/product-create.html',
controller: 'ProductCtrl'
}).
when('/products/:id', {
templateUrl: 'areas/product/product-detail.html',
controller: 'ProductCtrl'
}).
when('/products/:id/edit', {
templateUrl: 'areas/product/product-edit.html',
controller: 'ProductCtrl'
}).
otherwise({
redirectTo: '/products'
});
}],
['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
}]
);
It looks a lot in your Web.config. Can you trim it to...
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" runManagedModulesForWebDavRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
I have tested it in IIS with WebDAV component installed and both PUT and DELETE verbs work with it.
I was stuck in a position similar to this but with a with PUT verb when I suddenly realize, after requesting my Api via Fiddler Composer, that my restClient was performing an unvalid request like using
"api/resource?id=1234"
instead of
"api/resource/1234"