【问题标题】:Web API Help pages - customizing Property documentationWeb API 帮助页面 - 自定义属性文档
【发布时间】:2013-08-15 15:30:13
【问题描述】:

我有我的 web api,我添加了 web api help pages 来自动生成我的文档。它对于列出我的参数的方法非常有用,但我有一个这样的方法:

public SessionResult PostLogin(CreateSessionCommand request)

而且,在我的帮助页面上,它只在属性部分列出命令参数。但是,在示例请求部分,它列出了我的 CreateSessionCommand 类的所有属性。

参数

姓名 |说明 |补充资料

请求 |没有可用的文档。 |在请求正文中定义此参数。

我希望它列出我的CreateSessionCommand 类中的所有属性。有没有简单的方法可以做到这一点?

【问题讨论】:

    标签: asp.net-mvc-4 asp.net-web-api documentation asp.net-web-api-helppages


    【解决方案1】:

    所以,我设法为这个问题设计了一个解决方法,以防万一有人感兴趣。

    在 HelpPageConfigurationExtensions.cs 我添加了以下扩展方法:

    public static void AlterApiDescription(this ApiDescription apiDescription, HttpConfiguration config)
    {
        var docProvider = config.Services.GetDocumentationProvider();
        var addParams = new List<ApiParameterDescription>();
        var removeParams = new List<ApiParameterDescription>();
    
        foreach (var param in apiDescription.ParameterDescriptions)
        {
            var type = param.ParameterDescriptor.ParameterType;
    
            //string is some special case that is not a primitive type
            //also, compare by full name because the type returned does not seem to match the types generated by typeof
            bool isPrimitive = type.IsPrimitive || String.Compare(type.FullName, typeof(string).FullName) == 0;
    
            if (!isPrimitive)
            {
                var properties = from p in param.ParameterDescriptor.ParameterType.GetProperties() 
                                   let s = p.SetMethod 
                                   where s.IsPublic 
                                   select p;
    
                foreach (var property in properties)
                {
                    var documentation = docProvider.GetDocumentation(new System.Web.Http.Controllers.ReflectedHttpParameterDescriptor()
                    {
                        ActionDescriptor = param.ParameterDescriptor.ActionDescriptor,
                        ParameterInfo = new CustomParameterInfo(property)
                    });
    
                    addParams.Add(new ApiParameterDescription()
                    {
                        Documentation = documentation,
                        Name = property.Name,
                        Source = ApiParameterSource.FromBody,
                        ParameterDescriptor = param.ParameterDescriptor
                    });
                }
    
                //since this is a complex type, select it to be removed from the api description
                removeParams.Add(param);
            }
        }
    
        //add in our new items
        foreach (var item in addParams)
        {
            apiDescription.ParameterDescriptions.Add(item);
        }
    
        //remove the complex types
        foreach (var item in removeParams)
        {
            apiDescription.ParameterDescriptions.Remove(item);
        }
    }
    

    这是我使用的参数信息实例类

    internal class CustomParameterInfo : ParameterInfo
    {
        public CustomParameterInfo(PropertyInfo prop)
        {
            base.NameImpl = prop.Name;
        }
    }
    

    然后,我们在扩展类中的另一个方法中调用扩展

    public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId)
    {
        object model;
        string modelId = ApiModelPrefix + apiDescriptionId;
        if (!config.Properties.TryGetValue(modelId, out model))
        {
            Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions;
            ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase));
            if (apiDescription != null)
            {
                apiDescription.AlterApiDescription(config);
    
                HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
                model = GenerateApiModel(apiDescription, sampleGenerator);
                config.Properties.TryAdd(modelId, model);
            }
        }
    
        return (HelpPageApiModel)model;
    }
    

    用于此的 cmets 必须添加到控制器方法中,而不是类对象的属性中。这可能是因为我的对象是外部库的一部分

    【讨论】:

      【解决方案2】:

      这应该作为@Josh 答案的补充。如果您不仅要列出模型类中的属性,还要包含每个属性的文档,则应将 Areas/HelpPage/XmlDocumentationProvider.cs 文件修改如下:

      public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
      {
          ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
          if (reflectedParameterDescriptor != null)
          {
              if (reflectedParameterDescriptor.ParameterInfo is CustomParameterInfo)
              {
                  const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
                  var pi = (CustomParameterInfo) reflectedParameterDescriptor.ParameterInfo;
      
                  string selectExpression = String.Format(CultureInfo.InvariantCulture, PropertyExpression, pi.Prop.DeclaringType.FullName + "." + pi.Prop.Name); 
                  XPathNavigator methodNode = _documentNavigator.SelectSingleNode(selectExpression);
                  if (methodNode != null)
                  {
                      return methodNode.Value.Trim();
                  }
              }
              else
              {
                  XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
                  if (methodNode != null)
                  {
                      string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
                      XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
                      if (parameterNode != null)
                      {
                          return parameterNode.Value.Trim();
                      }
                  }                    
              }
          }
      
          return null;
      }
      

      CustomParameterInfo 类也应该保留属性信息:

      internal class CustomParameterInfo : ParameterInfo
      {
          public PropertyInfo Prop { get; private set; }
      
          public CustomParameterInfo(PropertyInfo prop)
          {
              Prop = prop;
              base.NameImpl = prop.Name;
          }
      }
      

      【讨论】:

        【解决方案3】:

        目前不支持开箱即用。以下错误与此有关: http://aspnetwebstack.codeplex.com/workitem/877

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-24
          • 1970-01-01
          • 2014-12-27
          • 1970-01-01
          • 2016-07-17
          • 1970-01-01
          • 2016-12-08
          • 1970-01-01
          相关资源
          最近更新 更多