Перенаправить на указанное действие, если запрошенное действие не найдено - PullRequest
0 голосов
/ 18 сентября 2018

Как я могу перенаправить действие, которое не найдено в контроллере, в другое действие в том же контроллере?Допустим, файл abc.txt запрашивается через http://localhost:5000/Link/GetFile/abc.txt.Мой контроллер правильно обслуживает этот файл.Но теперь мне нужно обработать запрос, такой как http://localhost:5000/Link/Document/abc.Конечно, нет никакого действия, соответствующего Document, поэтому мне нужно вызвать функцию Error в том же контроллере (включая идентификатор из исходного запроса).

Я пытался решить эту проблему с помощью функции StatusCodePagesWithReExecute, нотогда мое File действие не работает (каждый запрос идет непосредственно к функции Error).

У меня есть следующий контроллер:

public class LinkController : ControllerBase
{
    public IActionResult GetFile(string id)
    {
        return DownloadFile(id);
    }

    public IActionResult Error(string id)
    {
        return File("~/index.html", "text/html");
    }

    private FileResult DownloadFile(string fileName)
    {
        IFileProvider provider = new PhysicalFileProvider(@mypath);

        IFileInfo fileInfo = provider.GetFileInfo(fileName);
        var readStream = fileInfo.CreateReadStream();
        return File(readStream, "text/plain");
    }
}

и конфигурация запуска:

app.UseDefaultFiles();

app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "application/octet-stream",
});

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller}/{action}/{id?}"
        );

});

Любые подсказки, как решить эту проблему?Привет

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Вы можете использовать UseStatusCodePages для достижения простого перенаправления, когда есть 404. Вот как это выглядит:

app.UseStatusCodePages(ctx =>
{
    if (ctx.HttpContext.Response.StatusCode == 404)
        ctx.HttpContext.Response.Redirect("/Path/To/Your/Action");

    return Task.CompletedTask;
});

Просто добавьте это где-то выше UseMvc.

0 голосов
/ 18 сентября 2018

EDIT:

Извините, мой первый ответ был неверным.

  1. IRouteCollection router = RouteData.Routers.OfType<IRouteCollection>().First();

с этим вы можете сопоставить URL с действием контроллера

  1. Создать HttpContext для тестирования (пример с инъекцией)

    private readonly IHttpContextFactory _httpContextFactory;
    
    public HomeController(
        IHttpContextFactory httpContextFactory)
    {
        _httpContextFactory = httpContextFactory;
    }
    
  2. Создать контекст со значениями

    HttpContext context = _httpContextFactory.Create(HttpContext.Features);
    context.Request.Path = "/Home/Index";
    context.Request.Method = "GET";
    
  3. Проверить маршрут

    var routeContext = new RouteContext(context);
    await router.RouteAsync(routeContext);
    bool exists = routeContext.Handler != null;
    

Дальнейшее чтение: https://joonasw.net/view/find-out-if-url-matches-action

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...