官术网_书友最值得收藏!

Using dynamic routing

Up until now, we've seen routing tables that statically map route templates to controller actions, but there is another kind: dynamic routes. In this case, we are still using route templates, but the thing is, we can change them dynamically.

A dynamic route handler is registered through a call to MapDynamicControllerRoute. I will provide an example that uses a translation service to translate the controller and action names supplied by the user, in any language to plain English, as they exist in the project.

Let's start from the beginning. We define the interface for the translation service:

public interface ITranslator
{
Task<string> Translate(string sourceLanguage, string term);
}

As you can see, this has a single asynchronous method, Translate, that takes two parameters: the source language and the term to translate. Let's not waste much time with this.

The core dynamic routing functionality is implemented as a class inheriting from DynamicRouteValueTransformer. Here is an example of one such class, followed by its explanation:

publicsealedclassTranslateRouteValueTransformer : DynamicRouteValueTransformer
{
    privateconststring _languageKey ="language";
    privateconststring _actionKey ="action";
    privateconststring _controllerKey ="controller";
 
    privatereadonlyITranslator _translator;
 
    publicTranslateRouteValueTransformer(ITranslatortranslator)
    {
        this._translator =translator;
    }
 
    publicoverride async ValueTask<RouteValueDictionary> TransformAsync(
HttpContexthttpContext, RouteValueDictionaryvalues) { varlanguage=values[_languageKey] asstring; varcontroller=values[_controllerKey] asstring; varaction=values[_actionKey] asstring; controller= await this._translator.Translate(
language, controller) ??controller; action= await this._translator.Translate(language, action)
??action; values[_controllerKey] =controller; values[_actionKey] =action; returnvalues; } }

The TranslateRouteValueTransformer class receives on its constructor an instance of ITranslator, which it saves as a local field. On the TransformAsync method, it retrieves the values for the route template values, language, controller, and action; for controller andaction, it has them translated by ITranslator. The resulting values are then stored again in the route values dictionary, which is returned in the end.

To make this work, we need three things:

  1. We need to register ITranslator as a service in ConfigureServices:
services.AddSingleton<ITranslator, MyTranslator>();
//MyTranslator is just for demo purposes, you need to roll out your own dictionary implementation
  1. We need to registerTranslateRouteValueTransformer as a service too:
services.AddSingleton<TranslateRouteValueTransformer>();
  1. And finally, we need to register a dynamic route:
app.UseEndpoints(endpoints=>
{
endpoints.MapDynamicControllerRoute<TranslateRouteValueTransformer>(
pattern: "{language}/{controller}/{action}/{id?}");
//now adding the default route
endpoints.MapDefaultControllerRoute();
});

As you can see, our dynamic route looks for a pattern of language/controller/action/id, where the id part is optional. Any request that can be mapped to this pattern will fall into this dynamic route.

Keep in mind that the purpose of dynamic routes is not to change the route pattern, but just to change the route template tokens. This will not cause any redirect, but will actually determine how the request is to be processed, the action method and the controller, and any other route parameters.

To bring this section to a close, this example allows the resolution of these routes, provided that the dictionary supports French (fr), German (de), and Portuguese (pt):

  • /fr/Maison/Index to /Home/Index
  • /pt/Casa/Indice to /Home/Index
  • /de/Zuhause/Index to /Home/Index
You can have multiple dynamic routes with different patterns; this is perfectly OK.

Having learned about dynamic routes, let's go back to static routes, this time using attributes in classes and methods to define the routes.

主站蜘蛛池模板: 广灵县| 广灵县| 卓资县| 象州县| 旬阳县| 方正县| 庆安县| 肥西县| 修水县| 瓦房店市| 来安县| 永宁县| 磐安县| 泸州市| 钟山县| 石楼县| 丹阳市| 嘉黎县| 鱼台县| 铜川市| 玉树县| 苏尼特右旗| 万州区| 历史| 虎林市| 利津县| 泌阳县| 峡江县| 邯郸县| 福鼎市| 太湖县| 淮安市| 赞皇县| 兴海县| 东乌珠穆沁旗| 阳高县| 贵溪市| 铜川市| 凤山市| 浠水县| 永丰县|