Files

38 lines
2.1 KiB
C#

using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Store.Users.Controllers;
internal static class UserRoutingChecks
{
public static void Run()
{
// 经真实 MVC 模型构建流程验证约定,不只是检查特性或直接调用 Apply。
var services = new ServiceCollection();
services.AddLogging();
services.AddControllers().AddApplicationPart(typeof(UserController).Assembly);
using var provider = services.BuildServiceProvider();
var actions = provider.GetRequiredService<IActionDescriptorCollectionProvider>().ActionDescriptors.Items
.OfType<ControllerActionDescriptor>().Where(a => a.ControllerTypeInfo.AsType() == typeof(UserController)).ToArray();
if (actions.Length != 19) throw new Exception("用户控制器操作发现数量错误");
foreach (var action in actions)
{
var method = "POST";
var constraint = action.ActionConstraints!.OfType<HttpMethodActionConstraint>().Single();
var metadata = action.EndpointMetadata.OfType<IHttpMethodMetadata>().Single();
if (!constraint.HttpMethods.SequenceEqual([method]) || !metadata.HttpMethods.SequenceEqual([method]))
throw new Exception($"{action.ActionName} 的方法约束或端点元数据错误");
}
var descriptions = provider.GetRequiredService<IApiDescriptionGroupCollectionProvider>().ApiDescriptionGroups.Items
.SelectMany(g => g.Items).Where(d => d.ActionDescriptor is ControllerActionDescriptor a
&& a.ControllerTypeInfo.AsType() == typeof(UserController)).ToArray();
if (descriptions.Length != actions.Length || descriptions.Any(d => d.HttpMethod !=
"POST"))
throw new Exception("用户接口文档的 HTTP 方法错误");
Console.WriteLine("PASS: User 统一 POST、路由约束、端点元数据和接口文档验证通过。");
}
}