乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      ASP.NET Core 3.0中使用動(dòng)態(tài)控制器路由

       印度阿三17 2019-09-04

      原文:Dynamic controller routing in ASP.NET Core 3.0
      作者:Filip W
      譯文:https://www.cnblogs.com/lwqlun/p/11461657.html
      譯者:Lamond Lu

      譯者注

      今天在網(wǎng)上看到了這篇關(guān)于ASP.NET Core動(dòng)態(tài)路由的文章,感覺(jué)蠻有意思的,給大家翻譯一下,雖然文中的例子不一定會(huì)在日常編碼中出現(xiàn),但是也給我們提供了一定的思路。

      前言

      相對(duì)于ASP.NET MVC以及ASP.NET Core MVC中的舊版本路由特性, 在ASP.NET Core 3.0中新增了一個(gè)不錯(cuò)的擴(kuò)展點(diǎn),即程序獲取到路由后,可以將其動(dòng)態(tài)指向一個(gè)給定的controller/action.

      這個(gè)功能有非常多的使用場(chǎng)景。如果你正在使用從ASP.NET Core 3.0 Preview 7及更高版本,你就可以在ASP.NET Core 3.0中使用它了。

      PS: 官方?jīng)]有在Release Notes中提到這一點(diǎn)。

      下面就讓我們一起來(lái)看一看ASP.NET Core 3.0中的動(dòng)態(tài)路由。

      背景

      當(dāng)我們使用MVC路由的時(shí)候,最典型的用法是,我們使用路由特性(Route Attributes)來(lái)定義路由信息。使用這種方法,我們需要要為每個(gè)路由進(jìn)行顯式的聲明。

      public class HomeController : Controller
      {
         [Route("")]
         [Route("Home")]
         [Route("Home/Index")]
         public IActionResult Index()
         {
            return View();
         }
      }

      相對(duì)的,你可以使用中心化的路由模型,使用這種方式,你就不需要顯式的聲明每一個(gè)路由 - 這些路由會(huì)自動(dòng)被所有發(fā)現(xiàn)的控制器的自動(dòng)識(shí)別。 然而,這樣做的前提是,所有的控制器首先必須存在。

      以下是ASP.NET Core 3.0中使用新語(yǔ)法Endpoint Routing的實(shí)現(xiàn)方式。

      app.UseEndpoints(
          endpoints =>
          {
              endpoints.MapControllerRoute("default", 
                        "{controller=Home}/{action=Index}/{id?}");
          }
      );

      以上兩種方式的共同點(diǎn)是,所有的路由信息都必須在應(yīng)用程序啟動(dòng)時(shí)加載。

      但是,如果你希望能夠動(dòng)態(tài)定義路由, 并在應(yīng)用程序運(yùn)行時(shí)添加/刪除它們,該怎么辦?

      下面我給大家列舉幾個(gè)動(dòng)態(tài)定義路由的使用場(chǎng)景。

      • 多語(yǔ)言路由,以及使用新語(yǔ)言時(shí),針對(duì)那些新語(yǔ)言路由的修改。
      • 在CMS類型的系統(tǒng)中,我們可能會(huì)動(dòng)態(tài)添加一些新頁(yè)面,這些新頁(yè)面不需要?jiǎng)?chuàng)建的控制器或者在源碼中硬編碼路由信息。
      • 多租戶應(yīng)用中,租戶路由可以在運(yùn)行時(shí)動(dòng)態(tài)激活或者取消激活。

      這個(gè)問(wèn)題的處理過(guò)程應(yīng)該相當(dāng)?shù)暮美斫?。我們希望盡早的攔截路由處理,檢查已為其解析的當(dāng)前路由值,并使用例如數(shù)據(jù)庫(kù)中的數(shù)據(jù)將它們“轉(zhuǎn)換”為一組新的路由值,這些新的路由值指向了一個(gè)實(shí)際存在的控制器。

      實(shí)例問(wèn)題 - 多語(yǔ)言翻譯路由問(wèn)題

      在舊版本的ASP.NET Core MVC中, 我們通常通過(guò)自定義IRouter接口,來(lái)解決這個(gè)問(wèn)題。然而在ASP.NET Core 3.0中這種方式已經(jīng)行不通了,因?yàn)槁酚梢呀?jīng)改由上面提到的Endpoint Routing來(lái)處理。值得慶幸的是,ASP.NET Core 3.0 Preview 7以及后續(xù)版本中,我們可以通過(guò)一個(gè)新特性MapDynamicControllRoute以及一個(gè)擴(kuò)展點(diǎn)DynamicRouteValueTransformer, 來(lái)支持我們的需求。下面讓我們看一個(gè)具體的例子。

      想象一下,在你的項(xiàng)目中,有一個(gè)OrderController控制器,然后你希望它支持多語(yǔ)言翻譯路由。

      public class OrdersController : Controller
      {
          public IActionResult List()
          {
              return View();
          }
      }

      我們可能希望的請(qǐng)求的URL是這樣的,例如

      • 英語(yǔ) - /en/orders/list
      • 德語(yǔ) - /de/bestellungen/liste
      • 波蘭語(yǔ) - /pl/zamowienia/lista

      使用動(dòng)態(tài)路由處理多語(yǔ)言翻譯路由問(wèn)題

      那么我們現(xiàn)在該如何解決這個(gè)問(wèn)題呢?我們可以使用新特性MapDynamicControllerRoute來(lái)替代默認(rèn)的MVC路由, 并將其指向我們自定義的DynamicRouteValueTransformer類, 該類實(shí)現(xiàn)了我們之前提到的路由值轉(zhuǎn)換 。

      public class Startup
      {
          public void ConfigureServices(IServiceCollection services)
          {
              services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);
      
              services.AddSingleton<TranslationTransformer>();
              services.AddSingleton<TranslationDatabase>();
          }
      
          public void Configure(IApplicationBuilder app)
          {
              app.UseRouting();
              app.UseEndpoints(endpoints =>
              {
                  endpoints.MapDynamicControllerRoute<TranslationTransformer>("{language}/{controller}/{action}");
              });
          }
      }

      這里我們定義了一個(gè)TranslationTransformer類,它繼承了DynamicRouteValueTransformer類。這個(gè)新類將負(fù)責(zé)將特定語(yǔ)言路由值,轉(zhuǎn)換為可以在我們應(yīng)用可以匹配到controller/action的路由值字典,而這些值通常不能直接和我們應(yīng)用中的任何controller/action匹配。所以這里簡(jiǎn)單點(diǎn)說(shuō),就是在德語(yǔ)場(chǎng)景下,controller名會(huì)從“Bestellungen”轉(zhuǎn)換成"Orders", action名"Liste"轉(zhuǎn)換成"List"。

      TranslationTransformer類被作為泛型類型參數(shù),傳入MapDynamicControllerRoute方法中,它必須在依賴注入容器中注冊(cè)。這里,我們還需要注冊(cè)一個(gè)TranslationDatabase類,但是這個(gè)類僅僅為了幫助演示,后面我們會(huì)需要它。

      public class TranslationTransformer : DynamicRouteValueTransformer
      {
          private readonly TranslationDatabase _translationDatabase;
      
          public TranslationTransformer(TranslationDatabase translationDatabase)
          {
              _translationDatabase = translationDatabase;
          }
      
          public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext
          , RouteValueDictionary values)
          {
              if (!values.ContainsKey("language") 
                  || !values.ContainsKey("controller") 
                  || !values.ContainsKey("action")) return values;
      
              var language = (string)values["language"];
              var controller = await _translationDatabase.Resolve(language, 
                  (string)values["controller"]);
                  
              if (controller == null) return values;
              values["controller"] = controller;
      
              var action = await _translationDatabase.Resolve(language, 
                  (string)values["action"]);
                  
              if (action == null) return values;
              values["action"] = action;
      
              return values;
          }
      }

      在這個(gè)轉(zhuǎn)換器中,我們需要嘗試提取3個(gè)路由參數(shù), language, controller,action,然后我們需要在模擬用的數(shù)據(jù)庫(kù)類中,找到其對(duì)應(yīng)的翻譯。正如我們之前提到的,你通常會(huì)希望從數(shù)據(jù)庫(kù)中查找對(duì)應(yīng)的內(nèi)容,因?yàn)槭褂眠@種方式,我們可以在應(yīng)用程序生命周期的任何時(shí)刻,動(dòng)態(tài)的影響路由。為了說(shuō)明這一點(diǎn),我們將使用TranslationDatabase類來(lái)模擬數(shù)據(jù)庫(kù)操作,這里你可以把它想象成一個(gè)真正的數(shù)據(jù)庫(kù)倉(cāng)儲(chǔ)服務(wù)。

      public class TranslationDatabase
      {
          private static Dictionary<string, Dictionary<string, string>> Translations 
              = new Dictionary<string, Dictionary<string, string>>
          {
              {
                  "en", new Dictionary<string, string>
                  {
                      { "orders", "orders" },
                      { "list", "list" }
                  }
              },
              {
                  "de", new Dictionary<string, string>
                  {
                      { "bestellungen", "orders" },
                      { "liste", "list" }
                  }
              },
              {
                  "pl", new Dictionary<string, string>
                  {
                      { "zamowienia", "order" },
                      { "lista", "list" }
                  }
              },
          };
      
          public async Task<string> Resolve(string lang, string value)
          {
              var normalizedLang = lang.ToLowerInvariant();
              var normalizedValue = value.ToLowerInvariant();
              if (Translations.ContainsKey(normalizedLang) 
                  && Translations[normalizedLang]
                      .ContainsKey(normalizedValue))
              {
                  return Translations[normalizedLang][normalizedValue];
              }
      
              return null;
          }
      }

      到目前為止,我們已經(jīng)很好的解決了這個(gè)問(wèn)題。這里通過(guò)在MVC應(yīng)用中啟用這個(gè)設(shè)置,我們就可以向我們之前定義的3個(gè)路由發(fā)送請(qǐng)求了。

      • 英語(yǔ) - /en/orders/list
      • 德語(yǔ) - /de/bestellungen/liste
      • 波蘭語(yǔ) - /pl/zamowienia/lista

      每個(gè)請(qǐng)求都會(huì)命中OrderController控制器和List方法。當(dāng)前你可以將這個(gè)方法進(jìn)一步擴(kuò)展到其他的控制器。但最重要的是,如果新增一種新語(yǔ)言或者新的路由別名映射到現(xiàn)有語(yǔ)言中的controller/actions,你是不需要做任何代碼更改,甚至重啟項(xiàng)目的。

      請(qǐng)注意,在本文中,我們只關(guān)注路由轉(zhuǎn)換,這里僅僅是為了演示ASP.NET Core 3.0中的動(dòng)態(tài)路由特性。如果你希望在應(yīng)用程序中實(shí)現(xiàn)本地化,你可能還需要閱讀ASP.NET Core 3.0的本地化指南, 因?yàn)槟憧梢孕枰鶕?jù)語(yǔ)言的路由值設(shè)置正確的CurrentCulture。

      最后, 我還想再補(bǔ)充一點(diǎn),在我們之前的例子中,我們?cè)诼酚赡0逯酗@式的使用了{controller}{action}占位符。這并不是必須的,在其他場(chǎng)景中,你還可以使用"catch-all"路由通配符,并將其轉(zhuǎn)換為controller/action路由值。

      "catch-all"路由通配符是CMS系統(tǒng)中的典型解決方案,你可以使用它來(lái)處理不同的動(dòng)態(tài)“頁(yè)面”路由。

      它看起來(lái)可能類似:

      endpoints.MapDynamicControllerRoute<PageTransformer>("pages/{**slug}");

      然后,你需要將pages之后的整個(gè)URL參數(shù)轉(zhuǎn)換為現(xiàn)有可執(zhí)行控制器的內(nèi)容 - 通常URL/路由的映射是保存在數(shù)據(jù)庫(kù)中的。

      希望你會(huì)發(fā)現(xiàn)這篇文章很有用 - 所有的演示源代碼都可以在Github上找到。

      來(lái)源:https://www./content-1-439951.html

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多