简体   繁体   English

ASP.NET 核心 3.1 路由 - API 和 MVC 路由混淆

[英]ASP.NET Core 3.1 Routing - API and MVC Route confusion

I have two controllers in my application.我的应用程序中有两个控制器。 One is an api controller, the other one a mvc controller.一个是 api controller,另一个是 mvc controller。 My routes are like this:我的路线是这样的:

api: /api/account/login api: /api/account/login

mvc: /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!当我在我看来使用 UrlHelper 时,它总是返回 api 路线!

<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?如何让 UrlHelper 在我的视图中返回我的 MVC 路由?

@Url.Action("Login", "Account") => /api/account/login @Url.Action("登录", "帐户") => /api/account/login

Why does this happen?为什么会这样? How can I make the UrlHelper return my MVC route in my views?如何让 UrlHelper 在我的视图中返回我的 MVC 路由?

It seems that by using the Url.Action method, it will auto using the API routing, instead of the MVC routing.似乎通过使用 Url.Action 方法,它将自动使用 API 路由,而不是 MVC 路由。

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.要使 UrlHelper 返回 MVC 视图,您可以使用 Url.RouteUrl() 方法来分配路由名称,或使用 Url.Content() 来设置正确的 ZE6B391A8D2C4D45902A23A8B65D。 Code as below:代码如下:

  1. Using the Url.RouteUrl() method :使用 Url.RouteUrl() 方法

     <form action="@Url.RouteUrl("defaultmvc", new { controller="Account", action = "Login" })" method="post">

    Code in the StartUp.cs: StartUp.cs 中的代码:

     app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "defaultmvc", pattern: "{controller=Home}/{action=Index}/{id?}"); });
  2. Using the Url.Content() method :使用 Url.Content() 方法

     <form action="@Url.Content("~/Account/login")" method="post">

Then, the html resource as below:然后,html 资源如下:

       <form action="/Account/login" method="post">
            ...
        </form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM