I'm trying to get my ReactJS app (on an AWS S3 machine) PUT request working with my Server API (on an AWS Windows EC2 machine). Seems I am being tripped up by the preflight message that is being sent out. I've been searching on how to handle this and came across these two stackoverflow posts:

[Enable OPTIONS header for CORS on .NET Core Web API](https://stackoverflow.com/questions/42199757/enable-options-header-for-cors-on-net-core-web-api)

[How to handle OPTION header in dot net core web api](https://stackoverflow.com/questions/53479946/how-to-handle-option-header-in-dot-net-core-web-api)

I've ensured IIS accepts the OPTIONS verb and have added the middleware described. I can see the OPTIONS preflight handling being called through the logging but for some reason I am still getting the CORS error. Listed the main sections of the code below, any help would be really appreciated.

**ReactJS PUT request**

```
    var myHeaders = new Headers();
    myHeaders.append('Accept', 'application/json');
    myHeaders.append('Content-Type', 'application/json-patch+json');

    var rawObject = {
      Name: this.state.recipeEdit.name,
      Type: this.state.recipeTypeEdit,
      Description: this.state.recipeEdit.description,
      Ingredients: this.state.recipeIngredients,
      Steps: this.state.recipeSteps,
    };

    var requestOptions = {
      method: 'PUT',
      headers: myHeaders,
      body: JSON.stringify(rawObject),
      redirect: 'follow',
    };

    fetch(this.state.url, requestOptions)
      .then((response) => response.json())
      .then((data) => {
        this.setState({ recipeDetail: data });
      });

```

**Middleware Class**

```
    public class OptionsMiddleware
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private readonly RequestDelegate _next;

        public OptionsMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
            return BeginInvoke(context);
        }

        private Task BeginInvoke(HttpContext context)
        {
            if (context.Request.Method == "OPTIONS")
            {
                log.Error("Handling the OPTIONS preflight message");

                context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)context.Request.Headers["Origin"] });
                context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
                context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
                context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
                context.Response.StatusCode = 200;
                return context.Response.WriteAsync("OK");
            }

            log.Error("Invoking message");
            return _next.Invoke(context);
        }
    }

    public static class OptionsMiddlewareExtentions
    {
        public static IApplicationBuilder UseOptions(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<OptionsMiddleware>();
        }
    }

```

**CORS Configuration in Startup.cs**

```
        public void ConfigureServices(IServiceCollection services)
        {
            log.Error("Entered ConfigureServices");

            try
            {
#if DEBUG
                services.AddCors();
#else
                services.AddCors(o => o.AddPolicy("MyCorsPolicy", builder =>
                {
                    builder.SetIsOriginAllowed((host) => true)
                           .AllowAnyMethod()
                           .AllowAnyHeader()
                           .AllowCredentials();
                }));
#endif

                services.AddControllersWithViews().AddNewtonsoftJson();

                services.AddControllersWithViews(options =>
                {
                    options.InputFormatters.Insert(0, GetJsonPatchInputFormatter());
                });

                services.AddMvc(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
                services.AddMvc(options => options.Filters.Add(typeof(homebakeExceptionFilter)));

#if USE_SQLITE
                log.Error("Using SQLITE");
                services.AddDbContext<SqliteDbContext>(options =>
                {
                    options.UseSqlite("Data Source=./homebake.db");
                });
#else
            services.AddDbContext<AppDbContext>(options =>
            {
                options.UseInMemoryDatabase("homebakeapp-api-in-memory");
            });
#endif
                log.Error("Adding services");
                services.AddScoped<IIngredientRepository, IngredientRepository>();
                services.AddScoped<IRecipeStepRepository, RecipeStepRepository>();
                services.AddScoped<IRecipeRepository, RecipeRepository>();
                services.AddScoped<IIngredientService, IngredientService>();
                services.AddScoped<IRecipeStepService, RecipeStepService>();
                services.AddScoped<IRecipeService, RecipeService>();
                services.AddScoped<IUnitOfWork, UnitOfWork>();

                log.Error("Adding auto mapper");
                services.AddAutoMapper(typeof(Startup));
            }
            catch (System.Exception ex)
            {
                log.Error(ex.Message);
                if (ex.InnerException != null )
                    log.Error(ex.InnerException);
            }
        }

        private static NewtonsoftJsonPatchInputFormatter GetJsonPatchInputFormatter()
        {
            var builder = new ServiceCollection()
                .AddLogging()
                .AddMvc()
                .AddNewtonsoftJson()
                .Services.BuildServiceProvider();

            return builder
                .GetRequiredService<IOptions<MvcOptions>>()
                .Value
                .InputFormatters
                .OfType<NewtonsoftJsonPatchInputFormatter>()
                .First();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddLog4Net();

            log.Error("Entered Configure");
            app.UseOptions();

#if DEBUG
            app.UseCors(options => options.WithOrigins("http://localhost:3000").AllowAnyMethod().AllowAnyHeader());
#else
            log.Error("Using cors policy");
            app.UseCors("MyCorsPolicy");
#endif

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            //app.use
            app.UseHttpsRedirection();

            log.Error("Using MVC");
            app.UseMvc();
        }

```