Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 501
Diego Perez Avatar asked Aug 29 '18 09:08

Diego Perez


1 Answers

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

like image 78
Diego Perez Avatar answered Oct 27 '22 21:10

Diego Perez