Home > Back-end >  ASP.NET MVC Core Html.BeginForm() always links to first Action in Controller
ASP.NET MVC Core Html.BeginForm() always links to first Action in Controller

Time:09-05

I have a problem with the Html.BeginForm() function, where every time I press the OkButton submit in _Prijava.cshtml, it runs the Prijava() Action in the Controller.

This is the LoginController.cs:

namespace BumCoreWebAppMVC.Controllers
{
    [Route("[controller]/[action]")]
    public class LoginController : Controller
    {
        [HttpGet] 
        [Route("/bum/Prijava.cshtml")]   
        public IActionResult Prijava()
        {
            var model = new LoginViewModel();
            return View("Prijava", model);
        }

        [HttpPost]
        public IActionResult OkButton(LoginViewModel model)
        {
            //...
            return View("Index");
        }
    }
}

This is the view Prijava.cshtml

@model BumCoreWebAppMVC.Models.LoginViewModel
@{
    ViewData["TitleHeader"] = "Prijava";
    Layout = "./BumLayout";
}
<!-- ... -->
@await Html.PartialAsync("/Views/Login/_Prijava.cshtml", Model)
<!-- ... -->

This is the partial view _Prijava.cshtml

@model BumCoreWebAppMVC.Models.LoginViewModel
@{}
@using (Html.BeginForm("OkButton", "Login", FormMethod.Post)){
    @Html.TextBoxFor(p => p.TextBox_ID, new {@, placeholder = "ID"})       
    <button type="submit">Submit</button>
}

From what i've seen this should be work. I have a suspicion that maybe my Program.cs isn't correctly set:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<HttpContextAccessor>();
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    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.UseCookiePolicy();
app.UseSession();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();

app.Run();

The strange thing is if I change the OkButton() Action to [HttpGet] and use @Html.ActionLink("Submit", "OkButton", "Login") it works just fine and it can find the correct Action. However the Html.BeginForm("OkButton", "Login", FormMethod.Get) will still not be able to run it.

CodePudding user response:

This is because you are not set the Attribute Routing in RouteConfig.cs file.

Inside Solution Explorer navigate to App_Start folder and open RouteConfig.cs file.

Add the following line bellow routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); line

routes.IgnoreRoute...;
routes.MapMvcAttributeRoutes();

Final Step: Don't use a trailing slash at the beginning of a Route attribute. Replace your route with this line

[Route("bum/Prijava.cshtml")]

Demonstration Video

CodePudding user response:

I've found the most mind boggling solution.

It appears that the first @using (Html.BeginForm()) will always call the wrong Action but the next ones will work correctly. So simply adding @using (Html.BeginForm()){ } at the top of the _Prijava.cshtml page will make the other ones work.

  • Related