Hi everyone i have Mcv Api Project and i try to loggin with Serilog, but when i try to invoke my api and logging some text in file/console, its empty, and i can't understand what's wrong
my program.cs
public static void Main(string[] args)
{
var seriliogConfiguration = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "Configs"))
.AddJsonFile("settings.json")
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(seriliogConfiguration)
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
my settings json
{
"Serilog": {
"Using": [],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "D:\\Logs\\logs.txt",
"outputTemplate": "{Timestamp:G} {Message}{NewLine:1}{Exception:1}"
}
}
]
}
}
and api when i try to exucete logging in file and console
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger) => _logger = logger;
public IEnumerable<WeatherForecast> Get() =>_logger.LogInformation("You requested Get()");
Because the Serilog is not injected into Asp.net Core container. The interface called in the controller is not a Serilog method. So the log will not be written to the file. You need to modify Program.cs.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var seriliogConfiguration = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "Configs"))
.AddJsonFile("settings.json")
.Build();
webBuilder.UseSerilog((hostingContext, loggerConfiguration) =>
{
loggerConfiguration.ReadFrom.Configuration(seriliogConfiguration);
});
});
}
I add a log in this action.
[HttpGet]
public IActionResult Get()
{
_logger.LogInformation("This info is in index");
return Ok();
}
In console.
In this log file.
Related
i am getting this error when i run the application:
System.AggregateException HResult=0x80131500
Message=Some services are not able to be constructed (Error while validating the
service descriptor 'ServiceType:
KimiaBaseProject.Framework.Commands.CommandHandler1[KimiaBaseProject.Core.Domain.Courses.Commands.AddCourseCommand] Lifetime: Scoped ImplementationType: KimiaBaseProject.Core.ApplicationServices.Courses.Commands.AddCourseCommandHandler': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbSet1[KimiaBaseProject.Core.Domain.Courses.Entities.Course]'
while attempting to activate
'KimiaBaseProject.Infrastructures.Data.SqlServer.Courses.Repositories.CourseCommandRepository'.)
(Error while validating the service descriptor 'ServiceType:
KimiaBaseProject.Core.Domain.Courses.Repositories.ICourseCommandRepository
Lifetime: Transient ImplementationType:
KimiaBaseProject.Infrastructures.Data.SqlServer.Courses.Repositories.CourseCommandRepository':
Unable to resolve service for type
'Microsoft.EntityFrameworkCore.DbSet1[KimiaBaseProject.Core.Domain.Courses.Entities.Course]' while attempting to activate 'KimiaBaseProject.Infrastructures.Data.SqlServer.Courses.Repositories.CourseCommandRepository'.) Source=Microsoft.Extensions.DependencyInjection StackTrace: at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable1
serviceDescriptors, ServiceProviderOptions options) at
Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection
services, ServiceProviderOptions options) at
Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection
containerBuilder) at
Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter1.CreateServiceProvider(Object containerBuilder) at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at Microsoft.Extensions.Hosting.HostBuilder.Build() at KimiaBaseProject.Endpoints.WebUI.Program.Main(String[] args) in C:\Users\n.eskandari\Desktop\NedaUnitSelection_3\BaseProject_Core3.1\03. EndPoints\KimiaBaseProject.Endpoints.WebUI\Program.cs:line 17 This exception was originally thrown at this call stack: [External Code] Inner Exception 1: InvalidOperationException: Error while validating the service descriptor 'ServiceType: KimiaBaseProject.Framework.Commands.CommandHandler1[KimiaBaseProject.Core.Domain.Courses.Commands.AddCourseCommand]
Lifetime: Scoped ImplementationType:
KimiaBaseProject.Core.ApplicationServices.Courses.Commands.AddCourseCommandHandler':
Unable to resolve service for type
'Microsoft.EntityFrameworkCore.DbSet1[KimiaBaseProject.Core.Domain.Courses.Entities.Course]' while attempting to activate 'KimiaBaseProject.Infrastructures.Data.SqlServer.Courses.Repositories.CourseCommandRepository'. Inner Exception 2: InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbSet1[KimiaBaseProject.Core.Domain.Courses.Entities.Course]'
while attempting to activate
'KimiaBaseProject.Infrastructures.Data.SqlServer.Courses.Repositories.CourseCommandRepository'.
The Startup.cs is:
namespace KimiaBaseProject.Endpoints.WebUI
{
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.AddLocalization(options => options.ResourcesPath = "Resources");
.AddEntityFrameworkStores<CommandDbContext>()
.AddErrorDescriber<CustomIdentityErrorDescriber>();
services.AddScoped<IdentityErrorDescriber, CustomIdentityErrorDescriber>();
#endregion
services.AddControllersWithViews()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
})
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddKendo();
services.AddSignalR();
services.AddHttpClient();
services.AddMemoryCache();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddDbContext<CommandDbContext>(ServiceLifetime.Transient);
services.AddScoped<QueryDbContext>();
services.AddScoped<IUnitOfWork, CommandDbContext>();
services.AddTransient<IResourceManager, ResourceManager<SharedResource>>();
services.AddAutoMapperConfigService();
services.AddCommandHandlersRegistery(typeof(CommandHandler<>));
services.AddCustomServicesRegistery();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, UserManager<User> userManager)
{
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.UseHttpsRedirection();
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id?}");
endpoints.MapControllerRoute(
name: "area",
pattern: "{area:exists}/{controller}/{action}/{id?}");
});
ApplicationDbInitializer.SeedDefaultUser(userManager);
if (env.IsDevelopment())
{
app.UseSpa(spa =>
{
spa.Options.SourcePath = "AppUi";
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
});
}
else
{
app.UseSpa(spa =>
{
spa.Options.SourcePath = "AppUi";
app.Use(async (context, next) =>
{
context.Request.Path = "/dist/index.html";
await next();
});
});
}
app.UseCors(bulider => bulider.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin());
}
}
}
The CustomServiceRegistraion is:
namespace KimiaBaseProject.Core.IocConfig
{
public static class CustomServiceRegistration
{
public static void AddCustomServicesRegistery(this IServiceCollection services)
{
services.AddTransient<ICourseCommandRepository, CourseCommandRepository>();
services.AddTransient<ICourseQueryRepository, CourseQueryRepository>();
}
}
i have checked the application many times,but i don't understand what is the reason of it.
I am hosting a ASP.net Core API using WindowsService, Its working fine on my local machine, But I am unable to access it on other machines on the same network.
When I am opening the EXE directly through Kestrel, then I am able to listen but when I am hosting it as a WindowsService, I am only able to listen on my local machine but not on other machines on the network.
PS: I am running the WindowsService under my local account
Error on Google Chrome : ERR_CONNECTION_TIMED_OUT
Program.CS
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
var repository = new ServiceRepository();
var certificatePath = ConfigHelper.AppSetting("certPath");
var certificatePassword = repository.Decrypt(ConfigHelper.AppSetting("certPass"));
var certificate = new X509Certificate2(certificatePath, certificatePassword);
return Host.CreateDefaultBuilder(args)
.ConfigureWebHost(webBuilder =>
{
webBuilder.UseKestrel(options =>
{
options.AddServerHeader = false;
options.Listen(IPAddress.Any, 44302, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
options.Listen(IPAddress.Any, 5000);
});
webBuilder.UseStartup<Startup>();
}).UseWindowsService();
}
Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(option =>
{
option.RequireHttpsMetadata = true; //made purposly to test ssl with kestrel
option.TokenValidationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = ConfigHelper.AppSetting("issuer"),
ValidAudience = ConfigHelper.AppSetting("audience"),
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ConfigHelper.AppSetting("secretkey"))),
ClockSkew = TimeSpan.Zero
};
});
services.AddControllers().AddNewtonsoftJson(options =>
{
// Use the default property (Pascal) casing
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddScoped<IApplication, Application>();
services.AddScoped<IServiceRepository, ServiceRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "ServiceNS/{action}");
});
}
The port was getting blocked through firewall, I had to add a inbound rule and specify the port which i was using in my application. This way firewall did not blocked my port for incoming requests.
References:
https://www.firehousesoftware.com/webhelp/FH/Content/FHEnterprise/FHEnterpriseInstallationGuide/24_StaticPort.htm
I am using Ocelot for API gateway with SignalR for real-time data update functionality in Asp.Net Core.
I have created three projects: APIGateway, AspNetCoreAPISignalR, AspNet core Web APP (as a client app)
I have created Message Hub in AspNetCoreAPISignalR project to broadcast messages to clients
Without using an API gateway, I am able to broadcast the messages to all the clients in real-time.
But as I have to use Ocelot as API gateway, I am getting below error - "Cannot send data if the connection is not in the 'Connected' State."
API Gateway configuration file:
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{catchAll}",
"DownstreamScheme": "ws",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 35685
}
],
"UpstreamPathTemplate": "/{catchAll}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE", "OPTIONS" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:44353"
}
}
API Gateway startup file:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(x => true)
.AllowCredentials();
}));
services.AddSignalR();
services.AddOcelot();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
app.UseWebSockets();
app.UseOcelot().Wait();
}
}
Microservice start up file:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed(x => true)
.AllowCredentials());
});
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ServerSignalR", Version = "v1" });
});
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ServerSignalR v1"));
}
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<MessageHub>("/messagehub");
});
}
-----
What can I try next, to get Ocelot and signalR to work together?
I enable all of the enable CORS settings, but some of these methods of request don't still work like Delete, Put.
This is my code
public void ConfigureServices(IServiceCollection services)
{
var appSettings = Configuration.GetSection("ApplicationSettings");
services.Configure<ApplicationSettingsModel>(Configuration.GetSection("ApplicationSettings"));
services.AddOptions();
services.AddControllersWithViews(options => options.UseGeneralRoutePrefix(appSettings.GetValue<string>("apiRoutePrefix") ?? ""));
services.AddMvc(o => { o.UseGeneralRoutePrefix("api/v{version:apiVersion}"); });
services.AddApiVersioning(config =>
{
config.DefaultApiVersion = new ApiVersion(1, 0);
config.AssumeDefaultVersionWhenUnspecified = true;
config.ReportApiVersions = true;
});
services.AddOurAuthentication(Configuration);
services.AddControllers(c => c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()))
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
});
services.AddCors(app =>
{
app.AddPolicy("allowAll", a => a.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowedToAllowWildcardSubdomains());
});
if (_enableSwagger)
services.AddOurSwagger();
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
SwaggerMiddleware(app);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCors("allowAll");
app.UseApiResponseAndExceptionWrapper();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(builder => builder.MapControllers());
}
How can I solve this problem?
You have to change the place of Cors code in your startup. Put this code to the top of ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("AllowAnyOrigins", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
...........
}
app.UseCors should be placed between app.UseRouting() and app.UseAuthorization()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.....
app.UseRouting();
app.UseCors("AllowAnyOrigins");
app.UseAuthentication();
app.UseAuthorization();
....
}
I resolve this.
I change my code to below:
public void ConfigureServices(IServiceCollection services)
{
var appSettings = Configuration.GetSection("ApplicationSettings");
services.Configure<ApplicationSettingsModel>(Configuration.GetSection("ApplicationSettings"));
services.AddOptions();
services.AddControllersWithViews(options => options.UseGeneralRoutePrefix(appSettings.GetValue<string>("apiRoutePrefix") ?? ""));
services.AddMvc(o => { o.UseGeneralRoutePrefix("api/v{version:apiVersion}"); });
services.AddApiVersioning(config =>
{
config.DefaultApiVersion = new ApiVersion(1, 0);
config.AssumeDefaultVersionWhenUnspecified = true;
config.ReportApiVersions = true;
});
services.AddOurAuthentication(Configuration);
services.AddControllers(c => c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()))
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
});
services.AddCors(options =>
{
options.AddPolicy("allowAll",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(s => true)
.SetPreflightMaxAge(TimeSpan.FromMinutes(9))
.AllowCredentials()
.Build());
});
if (_enableSwagger)
services.AddOurSwagger();
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
SwaggerMiddleware(app);
// app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors("allowAll");
app.UseCorsMiddleware();
// app.UseApiResponseAndExceptionWrapper();
app.UseEndpoints(builder => builder.MapControllers());
}
and this code:
public class CorsMiddleware
{
private readonly RequestDelegate Next;
public CorsMiddleware(RequestDelegate next)
{
Next = next;
}
public Task Invoke(HttpContext context)
{
return BeginInvoke(context);
}
private Task BeginInvoke(HttpContext context)
{
context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept, Athorization, ActualUserOrImpersonatedUserSamAccount, IsImpersonatedUser" });
context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
if (context.Request.Method == HttpMethod.Options.Method)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
return context.Response.WriteAsync("OK");
}
return Next.Invoke(context);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CorsMiddleware>();
}
}
Edited from comment suggestion, removed AllowCredentials I noticed OP didn't have that in his code.
Try this, instead of creating a policy, what if you did this:
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true)); // allow any origin
If this works, it's because you were creating a policy and maybe the policy is not applying. But the above should just work without a policy.
You also mention that only some verbs don't work - it's possible that a cors error is masking a 500 exception, the way to test that is, with a 500 (or other) exception, your code will actually get hit, so you can test that with a breakpoint and if your breakpoint gets hit, it's not CORS even though the browser is saying that.
But most likely you were creating a policy, and not applying the policy to the things that aren't working. THe code above is global.
Hi I am working on a class group project and I am responsible for the front-end part. I am a rookie in front-end so I may have made stupid mistakes.
After I got codes in back-end from my partner:
[ApiController]
public class AccountController : ControllerBase
{
public IDBManager_Users _usersManager;
public AccountController(IDBManager_Users usersManager)
{
_usersManager = usersManager;
}
[HttpPost]
[Route("Account/Create")]
public bool CreateUser(User user)
{
bool created = _usersManager.CreateUser(user);
return created;
}
And I put a fetching data request in React to create a user:
register= e => {
e.preventDefault();
fetch(`http://localhost:5001/Account/Create`, {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
email: this.state.email,
password: this.state.password,
userRole: this.state.userRole,
country: this.state.country,
place: this.state.place,
city: this.state.city
})
})
.then((response) => {
if(response){
this.props.history.push('/login')
}
else{
alert('Please Register with Correct Info!');
}
})
.catch(err => console.log(err));
};
I think all other parts go well and I can get my request payload from Chrome like:
{"email":"abc#gmail.com","password":"abc","userRole":"1","country":"United States","place":"NY","city":"whatever"}
but fail with:
POST http://localhost:5001/Account/Create net::ERR_CONNECTION_REFUSED
I do not know what kind of stupid I have made but I really struggled into it.
Waiting for reponse :)
Edit1: If you want to have a look of startup.cs, I have attach it here:
{
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.Add(new ServiceDescriptor(typeof(SqlManager), new SqlManager(Configuration.GetConnectionString("DefaultConnection"))));
services.AddControllersWithViews();
services.AddCors(options =>
{
options.AddPolicy("AllowAllHeaders",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
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: "{controller}/{action=Index}/{id?}");
});
app.UseCors("AllowAllHeaders");
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
You need to change your method signature to map the JSON from the body of the request to the actual DTO object using the FromBody annotation:
public bool CreateUser([FromBody] User user)
Please note that since you didn't provided the code from the Startup.cs I have no idea if something else is missing there in regards of the routing and authorization.
Ref: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#frombody-attribute