使用属性路由定义的路径模板是否被视为硬编码?
Are path templates defined using Attribute Routing considered hard coded?
如果我在 ASP.NET 控制器中使用 Attribute Routing,这些路径模板是否被视为硬编码?例如,如果我添加 [HttpGet("/employee")]
或 [Route("/employee")]
,/employee
路径是硬编码值吗?
正如其他人在评论中指出的那样,这些路由 绝对 是硬编码的,但 可能 并不是真正的问题。更好地了解是什么需求导致了这种担忧,这将很有用,因为解决方案最终将取决于此。同时,我可以提供一些基于常见场景的高级指导。
单层 Web 应用程序
如果您的控制器作为 Web 应用程序的一部分进行分发,并且您的路由 总是 在设计时定义(即,作为开发过程的一部分),那么它只是关于您的路由路径是硬编码为控制器的一部分还是硬编码为 Startup
class 的一部分的风格偏好。 这是大多数 Web 应用程序的典型场景。
可分发Class库
如果您分发您的控制器作为 Class 库(或 Razor Class 库)的一部分,旨在用于多个个web应用,那么这个考虑就更大了。在这种情况下,将路由硬编码为控制器的一部分可以防止 class 库的使用者修改路径。
如果您想确保始终使用相同的路由,同时又无需在每个应用程序的基础上配置它们,那么这可能是有利的。但允许每个应用程序在其 Startup
class 中自定义这些路由可能 而 有意义,从而使消费者可以灵活地自定义您的库端点所在的位置。如果是这种情况,在 class 库的控制器中硬编码这些值是不可取的。
Extension Methods
If the latter is the requirement, it's common to include an extension method for IRouteBuilder
and/or IEndpointRouteBuilder
so that consumers can easily configure routes for your library, while accepting parameters for any variables you expect them to override, such as a path prefix. This provides a balance between flexibility and ease of configuration. For example, this might look something like the following:
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 }
);
Which could be used with any of the following calls:
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
});
}
动态路由配置
Note: This is a pretty uncommon scenario, and so I hesitate to even bring it up. That said, I'm including it for completeness in case it relates to your requirements.
另一种可能需要对路由进行硬编码的情况是,如果出于某种原因,您需要在 运行 时动态配置它们 and/or 使用来自外部数据源。
例如,如果您正在构建一个平台即服务 (PAAS),有时需要提供一个 Web 界面,用户可以在其中配置与特定服务关联的路由,然后动态注册这些,而不是硬性注册-将它们编码到平台本身。不过,这是一种复杂得多的方法。
如果我在 ASP.NET 控制器中使用 Attribute Routing,这些路径模板是否被视为硬编码?例如,如果我添加 [HttpGet("/employee")]
或 [Route("/employee")]
,/employee
路径是硬编码值吗?
正如其他人在评论中指出的那样,这些路由 绝对 是硬编码的,但 可能 并不是真正的问题。更好地了解是什么需求导致了这种担忧,这将很有用,因为解决方案最终将取决于此。同时,我可以提供一些基于常见场景的高级指导。
单层 Web 应用程序
如果您的控制器作为 Web 应用程序的一部分进行分发,并且您的路由 总是 在设计时定义(即,作为开发过程的一部分),那么它只是关于您的路由路径是硬编码为控制器的一部分还是硬编码为 Startup
class 的一部分的风格偏好。 这是大多数 Web 应用程序的典型场景。
可分发Class库
如果您分发您的控制器作为 Class 库(或 Razor Class 库)的一部分,旨在用于多个个web应用,那么这个考虑就更大了。在这种情况下,将路由硬编码为控制器的一部分可以防止 class 库的使用者修改路径。
如果您想确保始终使用相同的路由,同时又无需在每个应用程序的基础上配置它们,那么这可能是有利的。但允许每个应用程序在其 Startup
class 中自定义这些路由可能 而 有意义,从而使消费者可以灵活地自定义您的库端点所在的位置。如果是这种情况,在 class 库的控制器中硬编码这些值是不可取的。
Extension Methods
If the latter is the requirement, it's common to include an extension method for
IRouteBuilder
and/orIEndpointRouteBuilder
so that consumers can easily configure routes for your library, while accepting parameters for any variables you expect them to override, such as a path prefix. This provides a balance between flexibility and ease of configuration. For example, this might look something like the following: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 } );
Which could be used with any of the following calls:
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 }); }
动态路由配置
Note: This is a pretty uncommon scenario, and so I hesitate to even bring it up. That said, I'm including it for completeness in case it relates to your requirements.
另一种可能需要对路由进行硬编码的情况是,如果出于某种原因,您需要在 运行 时动态配置它们 and/or 使用来自外部数据源。
例如,如果您正在构建一个平台即服务 (PAAS),有时需要提供一个 Web 界面,用户可以在其中配置与特定服务关联的路由,然后动态注册这些,而不是硬性注册-将它们编码到平台本身。不过,这是一种复杂得多的方法。