Контроллер веб-API.NET Core (2.1), принимающий все, что следует в URL-адресе запроса, в качестве параметра

У меня есть контроллер веб-API.NET Core 2.1 (далее TestController), который должен генерировать перенаправления на другие URL при получении запросов GET.

Пример:

Контроллер называется так: http://localhost/api/v1/Test/somedir/somesubdir/filename.extension

и он должен вернуть перенаправление на https://example-domain.com/somedir/somesubdir/filename.extension

Мой пример контроллера для этого вопроса выглядит так:

  [Authorize]
  [Route("api/v1/[controller]")]
  public class TestController : ControllerBase
  {
    [HttpGet("{path}")]
    public async Task<IActionResult> Get(string path)
    {
      //path e.g. is somedir/somesubdir/filename.extension
      string prefix = "https://example-domain.com/api/v1/Other/";
      //string path2 = HttpContext.Request.Path.Value.Replace("/api/v1/Test/", "/api/v1/Other/").Replace("%2F", "/");
      return Redirect(prefix + path);
    }
  }

Я не получаю маршрутизацию на работу. Если я вызываю метод с помощью Swagger, он вызывается (с косыми чертами, замененными на%2F), но по крайней мере он вызывается. Если я вызываю контроллер через почтальона.NET Core просто возвращает 404 Not Found.

Мне не обязательно нужен HttpGet("{путь}"). Я знаю, что мог бы получить путь, как я назначил переменную path2.

Любые намеки, как я могу получить правильную маршрутизацию?


Другое возможное решение:

Как отметили в комментариях Джон и Кирк Ларкин, я искал маршрут общего назначения, заполняющий аргумент пути с помощью "somedir/somesubdir/filename.extension", независимо от продолжительности пути.

Просто звездочка перед именем переменной делает свое дело.

[HttpGet("{*} путь")]

3 ответа

Решение

Вам не нужно принимать "api/v1/Test" в соответствии с вашими комментариями к коду, он уже отфильтрован атрибутом [Route] на уровне контроллера.

Для остальной части следующего пути вы можете использовать {*path}:

[HttpGet("{*path}")]
public async Task<IActionResult> Get(string path)
{
    const string prefix = "https://example-domain.com/api/v1/Other/";
    return Redirect(prefix + path);
}

@ Джон, его решение замечательно: [HttpGet("{*path}")]Только что проверил. но я хочу сохранить свой ответ для использования функции в качестве опции:

в качестве другого варианта вы можете воспользоваться MSDN [Catch-all route]: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.1

routes.MapRoute(
  name: "blog",
  template: "Blog/{*article}", //<==
  defaults: new { controller = "Blog", action = "ReadArticle" });

Этот шаблон будет соответствовать URL-пути, например /Blog/All-About-Routing/ Введение, и будет извлекать значения { controller = Blog, action = ReadArticle, article = All-About-Routing/ Введение}. Значения маршрута по умолчанию для контроллера и действия создаются маршрутом, даже если в шаблоне нет соответствующих параметров маршрута. Значения по умолчанию могут быть указаны в шаблоне маршрута. Параметр маршрута статьи определен как универсальный по появлению звездочки * перед именем параметра маршрута. Параметры маршрута Catch-all фиксируют оставшуюся часть пути URL, а также могут соответствовать пустой строке.

последние параметры: не используйте контроллер, и делайте это в глобальной конфигурации:

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.Map("api/v1/Test", x =>
        {
            x.Run(async context =>
            {
                //path e.g. is somedir/somesubdir/filename.extension
                string prefix = "https://example-domain.com/api/v1/Other/";
                string path = context.Request.Path.Value.Replace("/api/v1/Test/", "/api/v1/Other/").Replace("%2F", "/");
                context.Response.Redirect(prefix + path);
            });
        });
    }
}

Я думаю, что вам нужно получить эти 3 параметра, разделенных, как у вас в URL, так что... этот метод должен быть примерно таким...

[Route("{dir}/{subdir}/filename")]
public async Task<IActionResult> Get(string dir, string subdir, string filename)
{
  string path = dir + "/" + subdir + "/" + filename;
  //path e.g. is somedir/somesubdir/filename.extension
  string prefix = "https://example-domain.com/api/v1/Other/";
  //string path2 = HttpContext.Request.Path.Value.Replace("/api/v1/Test/", "/api/v1/Other/").Replace("%2F", "/");
  return Redirect(prefix + path);
}
Другие вопросы по тегам