web-dev-qa-db-ja.com

Web ApiのXMLドキュメントには、メインプロジェクト以外のドキュメントを含めることができますか?

Web ApiプロジェクトへのXmlDoc統合を有効にする documentation は、すべてのAPIタイプがWebApiプロジェクトの一部である状況のみを処理するように見えます。特に、XMLドキュメントをApp_Data/XmlDocument.xmlに再ルーティングし、そのファイルを使用する構成内の行のコメントを解除する方法について説明します。これにより、1つのプロジェクトのドキュメントファイルのみが暗黙的に許可されます。

ただし、セットアップでは、一般的な「モデル」プロジェクトで定義された要求と応答のタイプがあります。これは、次のようなエンドポイントが定義されている場合:

[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ドキュメントに表示されるようにするにはどうすればよいですか?

100
Kirk Woll

これを実現する組み込みの方法はありません。ただし、必要な手順はわずかです。

  1. Web APIプロジェクトの場合と同様に、サブプロジェクトのXMLドキュメントを(プロジェクトプロパティ/ビルドから)有効にします。今回を除き、直接XmlDocument.xmlこれにより、プロジェクトのルートフォルダに生成されます。

  2. Web APIプロジェクトのポストビルドイベントを変更して、このXMLファイルをApp_Dataフォルダー:

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

    どこ Subproject.xmlは、プロジェクトの名前にプラス.xml

  3. 次に開くAreas\HelpPage\HelpPageConfigそして次の行を見つけます。

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

    これは、最初にXMLヘルプドキュメントを有効にするために最初にコメント解除した行です。その行を次のように置き換えます。

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

    この手順により、プロジェクトの特定のXMLファイルではなく、XMLファイルを含むディレクトリにXmlDocumentationProviderが確実に渡されます。

  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。最後に、すべてのコンパイラエラー(3つあります)を修正して、_documentNavigator.SelectSingleNode_documentNavigator.部分。これにより、上記で定義した新しいSelectSingleNodeメソッドが呼び出されます。

この最後の手順では、ドキュメントプロバイダーを変更して、プライマリプロジェクトだけでなく、ヘルプテキストを複数のXMLドキュメント内で検索できるようにします。

ヘルプドキュメントを調べると、関連プロジェクトのタイプのXMLドキュメントが含まれるようになります。

160
Kirk Woll

私もこれに遭遇しましたが、後で発生する問題を回避するために、生成されたコードを編集または複製したくありませんでした。

他の答えに基づいて、複数の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")));
30
Pathoschild

これを行うもう1つの簡単な方法は、xmlファイルをマージすることです。私の以下の返信のコード例:

複数のファイルからのWeb ApiヘルプページXMLコメント

5
Kiran Challa

この問題を修正する最も簡単な方法は、展開したサーバーにApp_Codeフォルダーを作成することです。次に、binフォルダーにあるXmlDocument.xmlをローカルでApp_Codeフォルダーにコピーします

0
Ziregbe Otee

ここで回答リンクを提供します。複数のXMLファイルをドキュメントに簡単に使用できます。

複数のファイルからのWeb ApiヘルプページXMLコメント

0
Shekhar Patel