1
votes

I'm working on a ASP.NET Web API. I'm trying to use a Put http call to update some resource.

I've been searching and there are a lot of possible configurations but I wasn't able to hit the right one for me.

I'm using the endpoints by convention. No routes on the Controllers, just the name of the function I want to execute.

public IHttpActionResult Put([FromBody]JObject data)
{
    return this.ExecuteWithErrorHandling(() =>
    {
        return Ok();
    });
}

The problem is that when I call this from my web-app is calling an OPTIONS first. And I get a 405 error.

So I've found that if I remove the OPTIONSVerbHandler and the ExtensionlessUrlHandler-Integrated-4.0 from the web config I can get a 200 on the options call.

   <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" /> <-- Remove this line -->
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />  <-- Remove this line -->
    </handlers>

But the problem is that after this when I call my Put function on the api, I get 404.

I'm using IIS express. So I went to the config file of IIS and add the missing verbs on the handlers section.

<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />




<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Also add the values on the web config to remove the WebDAV

<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule" />
</modules>

and

<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>

Noticed that when I make a option call from postman I don't see the Put method.

Postman output

Controller Full Code:

using Newtonsoft.Json.Linq;
using Rev.API.Controllers.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Rev.API.Controllers
{
    public class TestController : BaseApiController
    {
        public IHttpActionResult Get()
        {
            return this.ExecuteWithErrorHandling(() =>
            {
                int[] arr1 = new int[] { 3, 4, 5 }
                return Ok(arr1);
            });
        }

        public IHttpActionResult Get(string id)
        {
            return this.ExecuteWithErrorHandling(() =>
            {
                int Id = Convert.ToInt32(id);
                return Ok(Id);
            });
        }
        [System.Web.Http.HttpPut]
        public IHttpActionResult Put([FromBody]JObject data)
        {
            return this.ExecuteWithErrorHandling(() =>
            {
                return Ok();
            });
        }

    }
}

But the problem still happening. Not sure what I'm missing.

1
First of all, if your API exists on a different domain/port from your web application, and your web application is browser based, then your API is going to have to support CORS. The initial OPTIONS request, sent by the browser, is called a preflight, and is used to query the API for allowed origins and methods for that endpoint. The CORS implementation was devised as a way to work around/with the browser same-origin policy, a policy implemented by browsers as a security measure.Joshua Jones
Yes totally agree with you. As I mention on the question. I get a 200 on the options call previous to call the put. But when the put call occurs I get 404. May be is not so clear.Mauri1OA
Just to clarify, on the WebApiConfig on the Register I added the Eneable cors: var cors = new EnableCorsAttribute("", "", "*"); config.EnableCors(cors);Mauri1OA
Also I follow the instructions for IIS express on this:stevemichelotti.com/…Mauri1OA
Can you add the full code for your controller?Joshua Jones

1 Answers

0
votes

After looking several configurations this is the config that works for me.

  1. Removed the EnableCors from the WebApiConfig

2.on my web config this is my system.web server secction:

`  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <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>
    <modules runAllManagedModulesForAllRequests="false"/>
    <handlers>
      <remove name="ExtensionlessUrl-Integrated-4.0" />
       <add name="ExtensionlessUrl-Integrated-4.0" 
           path="*." 
           verb="GET,HEAD,POST,DEBUG,DELETE,PUT" 
           type="System.Web.Handlers.TransferRequestHandler" 
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>`

Any one knows why Adding the ExtensionlessUrl-Integrated-4.0 works?

Thanks!