上次,我们判断了《当前请求是否健康检查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
}