首页 文章

使Swagger输出IRouteConstraint的描述

提问于
浏览
1

我有一个带有自定义IRouteConstraint的路线 . Swagger生成参数部分,但描述字段始终为空 . 对于其他参数,我正确地从XML注释中获取描述 . 到目前为止我找到的唯一解决方法是添加一个Operation过滤器并在那里设置描述

foreach ( var parameter in operation.Parameters.OfType<NonBodyParameter>() )
        {
            if (parameter.Name == RouteConstraint.Name)
            {
                parameter.Description = GetConstraintDescription();
            }

任何指示swagger从IRouteConstraints的XML注释中获取描述的方法 .

2 回答

  • 0

    我担心唯一的“简单方法”就是你已经实现的(操作过滤器)

    我正在查看项目输出的XML描述

    <?xml version="1.0"?>
    <doc>
        <assembly>
            <name>SwaggerWeb</name>
        </assembly>
        <members>
            <member name="M:SwaggerWeb.Controllers.ValuesController.Get(System.Int32)">
                <summary> Get by ID </summary>
                <param name="id">The value ID</param>
                <returns></returns>
            </member>
            <member name="T:SwaggerWeb.SectorRouteConstraint">
                <summary> Sector constraint </summary>
            </member>
        </members>
    </doc>
    

    您可以尝试使您的过滤器更通用,并从XML中获取描述,但除此之外我没有看到任何其他方式 .

  • 0

    我目前的解决方案是这个类,基于Swashbuckle XmlCommentsOperationFilter .

    public class RouteConstraintXmlDocsOperationFilter:IOperationFilter
    {
        private readonly XPathNavigator _xmlNavigator;
        private const string MemberXPath = "/doc/members/member[@name='{0}']";
        private const string SummaryXPath = "summary";
    
    
        public RouteConstraintXmlDocsOperationFilter(string filePath)
        {
            XPathDocument xmlDoc = new XPathDocument(filePath);
            _xmlNavigator = xmlDoc.CreateNavigator();
        }
    
    
        public void Apply(Operation operation, OperationFilterContext context)
        {
            ApplyConstraintsXmlToActionParameters(operation.Parameters, context.ApiDescription);
        }
    
        private void ApplyConstraintsXmlToActionParameters(IList<IParameter> parameters, ApiDescription apiDescription)
        {
            var nonBodyParameters = parameters.OfType<NonBodyParameter>();
            foreach (var parameter in nonBodyParameters)
            {                // Check for a corresponding action parameter?
                var actionParameter = apiDescription.ParameterDescriptions.FirstOrDefault(p =>
                    parameter.Name.Equals(p.Name, StringComparison.OrdinalIgnoreCase));
                if (actionParameter == null) continue;
    
                if (!actionParameter.RouteInfo.Constraints.Any()) continue;
    
                var constraintType = actionParameter.RouteInfo.Constraints.FirstOrDefault().GetType();
                var commentIdForType = XmlCommentsIdHelper.GetCommentIdForType(constraintType);
                var constraintSummaryNode = _xmlNavigator
                    .SelectSingleNode(string.Format(MemberXPath, commentIdForType))
                    ?.SelectSingleNode(SummaryXPath);
                if (constraintSummaryNode != null)
                {
                    parameter.Description = XmlCommentsTextHelper.Humanize(constraintSummaryNode.InnerXml);
                }
            }
        }
    }
    

    设置:

    services.AddSwaggerGen(o =>
            {
                var fileName = GetType().GetTypeInfo().Module.Name.Replace(".dll", ".xml").Replace(".exe", ".xml");
                o.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, fileName));
                o.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
                o.OperationFilter<RouteConstraintXmlDocsOperationFilter>(Path.Combine(AppContext.BaseDirectory, fileName));
            })
    

相关问题