I have two controllers in my application. One is an api controller, the other one a mvc controller. My routes are like this:
api: /api/account/login
mvc: /account/login
My controllers:
[ApiController]
[Route("api/[controller]")]
public class AccountController : ControllerBase
{
private readonly IMediator _mediator;
public AccountController(
IMediator mediator)
{
_mediator = mediator;
}
[HttpPost("login")]
public async Task<AuthenticationResultViewModel> Login(LoginRequest loginData, CancellationToken cancellationToken)
=> await _mediator.Send(loginData, cancellationToken);
}
// this one's in a different namespace
[Route("[controller]")]
public class AccountController : Controller
{
private readonly IMediator _mediator;
public AccountController(
IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("login")]
public IActionResult Login([FromQuery] string r)
=> View();
[HttpPost("login")]
public async Task<IActionResult> Login([FromQuery] string r, [FromForm] LoginRequest login, CancellationToken cancellationToken)
{
await _mediator.Send(login, cancellationToken);
if (!string.IsNullOrWhiteSpace(r))
return Redirect(r);
return RedirectToAction("Index", "Home");
}
}
My ServiceCollection:
//...
services.Configure<RouteOptions>(options => options.LowercaseUrls = true);
services.AddControllersWithViews()
//...
My pipeline is this:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseCors();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// here i tried defining my routes
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// I have tried the following without success
// I'm actually lost :'(
//endpoints.MapControllerRoute("mvc", "{controller}/{action}/{id?}", new { controller = "Home", action = "Index" });
//endpoints.MapControllerRoute("api", "api/{controller}/{action}/{id?}");
});
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.All,
RequireHeaderSymmetry = false
});
Now my actual problem:
When I use the UrlHelper in my view it always returns the api route!
<form action="@Url.Action("Login", "Account")" method="post">
<div class="form-group">
<input asp-for="Username" type="text" placeholder="Username" />
</div>
<div class="form-group">
<input asp-for="Password" type="password" placeholder="Password"/>
</div>
<div class="form-group">
<button type="submit">Login</button>
</div>
</form>
@Url.Action("Login", "Account")
=> /api/account/login
@Url.Action("Login", "Account") => /api/account/login
Why does this happen? How can I make the UrlHelper return my MVC route in my views?
It seems that by using the Url.Action method, it will auto using the API routing, instead of the MVC routing.
To make the UrlHelper return the MVC view, you could use the Url.RouteUrl() method to assign the route Name, or using Url.Content() to set the correct URL. Code as below:
Using the Url.RouteUrl() method:
<form action="@Url.RouteUrl("defaultmvc", new { controller="Account", action = "Login" })" method="post">
Code in the StartUp.cs:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "defaultmvc",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Using the Url.Content() method:
<form action="@Url.Content("~/Account/login")" method="post">
Then, the html resource as below:
<form action="/Account/login" method="post">
...
</form>