简体   繁体   中英

Angular 6 Asp.Net (not Core) Web Api CORS request fails

I'm building a .Net Web Api that will be consumed by Angular 6 client but for any reason I'm not being able to make it to work in my development environment.

I started with an extremely simple Web Api that just does nothing but returns a string (with communication between frontend and backend testing purposes):

// GET: api/Login
public IEnumerable<string> Get()
{
    return new string[] { "Now it works!" };
}

// POST: api/Login
public void Post([FromBody]string value)
{
    string strTest = "I'm doing just nothing";
}

and then in my Angular 6 app I have a method with the following post request:

return this.http.post<any>(`http://localhost:9810/api/Login`, { username, password })
            .pipe(map(user => {
                // login successful if there's a jwt token in the response
                if (user && user.token) {
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                }

                return user;
            }));

In my first attempts all my responses were failing with response:

zone.js:2969 OPTIONS http://localhost:9810/api/Login 405 (Method Not Allowed)
login:1 Failed to load http://localhost:9810/api/Login : Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ' http://localhost:4200 ' is therefore not allowed access.

So I after investigating I've added CORS support to my WebApi .Net project the next way:

1) Installed Nuget packages:

Microsoft.AspNet.WebApi.Cors
Microsoft.AspNet.Cors

2) In WebApiConfig Register method:

var cors = new EnableCorsAttribute("http://localhost:4200", "*", "*");
// or var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

3) Alternatively to 2) in Api controller class header:

[EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]

But none seems to work, the request always fails with the same error as described above in browser console.

I tried creating a self hosting WebApi listening http calls on http://localhost:9000 as well as my last attempt that was publishing the WebApi in my local Windows 10 IIS server with 9810 port.

If I access the url in browser like so " http://localhost/api/Login " then the string is returned like so:

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <string>Now it works!</string>
</ArrayOfstring>

and no error is displayed in console but as long as I try to make the request by Angular (default port 4200) the request fails with CORS error.

I'm stuck. If I cannot make it to work from Angular I won't be able to do debugging and testing.

Thanks.

Edit 1: Chrome network tab info added.

General:

Request URL: http://localhost:9000/api/Login
Request Method: OPTIONS
Status Code: 405 Method Not Allowed
Remote Address: [::1]:9000
Referrer Policy: no-referrer-when-downgrade

Response Headers:

Allow: GET,POST
Content-Length: 76
Content-Type: application/json; charset=utf-8
Date: Wed, 29 Aug 2018 10:32:36 GMT
Server: Microsoft-HTTPAPI/2.0

Request Headers:

Accept: /
Accept-Encoding: gzip, deflate, br
Accept-Language: es-ES,es;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:9000
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

After struggling my head the whole morning and trying everything each one of you suggested here I cannot believe in the end my problem could have been resolved so easily.

Regarding @Madpop suggestion Application_BeginRequest (for any reason) was never being fired (dind't want to spend much time investigating why).

@Steveland solution involved adding dependency injection and it resulted a little bit complicated to me (I don't have much experience with that) aparte from the fact I'm not using Asp.Net Core but Asp.Net framework 4.6.

I was looking for a simple solution to a problem I thought it should have been easy to solve and the key was appending

[HttpPost]
[HttpOptions] //this was the key
[Authorize]

to Post method header. This was the only way for me to allow "Options" verb in request.

I don't know if this is the best way to accomplish this but for now it works (let me know what d'you think guys).

I appreciate ev'ry help I've received here from everybody and say thanks and as I'm not an expert on this subject (Angular + Web Api) I would like to finally ask the next:

Will I have to put this [HttpOptions] also for production when the api will be deployed to server or this is just needed for now for debugging and testing locally purposes?

Edit 1:

After testing I've noticed it works with self hosting Web Api but as I publish Web Api to my local IIS I get "415 Unsupported Media Type" in browser :(

Regarding the cors issue i also faced the similar issue i have created a global.asax file that i have place the below code

protected void Application_BeginRequest()
{

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        //These headers are handling the "pre-flight" OPTIONS call sent by the browser
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://staging.example.com:8044");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Accepts, Content-Type, Origin, X-My-Header");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "60");
        HttpContext.Current.Response.End();
    }

}

it worked for me in angular 6 as well in ionic 3 also and before all these try to install https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

the above chrome plugin and activate it and then try to run the application

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