过程,controller下的路由是怎么来的。最后落到了,DefaultApplicationModelProvider下面的CreateActionModel,

参考来自此,(78条消息) .netcore入门13:aspnetcore源码之如何在程序启动时将Controller里的Action自动扫描封装成Endpoint_jackletter的博客-CSDN博客

 

一、探索目的说明
我们知道在程序启动时,程序就会扫描所有相关程序集中Controller的Action,然后将他们封装成一个个的Endpoint交给“路由”模块去管理,这样在http请求到来时“路由”模块才能寻找到正确的Endpoint,进而找到Action并调用执行。这里我们正是要探索“程序在启动时如何扫描Action并封装成Endpoint”的。
————————————————
版权声明:本文为CSDN博主「jackletter」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010476739/article/details/104545284

 

正常的Controller的Action怎么变成Endpoint的。

services.AddControllers()—>ActionDescriptor 

MvcCoreServiceCollectionExtensions.cs

services.TryAddEnumerable(
ServiceDescriptor.Transient<IApplicationModelProvider, DefaultApplicationModelProvider>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IApplicationModelProvider, ApiBehaviorApplicationModelProvider>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<IActionDescriptorProvider, ControllerActionDescriptorProvider>());

ControllerActionDescriptorProvider->ControllerActionDescriptorBuilder

endpoints.MapControllers()--->EndPoint

热拔插系统,会通知修改,在change之后,会upEndPoint

我的问题是怎么修改 EndPoint 的路由。

重写DefaultApplicationModelProvider,不太现实。在bing里面翻了半天。突然看到

https://www.vb-net.com/AspNet-DocAndSamples-2017/aspnetcore/mvc/controllers/application-model.htm

 

下面一个例子

Sample: Custom Routing Convention

You can use an IApplicationModelConvention to customize how routing works. For example, the following convention will incorporate Controllers’ namespaces into their routes, replacing . in the namespace with / in the route:

[!code-csharpMain]

   1:  using Microsoft.AspNetCore.Mvc.ApplicationModels;
   2:  using System.Linq;
   3:   
   4:  namespace AppModelSample.Conventions
   5:  {
   6:      public class NamespaceRoutingConvention : IApplicationModelConvention
   7:      {
   8:          public void Apply(ApplicationModel application)
   9:          {
  10:              foreach (var controller in application.Controllers)
  11:              {
  12:                  var hasAttributeRouteModels = controller.Selectors
  13:                      .Any(selector => selector.AttributeRouteModel != null);
  14:   
  15:                  if (!hasAttributeRouteModels
  16:                      && controller.ControllerName.Contains("Namespace")) // affect one controller in this sample
  17:                  {
  18:                      // Replace the . in the namespace with a / to create the attribute route
  19:                      // Ex: MySite.Admin namespace will correspond to MySite/Admin attribute route
  20:                      // Then attach [controller], [action] and optional {id?} token.
  21:                      // [Controller] and [action] is replaced with the controller and action
  22:                      // name to generate the final template
  23:                      controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
  24:                      {
  25:                          Template = controller.ControllerType.Namespace.Replace('.', '/') + "/[controller]/[action]/{id?}"
  26:                      };
  27:                  }
  28:              }
  29:   
  30:              // You can continue to put attribute route templates for the controller actions depending on the way you want them to behave
  31:          }
  32:      }
  33:  }

 

The convention is added as an option in Startup.

[!code-csharpMain]

   1:  using AppModelSample.Conventions;
   2:  using Microsoft.AspNetCore.Builder;
   3:  using Microsoft.AspNetCore.Hosting;
   4:  using Microsoft.Extensions.Configuration;
   5:  using Microsoft.Extensions.DependencyInjection;
   6:  using Microsoft.Extensions.Logging;
   7:   
   8:  namespace AppModelSample
   9:  {
  10:      public class Startup
  11:      {
  12:          public Startup(IHostingEnvironment env)
  13:          {
  14:              var builder = new ConfigurationBuilder()
  15:                  .SetBasePath(env.ContentRootPath)
  16:                  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  17:                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
  18:                  .AddEnvironmentVariables();
  19:              Configuration = builder.Build();
  20:          }
  21:   
  22:          public IConfigurationRoot Configuration { get; }
  23:   
  24:          // This method gets called by the runtime. Use this method to add services to the container.
  25:          #region ConfigureServices
  26:          public void ConfigureServices(IServiceCollection services)
  27:          {
  28:              services.AddMvc(options =>
  29:              {
  30:                  options.Conventions.Add(new ApplicationDescription("My Application Description"));
  31:                  options.Conventions.Add(new NamespaceRoutingConvention());
  32:                  //options.Conventions.Add(new IdsMustBeInRouteParameterModelConvention());
  33:              });
  34:          }
  35:          #endregion
  36:   
  37:          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  38:          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  39:          {
  40:              loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  41:              loggerFactory.AddDebug();
  42:   
  43:              if (env.IsDevelopment())
  44:              {
  45:                  app.UseDeveloperExceptionPage();
  46:                  app.UseBrowserLink();
  47:              }
  48:              else
  49:              {
  50:                  app.UseExceptionHandler("/Home/Error");
  51:              }
  52:   
  53:              app.UseStaticFiles();
  54:   
  55:              app.UseMvc(routes =>
  56:              {
  57:                  routes.MapRoute(
  58:                      name: "default",
  59:                      template: "{controller=Home}/{action=Index}/{id?}");
  60:              });
  61:          }
  62:      }
  63:  }

 

[!TIP] You can add conventions to your (xref:)middleware by accessing MvcOptions using services.Configure<MvcOptions>(c => c.Conventions.Add(YOURCONVENTION));

This sample applies this convention to routes that are not using attribute routing where the controller has “Namespace” in its name. The following controller demonstrates this convention:

[!code-csharpMain]

ControllerActionDescriptorBuilder->ApplicationModelFactory->ApplicationModelConventions->IApplicationModelProvider

解决了我的问题。

根据dll的名称来 改变路由。

代码的确是很复杂。

原文地址:http://www.cnblogs.com/forhell/p/16907566.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性