ASP.NET Core 3.1 路由 - API 和 MVC 路由混淆
ASP.NET Core 3.1 Routing - API and MVC Route confusion
我的应用程序中有两个控制器。一个是 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 时,它总是 return 是 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 return 在我的视图中成为我的 MVC 路由?
@Url.Action("Login", "Account") => /api/account/login
Why does this happen? How can I make the UrlHelper return my MVC route
in my views?
似乎通过使用 Url.Action 方法,它将自动使用 API 路由,而不是 MVC 路由。
要使 UrlHelper return 成为 MVC 视图,您可以使用 Url.RouteUrl() 方法分配路由名称,或使用 Url.Content() 设置正确的 URL。代码如下:
使用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?}");
});
使用Url.Content()方法:
<form action="@Url.Content("~/Account/login")" method="post">
那么,html资源如下:
<form action="/Account/login" method="post">
...
</form>
我的应用程序中有两个控制器。一个是 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 时,它总是 return 是 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 return 在我的视图中成为我的 MVC 路由?
@Url.Action("Login", "Account") => /api/account/login
Why does this happen? How can I make the UrlHelper return my MVC route in my views?
似乎通过使用 Url.Action 方法,它将自动使用 API 路由,而不是 MVC 路由。
要使 UrlHelper return 成为 MVC 视图,您可以使用 Url.RouteUrl() 方法分配路由名称,或使用 Url.Content() 设置正确的 URL。代码如下:
使用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?}"); });
使用Url.Content()方法:
<form action="@Url.Content("~/Account/login")" method="post">
那么,html资源如下:
<form action="/Account/login" method="post">
...
</form>