Не работает маршрутизация Asp.Net Core Area на Api Controller - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть контроллер 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 /» из аннотации данных Route на контроллере.

Я не уверен, что я делаю здесь неправильно.Я следую всем примерам, которые я нашел в Интернете.

1 Ответ

0 голосов
/ 01 марта 2019

В MVC есть два типа маршрутизации: conventions routing для mvc и route attribute routing для веб-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.

Reuqest 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

...