C# WebAPI routing configuration

Background: In the process of developing the project, a new controller was created, and it was found that vs would directly add a prefix to the controller header, such as [Route("api/[controller]")], that is, when accessing the interface, it will become http://localhost:8000/api/values, but if there are many controllers, or when version iteration is to be performed, we will find that a painful moment has come, and we need to modify them one by one.

 

If you can configure the prefix globally at this time, it is really a blessing, just modify one place. Let's use it for this purpose.

1. We need to use the IApplicationModelConvention interface, which is located under the command space of Microsoft.AspNetCore.Mvc.ApplicationModels

ApiExplorerModel: including description information, group information, visibility, etc.

ControllerModel: It is mainly related to the default agreement of the Comtroller. There are many things in it, including the controller name, routing value, Actions, etc. Our next configuration will also be expanded here

IFilterMetadata: an empty interface, which mainly serves as a marker.

2. Configuration

Step 1: First define a class to implement the IApplicationModelConvention interface.

using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebAPI.Controllers
{
    public class RouteConvention: IApplicationModelConvention
    {
        /// <summary>
        /// 定义一个路由前缀变量
        /// </summary>
        private readonly AttributeRouteModel _centralPrefix;
        /// <summary>
        /// 调用时传入指定的路由前缀
        /// </summary>
        /// <param name="routeTemplateProvider"></param>
        public RouteConvention(IRouteTemplateProvider routeTemplateProvider)
        {
            _centralPrefix = new AttributeRouteModel(routeTemplateProvider);
        }

        //接口的Apply方法
        public void Apply(ApplicationModel application)
        {
            //遍历所有的 Controller
            foreach (var controller in application.Controllers)
            {
                // 1、已经标记了 RouteAttribute 的 Controller
                //这一块需要注意,如果在控制器中已经标注有路由了,则会在路由的前面再添加指定的路由内容。

                var matchedselectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
                if (matchedselectors.Any())
                {
                    foreach (var selectorModel in matchedselectors)
                    {
                        // 在 当前路由上 再 添加一个 路由前缀
                        selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_centralPrefix,
                          selectorModel.AttributeRouteModel);
                    }
                }

                //2、 没有标记 RouteAttribute 的 Controller
                var unmatchedselectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
                if (unmatchedselectors.Any())
                {
                    foreach (var selectorModel in unmatchedselectors)
                    {
                        // 添加一个 路由前缀
                        selectorModel.AttributeRouteModel = _centralPrefix;
                    }
                }
            }
        }
    }
}

Step 2: After adding the above, let's define a class to insert our route.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebAPI.Controllers
{
    public static class MvcOptionsExtensions
    {
        /// <summary>
        /// 扩展方法
        /// </summary>
        /// <param name="opts"></param>
        /// <param name="routeAttribute"></param>
        public static void UseCentralRoutePrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute)
        {
            // 添加我们自定义 实现IApplicationModelConvention的RouteConvention
            opts.Conventions.Insert(0, new RouteConvention(routeAttribute));
        }
    }
}

Step 3: Add configuration information to the ConfigureServices method in startup.cs

#region 配置全局路由
            //在各个控制器添加前缀(没有特定的路由前面添加前缀)
            services.AddMvc(opt =>
            {
                opt.UseCentralRoutePrefix(new RouteAttribute("lg/v1/[action]"));
                //opt.UseCentralRoutePrefix(new RouteAttribute("api/[controller]/[action]"));
            });
            #endregion

Step 4: Run

Guess you like

Origin blog.csdn.net/qq_26695613/article/details/129321277