Перенос использования IRouter на ASP. NET Core 3.1 - PullRequest
1 голос
/ 13 января 2020

Я читаю через Adam Freeman Pro ASP. NET Core MVC 2, и одна из глав о расширенных функциях маршрутизации включает механизм, с помощью которого вы можете реализовать двустороннюю унаследованную обработку URL-адресов с помощью IRouter. Суть этого такова:

Предположим, у вас есть «устаревший» URL, такой как "/article/Windows_3.1_Overview.html"

Используя пользовательскую реализацию IRouter, Core 2.0 позволяет вам:

  1. Направьте этот устаревший URL-адрес на указанное c действие (например, Legacy/GetLegacyUrl) при передаче URL-адреса в качестве параметра следующим образом:
public async Task RouteAsync(RouteContext context) 
{
  string requestedUrl = context.HttpContext.Request.Path.Value.TrimEnd('/');

  if (urls.Contains(requestedUrl, StringComparer.OrdinalIgnoreCase)) 
  {
    context.RouteData.Values["controller"] = "Legacy";
    context.RouteData.Values["action"] = "GetLegacyUrl";
    context.RouteData.Values["legacyUrl"] = requestedUrl;
    await mvcRoute.RouteAsync(context); // mvcRoute is an instance of MvcRouteHandler
  }
}
Создайте тот же URL , используя помощник тега: (<a asp-route-legacyurl="/article/Windows_3.1_Overview.html">Old Link</a>), используя следующее:
public VirtualPathData GetVirtualPath(VirtualPathContext context) 
{
  if (context.Values.ContainsKey("legacyUrl")) 
  {
    string url = context.Values["legacyUrl"] as string;

    if (urls.Contains(url)) 
    {
      return new VirtualPathData(this, url);
    }
  }

  return null;
}

Мой вопрос: как мне это сделать в Core 3,0? Я попробовал этот подход, но MvcRouteHandler больше нет. Я пытался реализовать DynamicRouteValueTransformer так:

public async override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext,
  RouteValueDictionary values)
{
  string requestedUrl = httpContext.Request.Path.Value.TrimEnd('/');

  return await Task.FromResult(new RouteValueDictionary()
  {
    ["controller"] = "Legacy",
    ["action"] = "GetLegacyUrl",
    ["legacyUrl"] = requestedUrl
  });
}

... но, насколько я читал, это работает только в одном направлении. Это также единственное упоминание в руководстве по миграции Microsoft 2.2 -> 3.0. Я попытался буквально сопоставить URL, используя

routes.MapRoute(
  name: "",
  template: route,
  defaults: new { controller = "Legacy", action = "GetLegacyUrl", legacyUrl = route });

Но это также не генерирует устаревший URL, вместо этого выбрав Legacy/GetLegacyUrl/?legacyUrl=%2Farticle%2FWindows_3.1_Overview.html

Я не совсем уверен, как иначе я могу добиться этого, и я уже несколько часов ломаю голову и документацию. «Маршрутизация в ASP. NET Core» не помогла, не помог «Миграция с ASP. NET Core 2.2 до 3.0» .

Я, вероятно, упускаю что-то очевидное, но я просто не могу найти ответ.

...