เอกสาร Xml สำหรับ Web Api จะรวมเอกสารจากนอกเหนือจากโครงการหลักได้อย่างไร


102

เอกสารสำหรับการเปิดใช้บูรณาการ XMLDOC เป็นโครงการ Api เว็บของคุณจะปรากฏขึ้นเพื่อสถานการณ์ที่จับเฉพาะที่ทุกประเภท API ของคุณเป็นส่วนหนึ่งของโครงการ WebAPI ของคุณ โดยเฉพาะอย่างยิ่งจะกล่าวถึงวิธีการกำหนดเส้นทางเอกสาร XML ใหม่App_Data/XmlDocument.xmlและการยกเลิกการใส่เครื่องหมายบรรทัดใน config ของคุณที่จะใช้ไฟล์นั้น โดยปริยายนี้อนุญาตให้ใช้ไฟล์เอกสารของโครงการเดียวเท่านั้น

อย่างไรก็ตามในการตั้งค่าของฉันฉันมีคำขอและประเภทการตอบกลับที่กำหนดไว้ในโครงการ "โมเดล" ทั่วไป ซึ่งหมายความว่าหากฉันมีจุดสิ้นสุดที่กำหนดไว้เช่น:

[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 ได้อย่างไร

คำตอบ:


165

ไม่มีวิธีในตัวเพื่อให้บรรลุเป้าหมายนี้ อย่างไรก็ตามต้องใช้เพียงไม่กี่ขั้นตอน:

  1. เปิดใช้งานเอกสาร XML สำหรับโปรเจ็กต์ย่อยของคุณ (จากคุณสมบัติโปรเจ็กต์ / บิลด์) เช่นเดียวกับที่คุณมีสำหรับโปรเจ็กต์ Web API ของคุณ ยกเว้นเวลานี้กำหนดเส้นทางโดยตรงเพื่อXmlDocument.xmlให้สร้างขึ้นในโฟลเดอร์รูทของโปรเจ็กต์

  2. แก้ไขเหตุการณ์ postbuild ของโครงการ Web API ของคุณเพื่อคัดลอกไฟล์ 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ด้วยวิธีต่อไปนี้:

    ก. แทนที่_documentNavigatorฟิลด์ด้วย:

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

    ข. แทนที่ตัวสร้างด้วย:

    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());
        }
    }

    ค. เพิ่มวิธีการต่อไปนี้ด้านล่างตัวสร้าง:

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

    ง. และสุดท้ายแก้ไขข้อผิดพลาดของคอมไพเลอร์ทั้งหมด (ควรมีสามข้อ) ส่งผลให้มีการอ้างอิง_documentNavigator.SelectSingleNodeและลบ_documentNavigator.ส่วนออกเพื่อให้เรียกใช้SelectSingleNodeวิธีการใหม่ที่เรากำหนดไว้ข้างต้น

ขั้นตอนสุดท้ายนี้คือสิ่งที่ปรับเปลี่ยนผู้ให้บริการเอกสารเพื่อรองรับการค้นหาเอกสาร XML หลายชุดสำหรับข้อความช่วยเหลือแทนที่จะเป็นเพียงโครงการหลัก

ตอนนี้เมื่อคุณตรวจสอบเอกสารวิธีใช้ของคุณจะมีเอกสาร XML จากประเภทในโครงการที่เกี่ยวข้องของคุณ


7
คำตอบที่ยอดเยี่ยม ฉันคิดว่ามันง่ายกว่าเล็กน้อยสำหรับตัวสร้างในการยอมรับอาร์เรย์ของสตริง: XmlDocumentationProvider สาธารณะ (สตริง appDataPath) และระบุรายการนี้ในตัวให้บริการเอกสาร
กัปตันจอห์น

14
ยอดเยี่ยมนี่คือสิ่งที่ฉันกำลังมองหา !! แนะนำให้แทนที่var files...บรรทัดด้วยvar files = Directory.GetFiles(documentPath, "*.xml");if you (like me) จะไม่ทราบชื่อ / จำนวนไฟล์เอกสาร xml ที่จะอยู่ในนั้นเสมอไป ยังสามารถทำการกรองเพิ่มเติมได้ตามต้องการ
sǝɯɐſ

2
@ Leandro ขอบคุณสำหรับการปรับปรุงคำตอบ! :) ดีใจที่คุณพบว่ามีประโยชน์
Kirk Woll

5
ถ้าฉันทำได้ฉันจะ +10 คุณสำหรับคำตอบที่ละเอียดและถูกต้อง
Mark van Straten

2
ฉันต้องการเพิ่มการปรับเปลี่ยนของฉันที่ด้านบนของการแก้ไขอื่น ๆ ที่นี่ ฉันใช้ ... \ สัญกรณ์เพื่อสร้างไฟล์ xml ในโฟลเดอร์ root project App_Data \ documentation จากนั้นฉันใช้วิธีการ @ s of ในการดึงไฟล์ xml ทั้งหมดจากไดเร็กทอรีนั้น มันใช้งานได้อย่างสวยงามและน่าประหลาดใจที่นี่ไม่ใช่แค่การทำงานนอกกรอบเท่านั้น ขอบคุณมาก.
Darroll

32

ฉันเจอสิ่งนี้เช่นกัน แต่ฉันไม่ต้องการแก้ไขหรือทำซ้ำรหัสที่สร้างขึ้นเพื่อหลีกเลี่ยงปัญหาในภายหลัง

