Контроллер веб-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);
}