This question already has answers here:
ASP.NET 5: Access-Control-Allow-Origin in response
(2 answers)
Closed 6 years ago.
I've been working on a new mvc core application where I'm using core as my backend, and I'm using react as my front end.
I've started running into problems with cors where I am unable to post anything from my react fronted into my mvc core backend. Looking into the documentation has not been very helpful and even taking a "scorched earth" approach by allowing everything:
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
});
isn't helping either and now I've no idea what is really happening other than my post requests are being rejected.
My action looks as follows:
[HttpPost("_api/admin/monitor-customer")]
public IActionResult SetCustomerMonitor([FromBody]UpdateMonitor model){
try
{
var customer = Customers.Single(c => c.CustomerId == model.Id);
customer.IsMonitored = !customer.IsMonitored;
_context.SaveChanges();
return Json(new { success = true });
} catch(Exception ex){
_logger.LogDebug(ex.Message, null);
return Json(new { success = false });
}
}
My post request from react is as follows:
updateCustomer = (e) => {
var customerId = e.target.value;
$.ajax({
type: "POST",
contentType: 'application/json; charset=utf-8',
url: "http://localhost:5000/_api/admin/monitor-customer",
data: JSON.stringify({ Id: customerId }),
dataType: "json"
});
}
Also include is my Startup.cs
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
builder.AddUserSecrets();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
ILogger _logger;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AlertContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultSqlite")));
//services.AddDbContext<AlertContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<DbContext, AlertContext>();
services.AddSingleton<IDmsService>(new DmsService());
services.AddMvc();
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseCors(options => options.AllowAnyHeader());
app.UseCors(options => options.AllowAnyMethod());
app.UseCors(options => options.AllowAnyOrigin());
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Problem solved due to where core is enabled.
service.AddCors() must precede services.AdMvc() in the ConfigureServices methods, and the same holds true for the Configure() method. app.UseCors() must be called before app.UseMvc()
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AlertContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultSqlite")));
//services.AddDbContext<AlertContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<DbContext, AlertContext>();
services.AddSingleton<IDmsService>(new DmsService());
// Add service and create Policy with options
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials() );
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Related
Once after hosting the project both in local IIS and in server, I found that in server all the identity related pages throws 404 error, whereas in local IIS it works fine. All the other pages apart from Identity Pages are accessible. My StartUp class looks like this:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSingleton<IFileProvider>(
new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")));
var connectionString = this.Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(connectionString);
options.UseLazyLoadingProxies(true);
});
//services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDefaultIdentity<XonetPlus_V3.Entities.Domain.User>(options => options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>().AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(#"c:\shared-auth-ticket-keys\"))
.SetApplicationName("SharedCookieApp");
services.ConfigureApplicationCookie(options => {
options.Cookie.Name = ".AspNet.SharedCookie";
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddTransient<IRepositoryWrapper, RepositoryWrapper>();
services.AddScoped<IEmailSender, EmailSender>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, UserManager<User> userManager, RoleManager<IdentityRole> roleManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
IdentityDataInitializer.SeedData(userManager, roleManager);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=admindashboard}/{action=Index}/{id?}");
// endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("queryParams", "{controller=admindashboard}/{action=Index}/{param}/{id}");
endpoints.MapControllerRoute("areas", "{area:exists}/{controller=admindashboard}/{action=Index}");
endpoints.MapRazorPages();
});
}
}
My asp.net core web application is not serving the ApiController route I have setup, however it used to work but I didn't change anything so idk why its not working now.
When I navigate to https://localhost:5001/api/Demo; it returns me to my sites homepage instead of running the action and displaying the data. the url in the address bar does change to …:5001/api/Demo, but does not display the data.
// controller
[ApiController]
[Route("api/[controller]")]
public class DemoController : ControllerBase
{
[HttpGet]
public string Index(string result)
{
return "test string";
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "api/{controller=Demo}/{action=Index}/{result?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
==============================================
UPDATE: add configure method from startup class
The code was working perfectly but all of a sudden the seed method for the user is no longer working after I push to the production server with a fresh database.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequiredLength = 4;
options.Password.RequireUppercase = false;
})
.AddErrorDescriber<JapaneseErrorDescriber>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddDefaultUI()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDistributedMemoryCache();
services.AddMemoryCache();
services.AddHttpContextAccessor();
services.AddSession(options =>
{
options.Cookie.Name = ".AdventureWorks.Session";
options.IdleTimeout = TimeSpan.FromDays(365);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<IdentityUser> userManager, ApplicationDbContext context, IServiceProvider service)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
ApplicationDbInitializer.SeedUsers(userManager, context);
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
-- Seed method
public static void SeedUsers(UserManager<IdentityUser> userManager, ApplicationDbContext context)
{
if (userManager.FindByEmailAsync("admin#admin.com").Result == null)
{
IdentityUser user = new IdentityUser
{
UserName = "admin#admin.com",
Email = "admin#admin.com"
};
IdentityResult result = userManager.CreateAsync(user, "adminpass").Result;
> System.AggregateException: 'One or more errors occurred. (Object reference not set to an instance of an object.)'
> NullReferenceException: Object reference not set to an instance of an object.
if (result.Succeeded)
{
userManager.AddToRoleAsync(user, "Admin").Wait();
}
}
}
So I deleted all the data from the Dev Database and tried to see what was going on. In debugging mode, I was getting the instance of the Usermanger but when the call to the CreateAsync() was called the error occurs.
I try to implement redis cache in Asp.Net Core Application but its not Set any value in HttpContext.Session and not even return any value.This is my startup.cs file.
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.InstanceName = Configuration.GetValue<string>("redis:name");
options.Configuration = Configuration.GetValue<string>("redis:host");
});
services.AddSession(o=> { o.IdleTimeout = TimeSpan.FromMinutes(5); });
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseSession();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Appsetting.json
"redis": {
"host": "redis-17930.c1.ap-southeast-1-1.ec2.cloud.redislabs.com",
"port": 17930,
"name": "Astroyogi"
},
HomeController.cs
public IActionResult Index()
{
var helloRedis = Encoding.UTF8.GetBytes("Hello Redis");
HttpContext.Session.Set("hellokey", helloRedis);
var getHello = default(byte[]);
HttpContext.Session.TryGetValue("hellokey", out getHello);
ViewData["Hello"] = Encoding.UTF8.GetString(getHello);
return View();
}
and the lib which i installed-
Microsoft.Extensions.Caching.Redis
Microsoft.AspNetCore.Session
and its will not set any value in session.
Please help me where i am stucking.
You cannot both set and get the value you just set in the Session in the same request. Session requires a cookie to be set, which will only happen after you return the response. On the next request, you should be able to access your value fine.
When the server I'm authenticating with responds with the redirect back to my callback URL, my code doesn't seem to know how to handle the request - as if I'm missing a handler.
I thought the CallbackPath property would wire this up and pass the incoming request to my handler, is that not correct?
I just get a 404 from my app, the URL has the code=XXXX etc.
Here's my code
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string authScheme = CookieAuthenticationDefaults.AuthenticationScheme;
services.AddAuthentication(o =>
{
o.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultAuthenticateScheme = "MyAuthScheme";
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddOAuth(authScheme, options =>
{
options.ClientId = "xxxxxxxxxxxxxxxxxxxxxxxx";
options.AuthorizationEndpoint = "https://example.com/adfs/oauth2/authorize?resource=https://example.net/";
options.TokenEndpoint = "https://example.com/adfs/oauth2/token";
options.CallbackPath = new Microsoft.AspNetCore.Http.PathString("/signin-myauthserver");
options.ClientSecret = "xxxxxxxxxxxxxxxxxxxxxxxx";
});
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseAuthentication();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}