Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I use a comma seperated string from appsettings.json in my CORS service?

I am learning c#, and have created a .net 6.0 Core API server.

I wanted to add in CORS support, to have multiple front end servers connect to a single back end (if needed)

I have the following in my appsettings.json (for development)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
  "frontEnd": "https://localhost:3000,https://localhost:3001,https:localhost:3002"
}

My Program.cs looks like the following

{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add dbcontext to the container.
            builder.Services.AddDbContext<ModelContext>();
            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            var MyAllowedOrigins = "_myAllowedOrigins";
            var frontEnd = builder.Configuration.GetValue<string>("frontEnd");
            var cors = frontEnd.Split(',');

            builder.Services.AddCors(options =>
            {
                options.AddPolicy(name: MyAllowedOrigins,
                    policy =>
                    {
                        //policy.WithOrigins("https://localhost:3000",
                        //    "https://localhost:3001",
                        //    "https://localhost:3002");
                        //policy.WithOrigins(frontEnd);
                        Type type = policy.GetType();
                        if (type != null)
                        {
                            MethodInfo methodInfo = type.GetMethod("WithOrigins");
                            if (methodInfo != null)
                            {
                                try
                                {
                                    methodInfo.Invoke(policy, cors);
                                } catch (Exception e)
                                {
                                    Console.WriteLine(e);
                                }
                            }
                        }
                    });
            });
            builder.Logging.AddEventLog();
            var app = builder.Build();

            
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
                app.Logger.LogInformation("Startup enviornment: Development");
            } else if (app.Environment.IsProduction())
            {
                app.Logger.LogInformation("Startup enviornment: Production");
            }

            app.UseHttpsRedirection();

            // Add to allow my react app to send to it without using development proxy?
            // See: https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0
            app.UseCors(MyAllowedOrigins);

            app.UseAuthorization();

            app.MapControllers();

            app.Run();

        }
    }
}

the version works.

            var MyAllowedOrigins = "_myAllowedOrigins";
            var frontEnd = builder.Configuration.GetValue<string>("frontEnd");
            var cors = frontEnd.Split(',');

            builder.Services.AddCors(options =>
            {
                options.AddPolicy(name: MyAllowedOrigins,
                    policy =>
                    {
                        policy.WithOrigins("https://localhost:3000",
                            "https://localhost:3001",
                            "https://localhost:3002");
                    });
            });

What is interesting is the policy.WithOrigins takes in a string array so ‘cors’ should function here.

Using reflection fails, as it says the number of parameters entered does not match the method signature.

Using the array built from my appsettings entry also fails but in a different way. The first host (localhost:3000) works, but a react app running on port 3002 fails with a message

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:7197/*****. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

Using the string as entered (A comma separated list of hosts) causes none of the systems to function…

Is there another way to set this up that would make it easier to have multiple front ends can be controlled by an appsettings.Production.json file?

>Solution :

Reflection is very much over-engineering this.

You’re successfully passing values one at a time here:

policy.WithOrigins("https://localhost:3000",
                   "https://localhost:3001",
                   "https://localhost:3002");

And you can pass as many as you like. That’s because WithOrigins accepts a params string[] parameter. What params basically means is that you can pass it multiple strings and the compiler will interpret them all as a string array.

But you can also just pass a string array, which you have right here:

var cors = frontEnd.Split(',');

So skip all the reflection and just pass your string values to the method:

policy.WithOrigins(cors);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading