简体   繁体   中英

ASP NET web api POST/DELETE (Angular 6 HttpClient-)request returns: 405 Method not allowed

I created an application with Visual Studio 15 using ASP.NET web api as backend and Angular 6 within the Frontend. I simply want to show/add/delete a user in the Frontend based on the data in a database. I managed this using HttpClient in Angular 6 and the GET-Request to show the users data works fine. I tried to implement the POST/DELETE request in the same way. Here is the call from Angular:

deleteUser(id: number): Observable<{}> {
    const url = `${this.userURL}/${id}`;
    return this.http.delete(url, { withCredentials: true })
        .pipe(
            catchError(this.handleError('deleteData'))
        );
}

web API: I handled the preflight request in Global.asax.cs:

void Application_PreSendRequestHeaders(Object sender, EventArgs e)
    {
        var origin = Request.Headers.Get("Origin");
        var validOrigins = ConfigurationManager.AppSettings["allowedCorsOrigins"].Split(',');
        if (validOrigins.Any(o => o == origin))
        {
            Response.StatusCode = (int)HttpStatusCode.OK;
            Response.Headers.Set("Access-Control-Allow-Origin", origin);
            Response.Headers.Set("Access-Control-Allow-Credentials", "true");
            Response.Headers.Set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, access-control-allow-credentials, access-control-allow-headers, access-control-allow-methods, access-control-allow-origin, ontent-type, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization"); // "Content-Type, Accept, Authorization, withcredentials, Prefer"
            Response.Headers.Set("Access-Control-Expose-Headers", "Claims, *");
            Response.Headers.Set("Access-Control-Allow-Methods", "GET,PUT,POST,OPTIONS,PATCH,DELETE");
        }
    }

WebApiConfig.cs:

 public static void Register(HttpConfiguration config)
        {

            // enable Cors
            var cors = new EnableCorsAttribute("http://localhost:4200", "*", "GET, POST, PUT, DELETE, OPTIONS"){ SupportsCredentials = true};
            config.EnableCors(cors);
            // ...

            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
         }

auto-generated delete function in the controller: UserController.cs:

// DELETE: api/User/5
    [HttpDelete]
    [ResponseType(typeof(User))]
    public async Task<IHttpActionResult> DeleteUser(decimal id)
    {
        User user = await db.User.FindAsync(id);
        if (user == null)
        {
            return NotFound();
        }

        db.User.Remove(user);
        await db.SaveChangesAsync();

        return Ok(user);
    }

web.config.cs:

<appSettings>
   <add key="webpages:Version" value="3.0.0.0" />
   <add key="webpages:Enabled" value="false" />
   <add key="ClientValidationEnabled" value="true" />
   <add key="UnobtrusiveJavaScriptEnabled" value="true" />
   <add key="allowedCorsOrigins" value="http://localhost:4200" />
   <add key="allowedCorsMethods" value="GET, POST, PUT, DELETE, OPTIONS, BATCH" />
   <add key="allowedCorsHeaders" value="*" />
</appSettings>
<system.web>
   <compilation debug="true" targetFramework="4.5.2" />
   <httpRuntime targetFramework="4.5.2" />
   <httpModules>
     <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
   </httpModules>
</system.web>
<system.webServer>
   <validation validateIntegratedModeConfiguration="false" />
   <modules runAllManagedModulesForAllRequests="true">
     <remove name="WebDAVModule" />
     <remove name="ApplicationInsightsWebTracking" />
     <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
   </modules>
   <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>

If i press F12 in the client browser to open the development tools, the web API response code to the preflight request and finally the DELETE request is 200 as expected, but if i click on "application insights" in Visual Studio, the response code to the preflight is 401 and for DELETE it is 405. As a result the user is not getting deleted.

Client:

  • Options - 200

  • Delete - 200

Server: (in Applications Insights)

  • Options - 401

  • Delete - 405

I took a look at several similar questions at stackoverflow, but the given solutions didnt affect or solve my issue. I can provide more source code, if needed. Thanks in Advance.

I fixed my problem just by inserting [Route("api/User/{id}")] below [HttpDelete] . The delete function in the UserController.cs now looks like:

[HttpDelete]
[Route("api/User/{id}")]
[ResponseType(typeof(User))]
public async Task<IHttpActionResult> DeleteUser(decimal id)
{
    ...
}

I am not completely sure about this but you can try changing your function signature to DeleteUser(int id) (honestly, decimal id parameter looks so annoying :))and check your config file route template ( routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ) as to match with your parameter name (in this case id). Hope this solves your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM