Asp.Net核心区域路由到Api控制器不起作用 [英] Asp.Net Core Area routing to Api Controller not working

查看:77
本文介绍了Asp.Net核心区域路由到Api控制器不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在某个区域托管了一个API控制器.但是,路由似乎不起作用,因为当我尝试执行控制器操作时,我的ajax调用会不断返回404.永远不会碰到控制器构造函数中的断点.

I have an API controller hosted in an area. However, the routing doesn't seem to be working as my ajax calls keep returning 404's when trying to hit the controller actions. Breakpoints in the controller constructor are never hit.

[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文件:

And my startup.cs file:

    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地址:

I have tried the following ajax addresses:

   localhost:44344/api/WorldApi/RegionSetSearch
   localhost:44344/WorldBuilder/api/WorldApi/RegionSetSearch
   localhost:44344/api/WorldBuilder/WorldApi/RegionSetSearch
   localhost:44344/WorldBuilder/WorldApi/RegionSetSerarch

对于我尝试的最后一个地址,我从控制器上的Route数据注释中删除了"api/".

For the last address I tried, I removed the "api/" from the Route data annotation on the controller.

我不确定我在做什么错.我将跟踪我在网上找到的所有示例.

I'm not sure what I'm doing wrong here. I'm following all of the examples I've found online.

推荐答案

MVC中有两种路由类型,conventions routing用于mvc,而route attribute routing用于Web api.

There are two routing type in MVC, conventions routing which is for mvc and route attribute routing which is for web api.

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

For area which is configured in conventions routings for MVC should not be combine with route attribute. Route attribute will override the default convention routing.

如果您喜欢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中附加了一个占位符.

Pay attention to [HttpGet("RegionSetSearch")] which define the action for RegionSetSearch and append a placeholder in the url.

Reuqest是https://localhost:44389/worldbuilder/api/values/RegionSetSearch

如果您喜欢conventions routing,则可以删除RouteApiController之类的

If you prefer conventions routing, you could remove Route and ApiController like

[Area("WorldBuilder")]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> RegionSetSearch()
    {
        return new string[] { "value1", "value2" };
    }        
}

通过这种方式,您需要像一样更改UseMvc

With this way, you need to change the UseMvc like

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

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

这篇关于Asp.Net核心区域路由到Api控制器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