Asp.Net 核心区域路由到 Api 控制器不起作用

cha*_*986 1 asp.net-mvc-areas asp.net-core-mvc asp.net-core-2.0

我在一个区域托管了一个 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有我的 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了以下ajax地址:

   localhost:44344/api/WorldApi/RegionSetSearch
   localhost:44344/WorldBuilder/api/WorldApi/RegionSetSearch
   localhost:44344/api/WorldBuilder/WorldApi/RegionSetSearch
   localhost:44344/WorldBuilder/WorldApi/RegionSetSerarch
Run Code Online (Sandbox Code Playgroud)

对于我尝试的最后一个地址,我从控制器上的路由数据注释中删除了“api/”。

我不确定我在这里做错了什么。我正在关注我在网上找到的所有示例。

Tao*_*hou 9

MVC中有两种路由类型,conventions routing一种用于mvc route attribute routing,一种用于web api。

对于在conventions routingsMVC 中配置的区域,不应与路由属性结合使用。路由属性将覆盖默认的约定路由。

如果你愿意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" };
    }        
}
Run Code Online (Sandbox Code Playgroud)

注意[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" };
    }        
}
Run Code Online (Sandbox Code Playgroud)

用这种方式,你需要改变UseMvc喜欢

app.UseMvc(routes => {
    routes.MapRoute("areaRoute", "{area:exists}/api/{controller}/{action}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)

请求是 https://localhost:44389/worldbuilder/api/values/RegionSetSearch