代码之家  ›  专栏  ›  技术社区  ›  Kirk Woll

Web Api的Xml文档如何包含主项目之外的文档?

  •  107
  • Kirk Woll  · 技术社区  · 12 年前

    这个 documentation 用于将XmlDoc集成到WebApi项目中的,似乎只处理所有Api类型都是WebApi的一部分的情况。特别是,它讨论了如何将XML文档重新路由到 App_Data/XmlDocument.xml 并在配置中取消注释将使用该文件的一行。这隐含地只允许一个项目的文档文件。

    然而,在我的设置中,我在一个通用的“模型”项目中定义了请求和响应类型。这意味着如果我定义了一个端点,例如:

    [Route("auth/openid/login")]
    public async Task<AuthenticationResponse> Login(OpenIdLoginRequest request) { ... }
    

    哪里 OpenIdLoginRequest 在单独的C#项目中定义,如下所示:

    public class OpenIdLoginRequest
    {
        /// <summary>
        /// Represents the OpenId provider that authenticated the user. (i.e. Facebook, Google, etc.)
        /// </summary>
        [Required]
        public string Provider { get; set; }
    
        ...
    }
    

    尽管有XML文档注释 request 当您查看特定于端点的帮助页面(即。 http://localhost/Help/Api/POST-auth-openid-login ).

    如何才能使包含XML文档的子项目中的类型在Web API XML文档中浮出水面?

    5 回复  |  直到 12 年前
        1
  •  169
  •   Pishang Ujeniya Kirk Woll    6 年前

    没有内置的方法来实现这一点。然而,它只需要几个步骤:

    1. 为子项目启用XML文档(从项目财产/构建),就像为Web API项目启用一样。除此之外,请将其直接发送到 XmlDocument.xml 以便在项目的根文件夹中生成。

    2. 修改Web API项目的postbuild事件以将此XML文件复制到 App_Data 文件夹:

      copy "$(SolutionDir)SubProject\XmlDocument.xml" "$(ProjectDir)\App_Data\Subproject.xml"
      

      哪里 Subproject.xml 应重命名为项目的加号 .xml .

    3. 下一个打开 Areas\HelpPage\App_Start\HelpPageConfig 并找到以下行:

      config.SetDocumentationProvider(new XmlDocumentationProvider(
          HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
      

      这是您最初取消注释的行,以便首先启用XML帮助文档。将该行替换为:

      config.SetDocumentationProvider(new XmlDocumentationProvider(
          HttpContext.Current.Server.MapPath("~/App_Data")));
      

      该步骤确保 XmlDocumentationProvider 传递给包含XML文件的目录,而不是项目的特定XML文件。

    4. 最后,修改 Areas\HelpPage\XmlDocumentationProvider 以以下方式:

      a.更换 _documentNavigator 字段:

      private List<XPathNavigator> _documentNavigators = new List<XPathNavigator>();
      

      b.将构造函数替换为:

      public XmlDocumentationProvider(string appDataPath)
      {
          if (appDataPath == null)
          {
              throw new ArgumentNullException("appDataPath");
          }
      
          var files = new[] { "XmlDocument.xml", "Subproject.xml" };
          foreach (var file in files)
          {
              XPathDocument xpath = new XPathDocument(Path.Combine(appDataPath, file));
              _documentNavigators.Add(xpath.CreateNavigator());
          }
      }
      

      c.在构造函数下面添加以下方法:

      private XPathNavigator SelectSingleNode(string selectExpression)
      {
          foreach (var navigator in _documentNavigators)
          {
              var propertyNode = navigator.SelectSingleNode(selectExpression);
              if (propertyNode != null)
                  return propertyNode;
          }
          return null;
      }
      

      d.最后,修复所有导致引用的编译器错误(应该有三个) _documentNavigator.SelectSingleNode 并删除 _documentNavigator. 部分,以便现在调用新的 SelectSingleNode 我们在上面定义的方法。

    最后一步是修改文档提供程序以支持在多个XML文档中查找帮助文本,而不仅仅是主项目的帮助文本。

    现在,当您检查帮助文档时,它将包括相关项目中类型的XML文档。

        2
  •  32
  •   Pathoschild    8 年前

    我也遇到过这种情况,但我不想编辑或复制任何生成的代码以避免以后出现问题。

    在其他答案的基础上,这里有一个用于多个XML源的独立文档提供程序。只需将其放入项目中:

    /// <summary>A custom <see cref="IDocumentationProvider"/> that reads the API documentation from a collection of XML documentation files.</summary>
    public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
    {
        /*********
        ** Properties
        *********/
        /// <summary>The internal documentation providers for specific files.</summary>
        private readonly XmlDocumentationProvider[] Providers;
    
    
        /*********
        ** Public methods
        *********/
        /// <summary>Construct an instance.</summary>
        /// <param name="paths">The physical paths to the XML documents.</param>
        public MultiXmlDocumentationProvider(params string[] paths)
        {
            this.Providers = paths.Select(p => new XmlDocumentationProvider(p)).ToArray();
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetDocumentation(MemberInfo subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetDocumentation(Type subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetDocumentation(HttpControllerDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetDocumentation(HttpActionDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetDocumentation(HttpParameterDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }
    
        /// <summary>Gets the documentation for a subject.</summary>
        /// <param name="subject">The subject to document.</param>
        public string GetResponseDocumentation(HttpActionDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetResponseDocumentation(subject));
        }
    
    
        /*********
        ** Private methods
        *********/
        /// <summary>Get the first valid result from the collection of XML documentation providers.</summary>
        /// <param name="expr">The method to invoke.</param>
        private string GetFirstMatch(Func<XmlDocumentationProvider, string> expr)
        {
            return this.Providers
                .Select(expr)
                .FirstOrDefault(p => !String.IsNullOrWhiteSpace(p));
        }
    }
    

    …并在您的 HelpPageConfig 包含所需XML文档的路径:

    config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/Api.xml"), HttpContext.Current.Server.MapPath("~/App_Data/Api.Models.xml")));
    
        3
  •  5
  •   Community Mohan Dere    9 年前

    一种更简单的方法是合并xml文件。以下回复中的示例代码:

    Web Api Help Page XML comments from more than 1 files

        4
  •  0
  •   Ziregbe Otee    9 年前

    解决此问题的最简单方法是在您部署的服务器上创建App_Code文件夹。然后将bin文件夹中的XmlDocument.xml本地复制到App_Code文件夹中

        5
  •  0
  •   user1768874    5 年前

    我找到了更好的解决方案

    1. 转到解决方案的财产,然后在“构建、输出、文档XML文件”中填充应用程序数据上的文件夹。

    2. 像这样添加一行包含要插入到文档中的文件。

    config.SetDocumentationProvider(新的XmlDocumentationProvider( HttpContext.Current.Server.MapPath(“~/App_Data/FenixCorpore.API.xml”));

            config.SetDocumentationProvider(new XmlDocumentationProvider(
                HttpContext.Current.Server.MapPath("~/App_Data/FenixCorporate.Entities.xml")));