You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
4.4 KiB
127 lines
4.4 KiB
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.ActionConstraints;
|
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
using Microsoft.AspNetCore.Mvc.Routing;
|
|
using Microsoft.AspNetCore.Routing.Template;
|
|
using SqlSugar;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Wood.Util;
|
|
|
|
namespace Wood.Admin.WebApi
|
|
{
|
|
/// <summary>
|
|
/// 自动扫描所有带service名称的程序集
|
|
/// 扫描程序集中所有带service后缀的类
|
|
/// 给类中所有public 方法注册路由
|
|
/// </summary>
|
|
public class AutoRouteConvention : IApplicationModelConvention
|
|
{
|
|
private readonly string _baseRoutePrefix = "api";
|
|
|
|
/// <summary>
|
|
/// 应用路由规则
|
|
/// get 开头为 get
|
|
/// 其他为post
|
|
/// </summary>
|
|
/// <param name="application"></param>
|
|
public void Apply(ApplicationModel application)
|
|
{
|
|
foreach (var controller in application.Controllers)
|
|
{
|
|
var controllerName = controller.ControllerName.ToLowerInvariant().Replace("service", "");
|
|
|
|
foreach (var action in controller.Actions)
|
|
{
|
|
var actionName = action.ActionName.ToLowerInvariant();
|
|
var httpMethod = "POST";
|
|
var isGetMethod = false;
|
|
if (!action.Selectors.Any() || !action.Selectors[0].ActionConstraints.Any())
|
|
{
|
|
if (actionName.StartsWith("get"))
|
|
{
|
|
httpMethod = "GET";
|
|
actionName = actionName.Substring(3);
|
|
isGetMethod = true;
|
|
}
|
|
else if (actionName.StartsWith("post"))
|
|
{
|
|
httpMethod = "POST";
|
|
actionName = actionName.Substring(4);
|
|
}
|
|
|
|
// 构建路由模板
|
|
var routeTemplate = $"{_baseRoutePrefix}/{controllerName}/{actionName}";
|
|
|
|
if (action.Selectors.Any())
|
|
{
|
|
//当前已经有了 Selectors 信息则直接设置
|
|
action.Selectors[0].AttributeRouteModel = new AttributeRouteModel { Template = routeTemplate };
|
|
action.Selectors[0].ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
|
|
}
|
|
else
|
|
{
|
|
//当前没有 Selectors 信息则直接新增
|
|
var selectorModel = new SelectorModel
|
|
{
|
|
AttributeRouteModel = new AttributeRouteModel { Template = routeTemplate },
|
|
};
|
|
selectorModel.ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
|
|
|
|
action.Selectors.Add(selectorModel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 构建路由模板
|
|
var routeTemplate = $"{_baseRoutePrefix}/{controllerName}/{actionName}";
|
|
//重新指定路由路径
|
|
action.Selectors[0].AttributeRouteModel = new AttributeRouteModel { Template = routeTemplate };
|
|
//是否get请求
|
|
isGetMethod = action.Attributes.Any(it => it.GetType() == typeof(HttpGetAttribute));
|
|
}
|
|
|
|
//查找所有没有绑定来源的参数
|
|
IEnumerable<ParameterModel> noBindModels = action.Parameters.Where(it => it.BindingInfo == null);
|
|
|
|
if (noBindModels.Any())
|
|
{
|
|
// 设置参数来源:GET 请求的参数来自 URL,POST 请求的参数来自请求体
|
|
// 只会设置没有明确指定来源的参数
|
|
// Get 会加上 FromQuery
|
|
// Post 会加上 FromBody (只有第一个参数加上 Frombody 多个参数会报错!)
|
|
if (isGetMethod)
|
|
{
|
|
foreach (var parameter in noBindModels)
|
|
{
|
|
var bindId = parameter.BindingInfo?.BindingSource?.Id;
|
|
if (string.IsNullOrEmpty(bindId))
|
|
{
|
|
// 对于 GET 请求,默认情况下参数应该来自于查询字符串或路径
|
|
parameter.BindingInfo = new BindingInfo() { BindingSource = BindingSource.Query };
|
|
// 对于 GET 请求,默认情况下参数应该来自于 URL
|
|
//parameter.BindingInfo = new BindingInfo() { BindingSource = BindingSource.Path };
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (noBindModels.Count() > 1)
|
|
throw Oops.Oh($"系统不支持Post请求FromBody绑定多个参数,请改成一个。路径:Controller({controller.ControllerName})Action({action.ActionName})");
|
|
else
|
|
{
|
|
if (action.Parameters.Any(it => it.BindingInfo?.BindingSource?.Id == "Body"))
|
|
throw Oops.Oh($"系统不支持Post请求FromBody绑定多个参数,请改成一个。路径:Controller({controller.ControllerName})Action({action.ActionName})");
|
|
noBindModels.First().BindingInfo = new BindingInfo() { BindingSource = BindingSource.Body };
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|