使用属性路由定义的路径模板是不是被视为硬编码?

Posted

技术标签:

【中文标题】使用属性路由定义的路径模板是不是被视为硬编码?【英文标题】:Are path templates defined using Attribute Routing considered hard coded?使用属性路由定义的路径模板是否被视为硬编码? 【发布时间】:2020-05-22 07:02:21 【问题描述】:

如果我在 ASP.NET 控制器中使用Attribute Routing,这些路径模板是否被视为硬编码?例如,如果我添加[HttpGet("/employee")][Route("/employee")]/employee 路径是否是硬编码值?

【问题讨论】:

硬编码是什么意思?路由完全基于开发人员用来开发 API 访问端点的命名法。硬编码只是对可能会根据不同事件发生变化的逻辑使用固定的静态值。在这种情况下,路由永远不会改变,尽管内部逻辑可以多次更改并且客户端不会意识到这一点。 我的一位前辈说这是硬编码,可以避免,但我不明白这一点,如果将来它不会改变我们怎么能说它是硬编码的。所以它不是硬编码的吗? @RahulSharma 嗯,这完全取决于您正在遵循或被要求遵循的架构。有一些方法可以动态创建您的路线,但这也取决于您正在开发的内容。所以,你不能说这是硬编码,而更多的是不同场景的需求基础。 它可以被认为是硬编码并没有错,但是应该用从常量类调用这个值的常量变量替换它,对我来说不是。如果需要将其替换为常量变量而不是主要编码实践之一,即不遵循代码的可读性。如果你在任何地方都使用常量变量,开发人员很难理解其他人的代码,在这种情况下,我必须为我看到的每个常量一次又一次地查看你的常量类。 啊,是的!我将在早上更新我的答案,提供更多详细信息,但快速总结是,您可能有一个 Web 应用程序,可以作为程序集分发(甚至可能通过 NuGet),然后嵌入到多个不同的 Web 应用程序中。例如,我有一个以这种方式分发的 CMS 编辑器。然后,每个站点都可以重用相同的控制器和视图,而无需维护自己的代码副本。对于解决此问题的一种方法,请查看Razor Class Libraries。 【参考方案1】:

正如其他人在 cmets 中指出的那样,这些路线肯定是硬编码的,但 可能不是真正的问题。更好地了解是什么需求导致了这种担忧,因为解决方案最终将取决于此。同时,我可以根据常见的场景提供一些高层次的指导。

单层网络应用程序

如果您的控制器作为 Web 应用程序的一部分分发,并且您的路由始终在设计时定义(即,作为开发过程的一部分),那么它只是一种风格偏好您的路由路径是硬编码为控制器的一部分还是硬编码为Startup 类的一部分。 这是大多数 Web 应用程序的典型场景

可分发的类库

如果您分发您的控制器作为类库(或 Razor 类库)的一部分,该类库(或 Razor 类库)旨在用于多个网络应用程序,那么这个是更大的考虑因素。在这种情况下,将路由硬编码为控制器的一部分会阻止类库的使用者修改路径。

如果您想确保始终使用相同的路由,同时消除在每个应用程序的基础上配置它们的需要,这可能是有利的。但相反可能是允许每个应用程序在其Startup 类中自定义这些路由,从而使消费者可以灵活地自定义库的端点所在的位置。如果是这种情况,在类库的控制器中硬编码这些值是不可取的。

扩展方法

如果后者是要求,通常包含IRouteBuilder 和/或IEndpointRouteBuilder 的扩展方法,以便消费者可以轻松地为您的库配置路由,同时接受您希望它们覆盖的任何变量的参数,例如路径前缀。这提供了灵活性和易于配置之间的平衡。例如,这可能类似于以下内容:

public static ControllerActionEndpointConventionBuilder MapEmployeeRoute(
  this IEndpointRouteBuilder routes,
  string pathPrefix = "Employee",
  string controller = "Employee",
  string action = "Index"
) =>
 routes.MapControllerRoute(
   name: "Employee-" + pathPrefix?.Replace("/", "", System.StringComparison.OrdinalIgnoreCase),
  pattern: pathPrefix?.Trim('/') + "/action",
  defaults: new  controller, action, pathPrefix 
);

可用于以下任何调用:

public static void Configure(IApplicationBuilder app, IWebHostEnvironment env) > 
  …
  app.UseRouting();
  app.UseEndpoints(endpoints => 
    endpoints.MapEmployeeRoute();                           //Maps /Employee
    endpoints.MapEmployeeRoute("Administration/Staff");     //Maps /Administration/Staff/
    endpoints.MapEmployeeRoute("/Administration/Staff/");   //Tolerate variations
    endpoints.MapEmployeeRoute("Staff", "MyEmployee");      //Reference derived controller
    endpoints.MapEmployeeRoute("Staff", "Employee", "Add"); //Default to the Add() action
  );

动态路由配置

注意: 这是一个非常少见的场景,所以我什至不敢提出来。也就是说,如果它与您的要求相关,我会将其包括在内。

另一个可能需要对路由进行硬编码的情况是,如果出于某种原因,您需要在运行时动态配置它们和/或使用来自外部数据源的配置值。

例如,如果您正在构建平台即服务 (PAAS),有时需要提供一个 Web 界面,用户可以在其中配置与特定服务关联的路由,然后动态注册这些路由,而不是硬编码他们进入平台本身。不过,这是一种更为复杂的方法。

【讨论】:

以上是关于使用属性路由定义的路径模板是不是被视为硬编码?的主要内容,如果未能解决你的问题,请参考以下文章

WebRTC[44] - WebRTC 在安卓端的视频硬编硬解策略详解

WebRTC[44] - WebRTC 在安卓端的视频硬编硬解策略详解

有没有办法在 Spring Security 插件的属性文件中定义角色而不是硬编码它们?

android音视频音频硬编解码pcm&aac&wav

android音视频音频硬编解码pcm&aac&wav

iOS VideoToolbox 硬编指南