15

I am using Angular 4 app with Asp core web api which I test on the locahost with different ports. My WebApi requires Windows Authentication(need to get logon user name). All calls using GET work, but unfortunately, I cannot get POST to work. I have WebApi setup for CORS:

        public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.AddDbContext<CatalogContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddCors(options =>
        {
            options.AddPolicy("AllowAll", builder =>
            {
                builder.AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });

        });
        services.AddMvc();
    }

And angular 4 client is trying to post file

fileChange(event) {
let fileList: FileList = event.target.files;
if (fileList.length > 0) {
  let file: File = fileList[0];
  let formData: FormData = new FormData();
  formData.append('uploadFile', file, file.name);
  let headers = new Headers();
  /** No need to include Content-Type in Angular 4 */
  headers.append('Content-Type', 'multipart/form-data');
  headers.append('Accept', 'application/json');

  let options = new RequestOptions({ headers: headers, withCredentials: true });
  this.http.post("http://localhost:495/api//upload",formData, options)
    .map(res => res.json())
    .catch(error => Observable.throw(error))
    .subscribe(
    data => console.log('success'),
    error => console.log(error)
    )
}

My error:

XMLHttpRequest cannot load http://localhost:495/api//upload. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 500.

And Response headers

Content-Length:0 Date:Sun, 13 Aug 2017 13:13:09 GMT Persistent-Auth:true Server:Kestrel X-Powered-By:ASP.NET X-SourceFiles:=?UTF-8?B?QzpcU291cmNlIENvZGVcUGFydG5lcnNoaXBDYXRhbG9nXFBhcnRuZXJzaGlwQ2F0YWxvZ1xQYXJ0bmVyc2hpcENhdGFsb2cuV2ViQXBpXGFwaVx1cGxvYWQ=?=

Any help would be appreciated!

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Tom Brzeski
  • 501
  • 1
  • 5
  • 9
  • Check http://enable-cors.org. it looks like the way you are adding cors is not working. Check chrome network tab for http request. Click on request individually to see request and response details. Instead of calling through your application, check with fiddler or chrome extensions like postman or advanced rest. You can also try enabling cors on individual class, method or in web.config separately. – Amit Kumar Singh Aug 13 '17 at 13:32
  • 3
    Please post your exception stack/message. When an exception in ASP.NET Core happens, the exception middleware will **clear the headers**, so the CORS headers get lost. Look what causes the exception and solve the exception, then it should work, Http code 500 is returned when exception happens – Tseng Aug 13 '17 at 13:45
  • 3
    Can you confirm that `UserCors` is before any `UseMvc` calls in the `Configure` method? – regnauld Aug 13 '17 at 15:21
  • Are you sure it's a CORS issue? I have seen this misleading error thrown by angular after the actual request fails for whatever reason. Have you checked the Network tab in the browser to ensure the pre-flight OPTIONS request is successful? If so then this is not a CORS issue. – Brad Aug 13 '17 at 23:43
  • Ok, I have some more info, very strange. I am testing locally. My angular app on port 4200 and my web api server on 495. All get calls work. The post methods works only if I have Fiddler running in the background. I cannot figure this one out, it is killing me!!! – Tom Brzeski Aug 16 '17 at 19:50

4 Answers4

8

Preflight requests (OPTIONS) do not send auth info to server. So, you need to enable Anonymous Auth in addition to WinAuth. Please see: https://stackoverflow.com/a/50354772/946773

jaymjarri
  • 3,048
  • 1
  • 18
  • 7
  • Use IIS CORS module to handle the preflights is the official way, https://blogs.iis.net/iisteam/introducing-iis-cors-1-0 since Nov 2017. – Lex Li Apr 08 '19 at 00:45
  • Thanks!! This was my issue. I could make GET but not PUT/POST/DELETE requests – steveareeno Mar 16 '20 at 19:29
5

You need something like this:

services.AddCors(options =>
      {
        options.AddPolicy("CorsPolicy",
            builder => 
            builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .WithExposedHeaders("content-disposition")
            .AllowAnyHeader()
            .AllowCredentials()
            .SetPreflightMaxAge(TimeSpan.FromSeconds(3600)));
      });

Notice AllowCredentials().

You also need, in your Startup file Configure method:

app.UseCors("CorsPolicy");
dee zg
  • 13,793
  • 10
  • 42
  • 82
  • Yes, I do have app.UseCors("AllowAll") and adding preflight did not help either. – Tom Brzeski Aug 13 '17 at 13:49
  • 1
    Follow the answer here: https://stackoverflow.com/questions/44379560/how-to-enable-cors-in-asp-net-core-webapi. We had `.WithOrigins("http://localhost:8000")` set, but did NOT have `.AllowAnyMethod().AllowAnyHeader();` set. The lack of these caused the problem. – VSO Feb 17 '20 at 16:41
1

I stumbled upon this thread because I had the exact same thing. After many frustrating hours playing with the CORS settings, I noticed the POST did work but only when using https instead of http.

Maybe this can help someone.

0

In my case I had to slighlty modified POST/Put method

From

public IHttpActionResult PostTest(Test objTest)

To

public IHttpActionResult PostTest([FromBody]Test objTest)
KumarHarsh
  • 5,046
  • 1
  • 18
  • 22