【问题标题】:ASP.NET Core 3.1 Routing - API and MVC Route confusionASP.NET Core 3.1 路由 - API 和 MVC 路由混淆
【发布时间】:2020-10-31 12:27:25
【问题描述】:

我的应用程序中有两个控制器。一个是 api 控制器,另一个是 mvc 控制器。 我的路线是这样的:

api:/api/account/login

mvc:/account/login

我的控制器:

[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");
    }
}

我的服务集合:

//...
services.Configure<RouteOptions>(options => options.LowercaseUrls = true);
services.AddControllersWithViews()
//...

我的管道是这样的:

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
});

现在我的实际问题:

当我在视图中使用 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

  • 为什么会这样?
  • 如何让 UrlHelper 在我的视图中返回我的 MVC 路由?

【问题讨论】:

  • 一些有趣的答案可能不是您遇到的问题,但非常相似的主题stackoverflow.com/q/56074002/8065832
  • 可以尝试制作两个控制器,不同的名称,看看会发生什么,也可以尝试添加 services.AddControllers();
  • 我认为它只是找到了第一个匹配的路线。
  • @apocalypse 是的,但是有人知道一种通过 urlhelper 在视图中强制 mvc 路由的方法,还是我应该实现自己的? :
  • 嗯,可能会在 Route 属性中添加“路由名称”。然后在表单中使用标签助手。像

标签: c# asp.net-core routes asp.net-routing


【解决方案1】:

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

为什么会这样?如何让 UrlHelper 返回我的 MVC 路由 在我看来?

似乎通过使用 Url.Action 方法,它会自动使用 API 路由,而不是 MVC 路由。

要使 UrlHelper 返回 MVC 视图,您可以使用 Url.RouteUrl() 方法分配路由名称,或使用 Url.Content() 设置正确的 URL。代码如下:

  1. 使用 Url.RouteUrl() 方法

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

    StartUp.cs 中的代码:

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

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

那么,html资源如下:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2021-01-29
    • 2020-11-15
    • 1970-01-01
    相关资源
    最近更新 更多