ASP Web API Help pages - Link to class from XML tag

前端 未结 2 1788
孤独总比滥情好
孤独总比滥情好 2020-12-21 18:36

I\'m working on Developing a Web-API project, and i\'m very impressed with the auto generated documentation by Microsoft\'s HelpPages.

i enabled custom documentation

2条回答
  •  佛祖请我去吃肉
    2020-12-21 19:18

    my solution is the following:

    1. you've got your custom documentation (from the generated xml file) working
    2. enable HTML and XML tags within the documentation, they normally get filtered out, thanks this Post you can preserve them.
      simply go to: ProjectName > Areas > HelpPage > XmlDocumentationProvider.cs
      on line 123 in method: GetTagValue(XPathNavigator parentNode, string tagName)
      change the code return node.Value.Trim(); to return node.InnerXml;
    3. create the following partial view:
      ProjectName\Areas\HelpPage\Views\Help**_XML_SeeTagsRenderer.cshtml**
      this is my code:
    @using System.Web.Http;
    @using MyProject.Areas.HelpPage.Controllers;
    @using MyProject.Areas.HelpPage;
    @using MyProject.Areas.HelpPage.ModelDescriptions
    @using System.Text.RegularExpressions
    @model string
    
    @{
        int @index = 0;
        string @xml = Model;
        if (@xml == null)
            @xml = "";
        Regex @seeRegex = new Regex("<( *)see( +)cref=\"([^\"]):([^\"]+)\"( *)/>");//Regex("");
        Match @xmlSee = @seeRegex.Match(@xml);
        string @typeAsText = "";
        Type @tp;
    
        ModelDescriptionGenerator modelDescriptionGenerator = (new HelpController()).Configuration.GetModelDescriptionGenerator();
    
    }
    
    @if (xml !="" && xmlSee != null && xmlSee.Length > 0)
    {
    
        while (xmlSee != null && xmlSee.Length > 0)
        {
    
                @MvcHtmlString.Create(@xml.Substring(@index, @xmlSee.Index - @index))
    
            int startingIndex = xmlSee.Value.IndexOf(':')+1;
            int endIndex = xmlSee.Value.IndexOf('"', startingIndex);
            typeAsText = xmlSee.Value.Substring(startingIndex, endIndex - startingIndex);  //.Replace("", "");
            System.Reflection.Assembly ThisAssembly = typeof(ThisProject.Controllers.HomeController).Assembly;
            tp = ThisAssembly.GetType(@typeAsText);
    
            if (tp == null)//try another referenced project
            {
                System.Reflection.Assembly externalAssembly = typeof(MyExternalReferncedProject.AnyClassInIt).Assembly;
                tp = externalAssembly.GetType(@typeAsText);
            }  
    
            if (tp == null)//also another referenced project- as needed
            {
                System.Reflection.Assembly anotherExtAssembly = typeof(MyExternalReferncedProject2.AnyClassInIt).Assembly;
                tp = anotherExtAssembly .GetType(@typeAsText);
            }
    
    
            if(tp == null)//case of nested class
            {
                System.Reflection.Assembly thisAssembly = typeof(ThisProject.Controllers.HomeController).Assembly;
                //the below code is done to support detecting nested classes.
                var processedTypeString = typeAsText;
                var lastIndexofPoint = typeAsText.LastIndexOf('.');
                while (lastIndexofPoint > 0 && tp == null)
                {
                    processedTypeString = processedTypeString.Insert(lastIndexofPoint, "+").Remove(lastIndexofPoint + 1, 1);
                    tp = SPLocatorBLLAssembly.GetType(processedTypeString);//nested class are recognized as: namespace.outerClass+nestedClass
                    lastIndexofPoint = processedTypeString.LastIndexOf('.');
                }
            }
    
            if (@tp != null)
            {
                ModelDescription md = modelDescriptionGenerator.GetOrCreateModelDescription(tp);
                    @Html.DisplayFor(m => md.ModelType, "ModelDescriptionLink", new { modelDescription = md })            
            }
            else
            {            
                    @MvcHtmlString.Create(@typeAsText)            
            }
            index = xmlSee.Index + xmlSee.Length;
            xmlSee = xmlSee.NextMatch();
        }    
                @MvcHtmlString.Create(@xml.Substring(@index, @xml.Length - @index))    
    }
    else
    {    
            @MvcHtmlString.Create(@xml);    
    }
    
    1. Finally Go to: ProjectName\Areas\HelpPage\Views\Help\DisplayTemplates**Parameters.cshtml**
      at line '20' we have the code corresponding to the Description in the documentation.
      REPLACE this:

                  
                      

      @parameter.Documentation

    With THIS:

                    
                        

    @Html.Partial("_XML_SeeTagsRenderer", (@parameter.Documentation == null? "" : @parameter.Documentation.ToString()))

    & Voila you must have it working now.
    Notes:

    • i tried putting HTML list inside the docs and it rendered it fine
    • i tried multiple class references (multiple and i worked fine
    • you can't refer to a class that is declared within a class
    • when you refer to a class that is outside the current project please add the assembly .getType of a class within that project (check my code above)
    • any un-found class found inside a will have it's full name printed in the description (for example if you reference a property or namespace, the code won't identify it as a type/class but it will be printed)

提交回复
热议问题