9

I have a blazor web assembly which fetches from an external API built on ASP.NET Core which I do not have access to. I can perform get requests, but cannot perform post requests. I get the following error when I do.

Access to fetch at 'http://external:9000/User/Create' from origin 'http://localhost:56138' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

The author of the api confirms he enabled cors to allow any header in his startup and also suggested I do the same but this did not fix the issue. I confirmed from the debugger I am sending the right data format the endpoint requires and I am also running on http scheme same as the web service.

This is the client configuration in program.cs

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://external:9000/") });
builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });

This is how I post

var dataJson = JsonConvert.SerializeObject(application);
var stringContent = new StringContent(dataJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"User/Create", stringContent);

I have read this is a common problem with blazor assembly, I'm not entirely sure of what I read. I am currently trying to move the project to blazor server to see if it would work, but I would prefer it on web assembly.

5
  • 1
    Using .AddCors(...) on the client is of little use. It looks like the other author may allow any Header but not any Method. The problem is on the server. Commented Jan 23, 2021 at 12:42
  • But if you're unabale to get that fixed, Blazor Server should not have this problem. Commented Jan 23, 2021 at 12:43
  • @HenkHolterman It's exactly what I thought. I was just desperate enough to add it.
    – Qudus
    Commented Jan 23, 2021 at 13:53
  • You can write your own API layer as a go-between. Lets you still use Blazor Wasm. Commented Jan 23, 2021 at 20:51
  • @HenkHolterman I got it running on Blazor server. I think I'll just stick to it. And I don't have to worry about the app not running on some browsers like the problem web assembly gives
    – Qudus
    Commented Jan 24, 2021 at 0:35

2 Answers 2

2
builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });

This configuration should be done on a Server, and not yours but the server of the external API. You do nothing in that regard, except call end points on that Web Api.

The author of the api confirms they enabled cors to allow any header in his startup

If so, ask them for the code for confirmation...

and also suggested I do the same but this did not fix the issue.

You do nothing of the sort.

Workaround solution:

AS CORS is a security feature of JavaScript enforced by the browser, you can circumvent it by calling your Server code from which you perform the call to this Web Api end point, and then returns it back to your WebAssembly front-end. Use asynchronous code as much as you can.

Update as per comment

Are you saying I should have two projects, the server and the client under one solution? The server calls the calls the external api, then passes it to the client. Is this what your last suggestion is?

If you're using WebAssembly Blazor App hosted wherein the hosting server contains Web Api controllers, then you should expose end points that can be called from your WebAssembly front-end. The code in these end points should perform the HTTP calls to the external Web Api, and pass back to the WebAssembly calling methods the data received from the external Web Api.

Note: If you don't have such controllers ( they are created by default by Visual Studio), you may add them yourself to the server project.

If you already have created a Web Api project instead of those controllers, then expose the necessary end points from your Web Api project. Note that it makes no difference whether your Web Api project resides in the same solution of the WebAssembly front-end, as long as you provide the correct Url.

If you're using WebAssembly Blazor App stand alone; that is, the default installation does not create a Server project, you'll need to create a Web Api project and use it, unless you've already created one.

2
  • Are you saying I should have two projects, the server and the client under one solution? The server calls the calls the external api, then passes it to the client. Is this what your last suggestion is?
    – Qudus
    Commented Jan 23, 2021 at 14:11
  • I've updated my answer to reflect your comment.
    – enet
    Commented Jan 23, 2021 at 18:21
2

If you are working with localhost so you should add this configuration to your Server:

 builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => 
    builder.WithOrigins("http://localhost:56138/")
     .SetIsOriginAllowed((host) => true) // this for using localhost address
     .AllowAnyMethod()
     .AllowAnyHeader()
     .AllowCredentials());
});
//
app.UseCors("_myAllowSpecificOrigins");

Not the answer you're looking for? Browse other questions tagged or ask your own question.