Web API
58 TopicsReact website with ASP.NET and IIS : API not working
Hi, I have found a lot of similar issues on the web but none was working for me, and I am so desperate after days so I am posting here and hope someone can help. I have an ASP.NET server that serves a React website, and also works as an API for the website itself. The server runs on a Windows 11 PC with IIS, in C:/MyWebSite. This folder contains the ASP.NET server (.exe, .dll, etc), the IIS configuration (web.config) and the build React website (index.html, favicon.ico and assets folder). The server succeed to show my main page, but it fails doing an API request. The API request fails as well when I call it from Postman, and gives me the error "HTTP 404.0 - Not Found" with these details : Module IIS Web Core Notification : MapRequestHandler Handler : StaticFile Error code : 0x80070002 FYI, the request is GET http://localhost:5058/api/configuration/settings Concerning ASP.NET, here is my Program.cs : using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; // Create the web application builder var builder = WebApplication.CreateBuilder(args); // JWT authentication builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { string? tKey = builder.Configuration["Jwt:Key"]; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = tKey != null ? new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tKey)) : null }; }); // Add the controllers to the application (for input http requests) builder.Services.AddControllers(); // Configure CORS policy builder.Services.AddCors(options => { options.AddPolicy("AllowAllOrigins", builder => { builder.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); // Create the App var app = builder.Build(); // Applies the CORS policy app.UseCors("AllowAllOrigins"); // Serving the static files app.UseDefaultFiles(); app.UseStaticFiles(); app.UseRouting(); // Map the routes to the controllers app.MapControllers(); // Undefined route will lead to index.html app.MapFallbackToFile("index.html"); // Run the App app.Run(); Of course, I have created some controllers, here is ConfigurationController.cs for example : using Microsoft.AspNetCore.Mvc; namespace AspReact.Server.Controllers { [ApiController] [Route("api/configuration")] public class GeneralController : ControllerBase { [HttpGet("settings")] public ActionResult GetSettings() { return Ok(new { language = 'fr', theme = 0 }); } [HttpPost("settings")] public ActionResult SetSettings([FromQuery] string language, [FromQuery] string theme) { m_tLanguage = language; m_tTheme = theme; return Ok(); } } } Here is my IIS configuration : <?xml version="1.0"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="React Routes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" /> </conditions> <action type="Rewrite" url="/" /> </rule> </rules> </rewrite> </system.webServer> </configuration> NB : At first I was not doing : <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" /> And the API request was returning the content of index.html... If it can help. Please note that all this is working during development with the server running in a debug console. I would be grateful for any help! Thanks.Solved87Views0likes2CommentsMultiple ASP.NET Core Web API instances runs only once
I have an ASP.NET Core 8.0 Web API hosted on two IIS applications (app-1 and app-2) under the Default Web Site on a Windows 11 OS. Both IIS applications point to the same physical path (inetpub\wwwroot\myapp) and each application has its own dedicated application pool (app1andapp2). The application pools have unique identities (app1svcandapp2svc), both of which are members of the Administrators group. In the Web API, I have anAppEventsclass implementingIHostedService, withStartAsyncandStopAsyncmethods to handle application start and stop events. In theProgram.cs, I register it usingbuilder.Services.AddHostedService<AppEvents>(). When accessinghttp://localhost/app-1, theStartAsyncmethod is triggered as expected. However, when accessinghttp://localhost/app-2, theStartAsyncmethod does not execute. It seems that the application starts only once, despite both IIS apps pointing to the same physical directory. I've tried changing theAspNetHostingModelfromInProcesstoOutOfProcess, but the behavior remains the same. Is there a way to deploy multiple instances of the same web app, each running separately but pointing to the same physical directory, so that each instance correctly triggers its own StartAsync?26Views0likes0CommentsIs it possible to run a asp.net core site within testing?
Hi! I'm trying to write tests for a small minimal API based on asp.net core. I don't want to test over the internet, but start the app within the tests and call the endpoints on the running site. Is this possible? And how? Should I use TestServer for this? I'm new to writing tests, so maybe it's an easy issue to code. Thanks! :)12Views0likes0CommentsMacos dotnet wacth https not working.
Hello; I wanted to start Asp.net core Angular training. I am a Macos M1 user. I installed the necessary plugins with Vscode and created a webapi. But the api does not work with the dotnet watch command. It says the reason is https certificate problem. launchSettings.json : { "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "applicationUrl": "http://localhost:5000;https://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } applicationUrl also only works when it is http. In the error command: Microsoft.Extensions.Hosting.Internal.Host[11] Hosting failed to start System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date. To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'. There is a long error like this. I enter the following commands in the terminal, in order: 1- dotnet dev-certs https 2- dotnet dev-certs https --trust I approve the certificate. When I say 3-dotnet dev-certs https --check, I get the error: No valid certificate found. I found the localhost certificates in Keychain Access and selected the always trust option. But I couldn't find a solution. Also: dotnet dev-certs https --trust Trusting the HTTPS development certificate was requested. If the certificate is not already trusted we will run the following command: 'security add-trusted-cert -p basic -p ssl -k <<login-keychain>> <<certificate>>' This command might prompt you for your password to install the certificate on the keychain. There is an addition process like To undo these changes: 'security remove-trusted-cert <<certificate>>' I didn't know how to do it. Can you help me with this?124Views0likes0Comments.NET Web API CancellationToken don't work with Angular .unsuscribe()?
In Angular, I make API calls by subscribing to observables. When a user cancels a request, the application unsubscribes to the subscription which cancels the request (I can see this in the network tab of the Chrome browser). However, it does not trigger the endpoint and so the cancellation token param in our endpoint is of no use. Is there a way around this? I need the cancellation token to cancel all database request.207Views0likes2CommentsIssue with Authentication
If anyone can give me a clue as to where I am going wrong. I have slowly been upgrading my code base from .NET 6 to .NET 8. With my authorization controller, in the authorize method with .NET 6 this line of code var results = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme) would return null or not succeed.I would then hit the Login Razor Page and Sign In, the same result would then be an actual `AuthenticateResult`. With the upgrade to .NET 8, it always returns null even after I sign in. I have looked with the Dev Tools open and I can see that the sign in does generate a cookie. I am testing this from Postman using the authorization tab in there and using all the correct parameters. Here is what is not changed from .NET 6 to .NET 8: Authorize method: [HttpGet(Name = nameof(Authorize))] [HttpPost(Name = nameof(Authorize))] [IgnoreAntiforgeryToken] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task<IActionResult> Authorize() { var request = HttpContext.GetOpenIddictServerRequest() ?? throw new InvalidOperationException("The OpenID Connect request cannot be retrieved."); // Retrieve the user principal stored in the authentication cookie. // If it can't be extracted, redirect the user to the login page. var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme); if (result == null || !result.Succeeded) { if (request.HasPrompt(Prompts.None)) { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in." })); } return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create( Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList()) }); } if (request.HasPrompt(Prompts.Login)) { var prompt = string.Join(" ", request.GetPrompts().Remove(Prompts.Login)); var parameters = Request.HasFormContentType ? Request.Form.Where(parameter => parameter.Key != Parameters.Prompt).ToList() : Request.Query.Where(parameter => parameter.Key != Parameters.Prompt).ToList(); parameters.Add(KeyValuePair.Create(Parameters.Prompt, new StringValues(prompt))); return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters) }); } if (request.MaxAge != null && result.Properties.IssuedUtc != null && DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value)) { if (request.HasPrompt(Prompts.None)) { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in." })); } return Challenge( authenticationSchemes: IdentityConstants.ApplicationScheme, properties: new AuthenticationProperties { RedirectUri = Request.PathBase + Request.Path + QueryString.Create( Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList()) }); } var user = await _userManager.GetUserAsync(result.Principal) ?? throw new InvalidOperationException("The user details cannot be retrieved"); var application = await _applicationManager.FindByClientIdAsync(request.ClientId) ?? throw new InvalidOperationException("Details concerning the calling client application cannot be found"); var permissionsArray = await _applicationManager.GetPermissionsAsync(application); var scopes = permissionsArray.Where(a => a.StartsWith("scp:")).Select(a => a[4..]).ToList().ToImmutableArray(); var authorizations = await _authorizationManager.FindAsync( subject: await _userManager.GetUserIdAsync(user), client: await _applicationManager.GetIdAsync(application), status: Statuses.Valid, type: AuthorizationTypes.Permanent, scopes: scopes).ToListAsync(); switch (await _applicationManager.GetConsentTypeAsync(application)) { case ConsentTypes.External when !authorizations.Any(): return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The logged in user is not allowed to access this client." })); case ConsentTypes.Implicit: case ConsentTypes.External when authorizations.Any(): case ConsentTypes.Explicit when authorizations.Any() && !request.HasPrompt(Prompts.Consent): var principal = await _signInManager.CreateUserPrincipalAsync(user); principal.SetScopes(scopes); principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); var authorization = authorizations.LastOrDefault(); if (authorization == null) { authorization = await _authorizationManager.CreateAsync( principal: principal, subject: await _userManager.GetUserIdAsync(user), client: await _applicationManager.GetIdAsync(application), type: AuthorizationTypes.Permanent, scopes: principal.GetScopes()); } principal.SetAuthorizationId(await _authorizationManager.GetIdAsync(authorization)); foreach (var claim in principal.Claims) { claim.SetDestinations(GetDestinations(claim, principal)); } return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); case ConsentTypes.Explicit when request.HasPrompt(Prompts.None): case ConsentTypes.Systematic when request.HasPrompt(Prompts.None): return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary<string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Interactive user consent is required." })); default: return View(new AuthorizeViewModel { ApplicationName = await _applicationManager.GetDisplayNameAsync(application), Scope = string.Join(" ", scopes) }); } } Login page: [AllowAnonymous] public class LoginModel : PageModel { private readonly ApplicationUserManager _userManager; private readonly SignInManager<ApplicationUsers> _signInManager; private readonly ILogger<LoginModel> _logger; public LoginModel(SignInManager<ApplicationUsers> signInManager, ILogger<LoginModel> logger, ApplicationUserManager userManager) { _userManager = userManager; _signInManager = signInManager; _logger = logger; } [BindProperty] public InputModel Input { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } public string ReturnUrl { get; set; } [TempData] public string ErrorMessage { get; set; } public class InputModel { //Snipped fro brevity } public async Task OnGetAsync(string returnUrl = null) { if (!string.IsNullOrEmpty(ErrorMessage)) { ModelState.AddModelError(string.Empty, ErrorMessage); } returnUrl ??= Url.Content("~/"); // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); ReturnUrl = returnUrl; } public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); if (ModelState.IsValid) { var user = await _userManager.FindByNameAsync(Input.Email); if (user != null) { if (!await _signInManager.CanSignInAsync(user) || (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user))) { _logger.LogInformation("Login was unsuccessful through controller"); } if (!await _userManager.CheckPasswordAsync(user, Input.Password)) { _logger.LogInformation("Login was unsuccessful through controller"); await _userManager.AccessFailedAsync(user); } if (_userManager.SupportsUserLockout) { await _userManager.ResetAccessFailedCountAsync(user); } var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } return Page(); } } Here is what I have changed in the .NET 6 to .NET 8 basically a move from `startup.cs` to `program.cs`: .NET 6 `startup.cs`: public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("Policy", builder => { builder.WithOrigins(Configuration.GetSection("Cors:Origins").GetChildren().Select(c => c.Value).ToArray()) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); services.AddControllers(); services.AddRazorPages(); services.AddDbContext<IdentDbContext>(options => { options.UseSqlServer( Configuration.GetConnectionString("IdentityDB")); options.UseOpenIddict(); }); services.AddDataProtection() .PersistKeysToDbContext<IdentDbContext>() .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) .SetApplicationName("Applications"); services.AddIdentity<ApplicationUsers, ApplicationRoles>() .AddEntityFrameworkStores<IdentDbContext>() .AddUserStore<ApplicationUserStore>() .AddRoleStore<ApplicationRoleStore>() .AddRoleManager<ApplicationRoleManager>() .AddUserManager<ApplicationUserManager>() .AddErrorDescriber<ApplicationIdentityErrorDescriber>() .AddDefaultTokenProviders() .AddDefaultUI(); services.Configure<IdentityOptions>(options => { options.ClaimsIdentity.UserNameClaimType = Claims.Name; options.ClaimsIdentity.UserIdClaimType = Claims.Subject; options.ClaimsIdentity.RoleClaimType = Claims.Role; // Configure the options for the Identity Account options.SignIn.RequireConfirmedEmail = true; options.SignIn.RequireConfirmedAccount = true; options.User.RequireUniqueEmail = true; options.Lockout.MaxFailedAccessAttempts = 3; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); }); services.Configure<SecurityStampValidatorOptions>(options => { options.ValidationInterval = TimeSpan.FromSeconds(1); }); services.AddQuartz(options => { options.UseMicrosoftDependencyInjectionJobFactory(); options.UseSimpleTypeLoader(); options.UseInMemoryStore(); }); services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); services.AddOpenIddict() // Register the OpenIddict core components. .AddCore(options => { options.UseEntityFrameworkCore() .UseDbContext<IdentDbContext>(); options.UseQuartz(); }) // Register the OpenIddict server components. .AddServer(options => { options.SetAuthorizationEndpointUris("/api/Authorization/Authorize") .SetTokenEndpointUris("/Token") .SetIntrospectionEndpointUris("/Introspect") .SetUserinfoEndpointUris("/api/Userinfo/Userinfo") .SetVerificationEndpointUris("/Verify"); options.RegisterScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles); options.UseReferenceAccessTokens() .UseReferenceRefreshTokens() .UseDataProtection(); options.AllowClientCredentialsFlow() .AllowAuthorizationCodeFlow() .RequireProofKeyForCodeExchange() .AllowRefreshTokenFlow(); if (_env.IsDevelopment()) { options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); } else if (_env.IsProduction() || _env.IsStaging()) { options.AddSigningCertificate(Configuration.GetSection("CertifcateThumbprints:SigningCertificate").Value) .AddEncryptionCertificate(Configuration.GetSection("CertifcateThumbprints:EncryptionCertificate").Value); } options.UseAspNetCore() .EnableAuthorizationEndpointPassthrough() .EnableTokenEndpointPassthrough() .EnableStatusCodePagesIntegration() .EnableUserinfoEndpointPassthrough() .EnableVerificationEndpointPassthrough(); }) // Register the OpenIddict validation components. .AddValidation(options => { options.UseLocalServer(); options.UseDataProtection(); options.UseSystemNetHttp(); options.UseAspNetCore(); }); services.AddSwaggerGen(swagger => { swagger.OperationFilter<SwaggerDefaultValues>(); swagger.OperationFilter<AuthenticationRequirementOperationFilter>(); swagger.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swagger.IncludeXmlComments(xmlPath); }); services.AddApiVersioning(); services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "'v'VVVV"; options.DefaultApiVersion = ApiVersion.Parse("0.10.alpha"); options.AssumeDefaultVersionWhenUnspecified = true; }); services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); if (_env.IsDevelopment()) { services.AddHostedService<TestData>(); } else if (_env.IsStaging() || _env.IsProduction()) { services.AddHostedService<ProdStageSeed>(); } } public void Configure(IApplicationBuilder app, IApiVersionDescriptionProvider provider) { if (_env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseStatusCodePagesWithReExecute("/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.UseCors("Policy"); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.DisplayOperationId(); var versionDescription = provider.ApiVersionDescriptions; foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(_ => _.ApiVersion)) { c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"API {description.GroupName}"); } }); app.UseSerilogRequestLogging(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); }); } .NET 8 `program.cs`: builder.Services.AddCors(options => { options.AddPolicy("Policy", opt => { opt.WithOrigins(builder.Configuration.GetSection("Cors:Origins").GetChildren().Select(c => c.Value).ToArray()!) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); builder.Services.AddControllersWithViews() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new EntityIdJsonConverterFactory()); }); builder.Services.AddRazorPages(); builder.Services.AddDbContext<IdentDbContext>(options => { options.UseSqlServer( builder.Configuration.GetConnectionString("IdentityDB")); options.UseOpenIddict(); }); builder.Services.AddDataProtection() .PersistKeysToDbContext<IdentDbContext>() .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) .SetApplicationName("Applications"); builder.Services.AddIdentity<ApplicationUsers, ApplicationRoles>() .AddEntityFrameworkStores<IdentDbContext>() .AddUserStore<ApplicationUserStore>() .AddRoleStore<ApplicationRoleStore>() .AddRoleManager<ApplicationRoleManager>() .AddUserManager<ApplicationUserManager>() .AddErrorDescriber<ApplicationIdentityErrorDescriber>() .AddDefaultTokenProviders() .AddDefaultUI(); builder.Services.Configure<IdentityOptions>(options => { options.ClaimsIdentity.UserNameClaimType = Claims.Name; options.ClaimsIdentity.UserIdClaimType = Claims.Subject; options.ClaimsIdentity.RoleClaimType = Claims.Role; options.SignIn.RequireConfirmedEmail = true; options.SignIn.RequireConfirmedAccount = true; options.User.RequireUniqueEmail = true; options.Lockout.MaxFailedAccessAttempts = 3; options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); }); builder.Services.Configure<SecurityStampValidatorOptions>(options => { options.ValidationInterval = TimeSpan.FromSeconds(1); }); builder.Services.AddQuartz(options => { options.UseSimpleTypeLoader(); options.UseInMemoryStore(); }); builder.Services.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); builder.Services.AddOpenIddict() // Register the OpenIddict core components. .AddCore(options => { options.UseEntityFrameworkCore() .UseDbContext<IdentDbContext>(); options.UseQuartz(); }) // Register the OpenIddict server components. .AddServer(options => { options.SetAuthorizationEndpointUris("api/Authorization/Authorize") .SetTokenEndpointUris("Token") .SetIntrospectionEndpointUris("Introspect") .SetUserinfoEndpointUris("api/Userinfo/Userinfo") .SetVerificationEndpointUris("Verify"); options.RegisterScopes(Scopes.OpenId, Scopes.Email, Scopes.Profile, Scopes.Roles); options.UseReferenceAccessTokens() .UseReferenceRefreshTokens() .UseDataProtection(); options.AllowClientCredentialsFlow() .AllowAuthorizationCodeFlow() .RequireProofKeyForCodeExchange() .AllowRefreshTokenFlow(); if (builder.Environment.IsDevelopment()) { options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); } else if (builder.Environment.IsProduction() || builder.Environment.IsStaging()) { options.AddSigningCertificate(builder.Configuration.GetSection("CertifcateThumbprints:SigningCertificate").Value!) .AddEncryptionCertificate(builder.Configuration.GetSection("CertifcateThumbprints:EncryptionCertificate").Value!); } options.UseAspNetCore() .EnableAuthorizationEndpointPassthrough() .EnableTokenEndpointPassthrough() .EnableStatusCodePagesIntegration() .EnableUserinfoEndpointPassthrough() .EnableVerificationEndpointPassthrough(); }) // Register the OpenIddict validation components. .AddValidation(options => { options.UseLocalServer(); options.UseDataProtection(); options.UseSystemNetHttp(); options.UseAspNetCore(); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(swagger => { swagger.OperationFilter<SwaggerDefaultValues>(); swagger.OperationFilter<AuthenticationRequirementOperationFilter>(); swagger.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // Set the comments path for the Swagger JSON and UI. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); swagger.IncludeXmlComments(xmlPath); }); builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(0, 10, "alpha"); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; }).AddMvc() .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVVV"; options.SubstituteApiVersionInUrl = false; }); builder.Services.AddApplication() .AddInfrastructure(builder.Configuration) .AddDataLibrary(); builder.Services.AddHttpClient("Login", sp => { sp.BaseAddress = new Uri(builder.Configuration.GetSection("BaseAddresses:Api").Value!); }); builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); if (builder.Environment.IsDevelopment()) { builder.Services.AddHostedService<TestData>(); builder.Services.AddHostedService<ProdStageSeed>(); } else if (builder.Environment.IsStaging() || builder.Environment.IsProduction()) { builder.Services.AddHostedService<ProdStageSeed>(); } builder.Host.UseWolverine(opts => { opts.PersistMessagesWithSqlServer(builder.Configuration.GetConnectionString("IdentityDB")!); opts.UseEntityFrameworkCoreTransactions(); opts.Policies.AutoApplyTransactions(); opts.Policies.UseDurableLocalQueues(); opts.Discovery.IncludeAssembly(Assembly.Load("IdentityApplication")); opts.UseFluentValidation(); opts.Services.AddResourceSetupOnStartup(); opts.OnException<SqlException>().MoveToErrorQueue(); }); builder.Services.AddTransient<ExceptionMiddleware>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>(); app.UseSwaggerUI(c => { c.DisplayOperationId(); var versionDescription = provider.ApiVersionDescriptions; foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(_ => _.ApiVersion)) { c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"API {description.GroupName}"); } }); } else { app.UseStatusCodePagesWithReExecute("/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.UseCors("Policy"); app.UseSerilogRequestLogging(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<ExceptionMiddleware>(); app.MapRazorPages(); app.MapControllers(); app.Run(); So with the minimal change I made I cannot figure out why the result is always returning null. A cookie is generated by the Login Page and does show up in program and Postman. I understand that the AuthenticateAsync changed in .NET 7 but I cannot find any good documentation as to what might be affected in my code. Not sure what the cause is, but I have been stuck on this for over a coupe of weeks.149Views0likes0CommentsCustomer portal application using .NET, Microsoft 365 and Microsoft Graph
Hello, I want to develop an customer portal application using .NET, Microsoft 365 and Microsoft Graph. I want to retrieve information from SharePoint lists where there's the information I want to show customers (bookings, invoices, etc.). Customers don't have Microsoft 365 account so my idea is to use my credentials for retrieving the information from M365 and use Identity Framework for identify them filter queries. I am not sure this is possible, specially the fact of using my credentials for connecting to Microsoft 365. I really appreciate any suggestion or previous experience that you share. Thanks, Regards599Views0likes4CommentsDockerize App based .NET Framework 4.6.1
I have a Rest API based on .Net framework 4.6.1 I want to dockerize this API, but the problem is that I can't find a solution? All the solutions I found are almost all dedicated to other versions, for example, version 4.6.2, 4.7.0 etc. Can anyone recommend me the base image that I can use to build this application? I used mcr.microsoft.com/dotnet/framework/aspnet:4.8 but it is not suitable for my project.114Views0likes0CommentsHow to post using jquery to asp.net core api
I'm trying to develop a simple app to post to an api using jquery. I've tried multiple online suggestions and none of them work. I've even tried some of the AI code without success. I can get GET to reply back with data but POST is just not working. Going on my 3rd day on this. Please help. This is my api code: This is what I'm trying. Thanks for your time.233Views0likes1CommentDeploy an application that uses BackgroundService on IIS
As the title suggests, I have a webapi project deployed on IIS. The project has a simple timed background task that needs to be executed in the early hours of the day. I used BackgroundService to develop this functionality, I checked the execution logs and found that this background task was not executed correctly during this time, the strange thing is that it is always triggered correctly in the development environment. Later I realized that it should be related to the Idle Time-out of the IIS application pool. In the early hours of the morning, my site is not visited, so the site should be “hibernated”, so my background task can not be triggered correctly. I can only deploy the site using IIS, but I still need the background tasks, what should I do?274Views0likes0Comments