我正在构建一个原型,我在同一个项目中托管我的ASP.NET Core网站(标准控制器/视图等)和API。
我希望使用以下路线方案:
到目前为止,我的方法是查看区域,下面的路径配置完美运行:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areaDefault",
template: "{area:exists}/{controller=Values}/{action=Index}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
现在我想扩展它以在访问API时使用一组中间件,在访问网站时使用另一组中间件。实际上,这是在区域之间使用不同的认证设置。 Google-fu引导我使用IApplicationBuilder.Map方法,这就是我的问题所在。
下面的配置适用于默认路由,执行Home / Index但是/ api后面的任何内容都返回404.
// TODO: Add common middleware.
app.Map("/api", builder =>
{
// TODO: Add api specific middleware.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "apiDefault",
template: "api/{controller=Values}/{action=Index}");
});
});
// TODO: Add website specific middleware.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
我尝试过没有成功的路线是:
ValuesController位于Regions / Api / Controllers文件夹下,定义为:
[Area("api")]
public class ValuesController : Controller
{
public IActionResult Index()
{
return Json(new { test = 1 });
}
}
可以在此处找到重现此内容的完整来源:https://github.com/AntSwift/ApiRouteTest
我是否正朝着正确的道路前进,是否有一些明显的我遗失或者是我试图根本不可能的事情。
答案 0 :(得分:2)
我建议采取不同的做法,不要将它们混合在一起。只需创建您的api区域或以您想要的方式使用api路由。然后创建一个中间件并将其命名为" ApiAuthenticationMiddleware"。把它放在配置管道的顶部。在该中间件中查看httpcontext中的不同属性。 httpcontext中有很多有用的值。在你的情况下你可以使用" path"找出要求的地方。
如果路径有" / api /"在里面。这意味着它会进入你的api。否则它将转到您的普通控制器。在这种情况下,您应该短路到管道中的下一步。
再次在您的情况下,您可以在中间件中使用以下代码段作为示例。你应该按照你想要的方式改变它:
public async Task Invoke(HttpContext httpContext, YourDbContext dbContext)
{
string requestPath = httpContext.Request.Path.Value;
if(!requestPath.Contains("/api/"))
await _next.Invoke(httpContext);
string authHeader = httpContext.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
//Extract credentials
// other stuff
// example when no authorization header exists and want to reject.
httpContext.Response.StatusCode = 401; //Unauthorized
return;
// Call the next delegate/middleware in the pipeline
await _next.Invoke(httpContext);
}
}
答案 1 :(得分:0)
选中此处,在地图部分中将app.UseMvc
替换为builder.UseMvc
app.Map("/api", builder =>
{
// TODO: Add api specific middleware.
app.UseMvc(routes => // should be builder.UseMvc(routes
{
routes.MapRoute(
name: "apiDefault",
template: "api/{controller=Values}/{action=Index}");
});
});