จากคำตอบอื่น ๆ นี่คือผู้ให้บริการเอกสารในตัวสำหรับแหล่ง 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")));

นี่เป็นทางออกที่ยอดเยี่ยม ฉันชอบมันมากกว่าโซลูชันที่ต้องการการปรับเปลี่ยนคลาส HelpPage เริ่มต้นเนื่องจากจะถูกเขียนทับในการอัปเดต
AronVanAmmers

3
มันใช้งานได้ดีขอบคุณสำหรับการโพสต์ เพื่อช่วยทุกคนที่ใช้เวลาเล็กน้อยคุณยังต้องทำสองขั้นตอนแรกของคำตอบที่ได้รับการยอมรับของเคิร์กข้างต้นนั่นคือ 1) เปิดใช้งานเอกสาร XML สำหรับโครงการย่อยของคุณและ 2) แก้ไขเหตุการณ์หลังการสร้างโครงการ Web API ของคุณเพื่อคัดลอกไฟล์ XML นี้ไปยัง โฟลเดอร์ App_Data ของคุณ
tomRedox

1
จากนั้นบรรทัดนี้จะกลายเป็น: config.SetDocumentationProvider (MultiXmlDocumentationProvider ใหม่ (HttpContext.Current.Server.MapPath ("~ / App_Data / [ชื่อไฟล์ xml ของโปรเจ็กต์เว็บ api ดั้งเดิมค่าเริ่มต้นคือ XmlDocument] .xml"), HttpContext.Current.Server.MapPath ("~ / App_Data / [สิ่งที่คุณเรียกว่าชื่อไฟล์ SubProject xml ของคุณ] .xml")));
tomRedox

ทำตามขั้นตอน แต่ไม่ได้ผล :( ไม่มีข้อผิดพลาดดังนั้นไม่แน่ใจว่าเกิดอะไรขึ้น แต่ยังคงแสดงเฉพาะเอกสาร api แต่ไม่ใช่เอกสารโครงการเพิ่มเติมฉันลองทำตามขั้นตอนในคำตอบที่ยอมรับแล้วและมันก็เหมือนเดิม มีอะไรเป็นพิเศษที่ฉันควรตรวจสอบ?
stt106

ด้วยเหตุผลบางประการฉันยังคงเห็น GET api / me เริ่มต้นที่มาพร้อมกับเทมเพลตโครงการเริ่มต้นใน VS
John Zabroski


0

ที่นี่ฉันให้ลิงค์คำตอบซึ่งสามารถช่วยคุณได้ คุณสามารถใช้ไฟล์ XML หลายไฟล์สำหรับเอกสารประกอบได้อย่างง่ายดาย

ความคิดเห็น XML ของหน้าวิธีใช้ Web Api จากไฟล์มากกว่า 1 ไฟล์


0

วิธีที่ง่ายที่สุดในการแก้ไขปัญหานี้คือการสร้างโฟลเดอร์ App_Code บนเซิร์ฟเวอร์ที่คุณปรับใช้ จากนั้นคัดลอก XmlDocument.xml ที่คุณมีในโฟลเดอร์ bin ของคุณลงในโฟลเดอร์ App_Code


ขอบคุณสำหรับคำแนะนำ !! ไม่มี -1 อีกต่อไปสำหรับคำตอบที่เป็นประโยชน์เช่นนี้ ใช่ถ้าคุณปรับใช้กับ Azure Cloud App Service ปัญหามากมายจะเกิดขึ้นกับการปรับใช้ * .xml หลายรายการดังนั้นการทำให้พร้อมใช้งานสำหรับการวางท่าอาจเป็นเรื่องยุ่งยากมาก แต่ฉันอยากจะเลือกโฟลเดอร์ฝั่งเซิร์ฟเวอร์ ASP.Net มาตรฐานอื่นคือ App_GlobalResources เนื่องจากไฟล์ xmldoc ค่อนข้างคล้ายกับทรัพยากร มันเป็นเรื่องจริงโดยเฉพาะอย่างยิ่งเพราะฉันยังไม่มีโฟลเดอร์ App_Code ในโครงการของฉันและมันไม่สำคัญว่าจะสร้างโฟลเดอร์มาตรฐานใด
moudrick

โฟลเดอร์มาตรฐานต่อไปนี้ใช้งานได้สำหรับฉัน: App_Code - ไม่สามารถมองเห็นได้จากไคลเอนต์ในการตั้งค่าเริ่มต้น App_GlobalResources - ไม่สามารถมองเห็นได้จากไคลเอนต์ในการตั้งค่าเริ่มต้น App_LocalResources - ไม่สามารถมองเห็นได้จากไคลเอนต์ในการตั้งค่าเริ่มต้น
moudrick

ให้ฉันแสดงรายการปัญหาเกี่ยวกับโฟลเดอร์มาตรฐานแต่ละโฟลเดอร์ที่ไม่ได้ผลสำหรับฉัน bin - เฉพาะ * .xml สำหรับแอสเซมบลีหลักจะถูกคัดลอกไปยัง App_Data - การตั้งค่าที่ใช้งานได้จริงที่สุดคือการข้ามทุกอย่างในโฟลเดอร์นี้เพื่อปรับใช้กับระบบคลาวด์
moudrick

ใครที่สนใจสามารถแก้ไขคำตอบนี้เพื่อสะท้อนข้อควรพิจารณาทั้งหมดข้างต้นได้หรือไม่ซึ่งอาจเป็นการคาดเดาเพิ่มเติม
moudrick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.