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,您可以删除 RouteApiController,例如

[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