Skip to content

MVC Controller POST methods in Blazor Server App returns 405 Method Not Allowed response when running the app via Aspire. #7107

Closed
@AlexHallParcVu

Description

@AlexHallParcVu

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have a POST method Identity/Login in an MVC controller which when called when the project is running via Aspire it returns a 405. However, if I run the project without Aspire then the POST method gets called correctly.

POST method in IdentityController.cs

        //[ValidateAntiForgeryToken]
        [HttpPost]
        [Route("Login")]
        public async Task<IActionResult> Login([FromForm] LoginInputModel model)
        {

       }

Form that calls the action in View/Identity/Login.cshtml:

<form method="post">

I have tried app.UseCors("AllowAll"); but this did not change anything.

Here is the program.cs file, if there is anything I have done wrong here

 var builder = WebApplication.CreateBuilder(args);

 builder.Configuration.SetBasePath(Directory.GetCurrentDirectory());
 builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
 if (args != null)
 {
     builder.Configuration.AddCommandLine(args);
 }
 builder.Configuration.AddEnvironmentVariables();
 builder.Host.UseSerilog((thing, config) => config.ReadFrom.Configuration(builder.Configuration));


 // Create a logger factory to pass to Startup
 using var loggerFactory = LoggerFactory.Create(logging =>
 {
     logging.AddConsole();
     logging.AddDebug();
 });
 var logger = loggerFactory.CreateLogger<Program>();
 var startup = new Startup(builder.Configuration, builder.Environment);
 startup.ConfigureServices(builder.Services);
 builder.Services.AddDevExpressServerSideBlazorPdfViewer();
 builder.AddServiceDefaults();
 builder.Services.AddCors(options =>
   {
       options.AddPolicy("AllowAll",
       builder =>
       {
           builder.AllowAnyOrigin()
                  .AllowAnyHeader()
                  .AllowAnyMethod();
       });
   });

 
 var app = builder.Build();
 
 if (app.Environment.IsDevelopment())
 {
     logger.LogInformation("In Development environment");
     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.MapDefaultEndpoints();
 var metaOptions = app.Configuration.GetSection("AppMetaOptions").Get<MetaOptions>();
 app.UsePathBase(metaOptions.BasePath);
 //this might get around the problem with the website not working when the user doesnt enter www,
 //but then again it might just break everything, we wont find out till we do an install
 //app.UseRewriter(new RewriteOptions().AddRedirectToWww().AddRedirectToHttps());

 app.UseHttpsRedirection();

 app.MapStaticAssets();
 app.MapRazorPages();
 app.MapRazorComponents<App>()
     .AddInteractiveServerRenderMode();

 app.UseAntiforgery();

 app.UseCookiePolicy();
 app.UseCors("AllowAll");

 app.UseAuthentication();
 app.UseAuthorization();

 // middleware that reads and sets the tenant
 app.UseMiddleware<MultiTenantContextServiceMiddleware>();

 app.MapDashboardRoute("api/dashboard", "DefaultDashboard");
 app.MapControllers();
 app.MapHealthChecks("/healthz");
 app.MapPost("/LogOut", async
     (ClaimsPrincipal user,
     [FromQuery] string returnUrl,
     HttpContext HttpContext,
     AuthStateCache Cache
     ) =>
 {
     if (user.Identity.IsAuthenticated)
     {
         var issuer = user.Claims.FirstOrDefault(x => x.Type == IdentityModel.JwtClaimTypes.SessionId)?.Issuer;
         var sid = user.Identity.GetSubjectId();


         if (sid != null && Cache.HasSubjectId(issuer, sid))
         {
             Cache.Remove(issuer, sid);
         }
     }
     //await HttpContext.SignOutAsync(Constants.CookieSchemes.AuthenticationScheme);
     //await HttpContext.SignOutAsync(Constants.CookieSchemes.OidcChallengeScheme, authProps);
     await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
     // TODO TODDO TODO: other schemes???
     return TypedResults.LocalRedirect($"~/Login?RetUrl={returnUrl}");
 });

 app.MapGet("/Login", ([FromQuery] string RetUrl, HttpContext httpContext) =>
 {
     var authProps = new AuthenticationProperties
     {
         IsPersistent = true,
         ExpiresUtc = DateTimeOffset.UtcNow.AddHours(20),
         RedirectUri = string.IsNullOrEmpty(RetUrl) ? "/" : RetUrl
     };
     //var result = Challenge(authProps, Constants.CookieSchemes.OidcChallengeScheme);
     var result = TypedResults.Challenge(authProps, [CookieAuthenticationDefaults.AuthenticationScheme]);
     return result;
 });




 app.Run();

Expected Behavior

I would expect the POST method to be called correctly, as it does without running with Aspire.

Steps To Reproduce

  1. Add MVC Controller with POST method. Call the POST method from a View via .
  2. Run using iisExpress without Aspire and see that method gets called correctly
  3. Run using Aspire and see that a 405 if returned.

Exceptions (if any)

405 Method not allowed.

.NET Version info

.NET 9

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-app-modelIssues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions