Web Api帮助页面来自多个文件的XML注释

时间:2014-03-04 07:37:39

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

我的Web api项目中有不同的插件和自己的XML文档,并且有一个集中的帮助页面,但问题是Web Api的默认帮助页面仅支持单个文档文件

new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/Documentation.xml"))

如何从不同的文件加载配置?我想这样做:

new XmlDocumentationProvider("PluginsFolder/*.xml")

4 个答案:

答案 0 :(得分:31)

您可以在XmlDocumentationProvider修改已安装的Areas\HelpPage,执行以下操作:

将多个Xml文档文件合并为一个文件:

示例代码(缺少一些错误检查和验证):

using System.Xml.Linq;
using System.Xml.XPath;

 XDocument finalDoc = null;
 foreach (string file in Directory.GetFiles(@"PluginsFolder", "*.xml"))
 {
    if(finalDoc == null)
    {
        finalDoc = XDocument.Load(File.OpenRead(file));
    }
    else
    {
        XDocument xdocAdditional = XDocument.Load(File.OpenRead(file));

        finalDoc.Root.XPathSelectElement("/doc/members")
                     .Add(xdocAdditional.Root.XPathSelectElement("/doc/members").Elements());
    }
}

// Supply the navigator that rest of the XmlDocumentationProvider code looks for
_documentNavigator = finalDoc.CreateNavigator();

答案 1 :(得分:19)

Kirans解决方案非常有效。我最终使用了他的方法,但创建了一个名为 MultiXmlDocumentationProvider XmlDocumentationProvider 的副本,其中包含一个改变的构造函数:

public MultiXmlDocumentationProvider(string xmlDocFilesPath)
{
       XDocument finalDoc = null;
        foreach (string file in Directory.GetFiles(xmlDocFilesPath, "*.xml"))
        {
            using (var fileStream = File.OpenRead(file))
            {
                if (finalDoc == null)
                {
                    finalDoc = XDocument.Load(fileStream);
                }
                else
                {
                    XDocument xdocAdditional = XDocument.Load(fileStream);

                    finalDoc.Root.XPathSelectElement("/doc/members")
                        .Add(xdocAdditional.Root.XPathSelectElement("/doc/members").Elements());
                }
            }
        }

        // Supply the navigator that rest of the XmlDocumentationProvider code looks for
        _documentNavigator = finalDoc.CreateNavigator();
}

我从 HelpPageConfig.cs 注册新的提供者:

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

在升级等时,创建一个新类并保持原始类保持不变可能更方便......

答案 2 :(得分:5)

我没有沿着XmlMultiDocumentationProvider创建一个单独的类,而是在现有的XmlDocumentationProvider中添加了一个构造函数。这需要一个字符串列表,而不是获取文件夹名称,因此您仍然可以准确指定要包含的文件(如果文档XML所在的目录中有其他xml文件,则可能变得毛茸茸)。这是我的新构造函数:

navigationItem.rightBarButtonItems = [aButton, anotherButton, awesomeButton]

HelpPageConfig.cs看起来像这样。 (是的,它可以是更少的行,但我没有行限制所以我喜欢拆分它。)

public XmlDocumentationProvider(IEnumerable<string> documentPaths)
{
    if (documentPaths.IsNullOrEmpty())
    {
        throw new ArgumentNullException(nameof(documentPaths));
    }
    XDocument fullDocument = null;
    foreach (var documentPath in documentPaths)
    {
        if (documentPath == null)
        {
            throw new ArgumentNullException(nameof(documentPath));
        }

        if (fullDocument == null)
        {
            using (var stream = File.OpenRead(documentPath))
            {
                fullDocument = XDocument.Load(stream);
            }
        }
        else
        {
            using (var stream = File.OpenRead(documentPath))
            {
                var additionalDocument = XDocument.Load(stream);
                fullDocument?.Root?.XPathSelectElement("/doc/members").Add(additionalDocument?.Root?.XPathSelectElement("/doc/members").Elements());
            }
        }
    }

    _documentNavigator = fullDocument?.CreateNavigator();
}

答案 3 :(得分:4)

我同意gurra777,创建一个新类是一个更安全的升级路径。我开始使用该解决方案,但它涉及相当数量的复制/意大利面,在一些软件包更新后很容易过时。

相反,我保留了XmlDocumentationProvider个孩子的集合。对于每种实现方法,我都会调用子进程来获取第一个非空结果。

public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
    private IList<XmlDocumentationProvider> _documentationProviders;

    public MultiXmlDocumentationProvider(string xmlDocFilesPath)
    {
        _documentationProviders = new List<XmlDocumentationProvider>();

        foreach (string file in Directory.GetFiles(xmlDocFilesPath, "*.xml"))
        {
            _documentationProviders.Add(new XmlDocumentationProvider(file));
        }
    }

    public string GetDocumentation(System.Reflection.MemberInfo member)
    {
        return _documentationProviders
            .Select(x => x.GetDocumentation(member))
            .FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));
    }

    //and so on...

HelpPageConfig注册与gurra777的答案相同,

config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/")));
相关问题