前言
上次,我们判断了《当前请求是否健康检查API》,避免其写入日志。
但是,对于我们自己开发的API来说,最好也能来区分,比如调试用API,就不需要再写调用日志了。
DisplayName方式
直接判断路由地址的方式就不考虑了。
本来想使用和上次一样的DisplayName方式,但是发现没有地方为Controller设置。
查看源码,发现Action的DisplayName属性的实现在ControllerActionDescriptor.cs:
public override string? DisplayName
{get{if (base.DisplayName == null && ControllerTypeInfo != null && MethodInfo != null){base.DisplayName = string.Format(CultureInfo.InvariantCulture,"{0}.{1} ({2})",TypeNameHelper.GetTypeDisplayName(ControllerTypeInfo),MethodInfo.Name,ControllerTypeInfo.Assembly.GetName().Name);}return base.DisplayName!;}set{if (value == null){throw new ArgumentNullException(nameof(value));}base.DisplayName = value;}
}
DisplayName是由"Controller类名.方法名 (Assembly名)"组成。
如果你的Controller类名/方法名命名有规律,可以考虑DisplayName方式。
Metadata方式
此路不通,考虑其他方式。
我们知道将Controller的方法添加为API端点是通过endpoints.MapControllers();
,查看其实现源码,最终定位到ActionEndpointFactory.cs,其中有这样一段代码:
// MVC guarantees that when two of it's endpoints have the same route name they are equivalent.
//
// The case for this looks like:
//
// [HttpGet]
// [HttpPost]
// [Route("/Foo", Name = "Foo")]
// public void DoStuff() { }
//
// However, Endpoint Routing requires Endpoint Names to be unique.
//
// We can use the route name as the endpoint name if it's not set. Note that there's no
// attribute for this today so it's unlikley. Using endpoint name on a
if (routeName != null &&
!suppressLinkGeneration &&
routeNames.Add(routeName) &&
builder.Metadata.OfType<IEndpointNameMetadata>().LastOrDefault()?.EndpointName == null)
{
builder.Metadata.Add(new EndpointNameMetadata(routeName));
}
通过注释,我们可以知道Asp.Net Core会把RouteName写入端点的Metadata属性。
那么,我们只需要判断EndpointNameMetadata即可:
var endpointName = context.GetEndpoint()?.Metadata.GetMetadata<EndpointNameMetadata>()?.EndpointName;
if (!string.IsNullOrEmpty(endpointName) && endpointName.StartsWith("Debug_"))
{
}
else
{//Log
}
结论
如果你有更好的实现方式,欢迎到公众号后台留言告诉我。