Asp.Net 核心区域路由到 Api 控制器不工作
Asp.Net Core Area routing to Api Controller not working
我有一个 API 控制器托管在一个区域中。但是,路由似乎不起作用,因为我的 ajax 调用在尝试执行控制器操作时不断返回 404。永远不会命中控制器构造函数中的断点。
[Area("WorldBuilder")]
[Route("api/[controller]")]
[ApiController]
public class WorldApiController : ControllerBase
{
IWorldService _worldService;
IUserRepository _userRepository;
public WorldApiController(IWorldService worldService, IUserRepository userRepository)
{
_worldService = worldService;
_userRepository = userRepository;
}
[HttpGet]
public ActionResult<WorldIndexViewModel> RegionSetSearch()
{
string searchTerm = null;
var userId = User.GetUserId();
WorldIndexViewModel model = new WorldIndexViewModel();
IEnumerable<UserModel> users = _userRepository.GetUsers();
UserModel defaultUser = new UserModel(new Microsoft.AspNetCore.Identity.IdentityUser("UNKNOWN"), new List<Claim>());
model.OwnedRegionSets = _worldService.GetOwnedRegionSets(userId, searchTerm);
var editableRegionSets = _worldService.GetEditableRegionSets(userId, searchTerm);
if (editableRegionSets != null)
{
model.EditableRegionSets = editableRegionSets.GroupBy(rs =>
(users.FirstOrDefault(u => u.IdentityUser.Id == rs.OwnerId) ?? defaultUser)
.IdentityUser.UserName)
.Select(g => new RegionSetCollectionModel(g)).ToList();
}
var viewableRegionSets = _worldService.GetViewableRegionSets(userId, searchTerm);
if (viewableRegionSets != null)
{
model.ViewableRegionSets = viewableRegionSets.Where(vrs => vrs.OwnerId != userId).GroupBy(rs =>
(users.FirstOrDefault(u => u.IdentityUser.Id == rs.OwnerId) ?? defaultUser)
.IdentityUser.UserName)
.Select(g => new RegionSetCollectionModel(g)).ToList();
}
return model;
}
}
还有我的 startup.cs 文件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(name: "areaRoute",
template: "{area}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
}
我尝试了以下 ajax 个地址:
localhost:44344/api/WorldApi/RegionSetSearch
localhost:44344/WorldBuilder/api/WorldApi/RegionSetSearch
localhost:44344/api/WorldBuilder/WorldApi/RegionSetSearch
localhost:44344/WorldBuilder/WorldApi/RegionSetSerarch
对于我尝试的最后一个地址,我从控制器上的路由数据注释中删除了 "api/"。
我不确定我做错了什么。我正在关注我在网上找到的所有示例。
MVC 中有两种路由类型,conventions routing
用于 mvc 和 route attribute routing
用于 web api。
在 conventions routings
中为 MVC 配置的区域不应与路由属性结合使用。 Route 属性将覆盖默认约定路由。
如果你喜欢attribute routing
,你可以
[Route("WorldBuilder/api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet("RegionSetSearch")]
public ActionResult<IEnumerable<string>> RegionSetSearch()
{
return new string[] { "value1", "value2" };
}
}
注意 [HttpGet("RegionSetSearch")]
,它定义了 RegionSetSearch
的动作,并在 url 中附加了一个占位符。
要求是 https://localhost:44389/worldbuilder/api/values/RegionSetSearch
如果您喜欢 conventions routing
,您可以删除 Route
和 ApiController
,例如
[Area("WorldBuilder")]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> RegionSetSearch()
{
return new string[] { "value1", "value2" };
}
}
使用这种方式,您需要将 UseMvc
更改为
app.UseMvc(routes => {
routes.MapRoute("areaRoute", "{area:exists}/api/{controller}/{action}/{id?}");
});
请求是https://localhost:44389/worldbuilder/api/values/RegionSetSearch
我有一个 API 控制器托管在一个区域中。但是,路由似乎不起作用,因为我的 ajax 调用在尝试执行控制器操作时不断返回 404。永远不会命中控制器构造函数中的断点。
[Area("WorldBuilder")]
[Route("api/[controller]")]
[ApiController]
public class WorldApiController : ControllerBase
{
IWorldService _worldService;
IUserRepository _userRepository;
public WorldApiController(IWorldService worldService, IUserRepository userRepository)
{
_worldService = worldService;
_userRepository = userRepository;
}
[HttpGet]
public ActionResult<WorldIndexViewModel> RegionSetSearch()
{
string searchTerm = null;
var userId = User.GetUserId();
WorldIndexViewModel model = new WorldIndexViewModel();
IEnumerable<UserModel> users = _userRepository.GetUsers();
UserModel defaultUser = new UserModel(new Microsoft.AspNetCore.Identity.IdentityUser("UNKNOWN"), new List<Claim>());
model.OwnedRegionSets = _worldService.GetOwnedRegionSets(userId, searchTerm);
var editableRegionSets = _worldService.GetEditableRegionSets(userId, searchTerm);
if (editableRegionSets != null)
{
model.EditableRegionSets = editableRegionSets.GroupBy(rs =>
(users.FirstOrDefault(u => u.IdentityUser.Id == rs.OwnerId) ?? defaultUser)
.IdentityUser.UserName)
.Select(g => new RegionSetCollectionModel(g)).ToList();
}
var viewableRegionSets = _worldService.GetViewableRegionSets(userId, searchTerm);
if (viewableRegionSets != null)
{
model.ViewableRegionSets = viewableRegionSets.Where(vrs => vrs.OwnerId != userId).GroupBy(rs =>
(users.FirstOrDefault(u => u.IdentityUser.Id == rs.OwnerId) ?? defaultUser)
.IdentityUser.UserName)
.Select(g => new RegionSetCollectionModel(g)).ToList();
}
return model;
}
}
还有我的 startup.cs 文件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(name: "areaRoute",
template: "{area}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
}
我尝试了以下 ajax 个地址:
localhost:44344/api/WorldApi/RegionSetSearch
localhost:44344/WorldBuilder/api/WorldApi/RegionSetSearch
localhost:44344/api/WorldBuilder/WorldApi/RegionSetSearch
localhost:44344/WorldBuilder/WorldApi/RegionSetSerarch
对于我尝试的最后一个地址,我从控制器上的路由数据注释中删除了 "api/"。
我不确定我做错了什么。我正在关注我在网上找到的所有示例。
MVC 中有两种路由类型,conventions routing
用于 mvc 和 route attribute routing
用于 web api。
在 conventions routings
中为 MVC 配置的区域不应与路由属性结合使用。 Route 属性将覆盖默认约定路由。
如果你喜欢attribute routing
,你可以
[Route("WorldBuilder/api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet("RegionSetSearch")]
public ActionResult<IEnumerable<string>> RegionSetSearch()
{
return new string[] { "value1", "value2" };
}
}
注意 [HttpGet("RegionSetSearch")]
,它定义了 RegionSetSearch
的动作,并在 url 中附加了一个占位符。
要求是 https://localhost:44389/worldbuilder/api/values/RegionSetSearch
如果您喜欢 conventions routing
,您可以删除 Route
和 ApiController
,例如
[Area("WorldBuilder")]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> RegionSetSearch()
{
return new string[] { "value1", "value2" };
}
}
使用这种方式,您需要将 UseMvc
更改为
app.UseMvc(routes => {
routes.MapRoute("areaRoute", "{area:exists}/api/{controller}/{action}/{id?}");
});
请求是https://localhost:44389/worldbuilder/api/values/RegionSetSearch