Skip to main content
 首页 » 编程设计

c#之ASP Web API 帮助页面之从 XML see> 标签链接到类

2024年05月22日46sharpest

我正在开发一个 Web-API 项目,Microsoft 的帮助页面自动生成的文档给我留下了深刻的印象。

我使用官方网站启用了自定义文档 creating Help Pages

文档已成功生成,但没有对 <See cref=""> 中的类的引用标签似乎被添加到描述中,HelpPages 只是忽略它们(这是有原因的)。

我真的很想在我的项目中使用这个功能,我搜索了很多(有时很接近)但没有一个给出令人信服的答案。

这就是为什么我决定将我的解决方案发布到此调整并希望对其他程序员有所帮助并节省他们一些时间和精力。 (我的答案在下面的回复中)

请您参考如下方法:

我的解决方案如下:

  1. 您的自定义文档(来自生成的 xml 文件)可以正常工作
  2. 在文档中启用 HTML 和 XML 标签,它们通常会被过滤掉,谢谢 Post你可以保存它们。
    只需转到:ProjectName > Areas > HelpPage > XmlDocumentationProvider.cs
    在第 123 行的方法中:GetTagValue(XPathNavigator parentNode, string tagName)
    更改代码 return node.Value.Trim();至 return node.InnerXml;
  3. 创建以下局部 View :
    ProjectName\Areas\HelpPage\Views\Help**_XML_SeeTagsRenderer.cshtml**
    这是我的代码:
@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("<see cref=\"T:([^\"]+)\" />"); 
    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("<see cref=\"T:", "").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. 最后转到:ProjectName\Areas\HelpPage\Views\Help\DisplayTemplates**Parameters.cshtml**
    在“20”行,我们有与文档中的描述相对应的代码。
    替换这个:

                <td class="parameter-documentation"> 
                    <p> 
                        @parameter.Documentation 
                    </p> 
                </td> 
    

有了这个:

                <td class="parameter-documentation"> 
                    <p> 
                        @Html.Partial("_XML_SeeTagsRenderer", (@parameter.Documentation == null? "" : @parameter.Documentation.ToString())) 
                    </p> 
                </td> 

& 瞧,你现在必须让它工作了。
备注:

  • 我尝试将 HTML 列表放入文档中,它呈现得很好
  • 我尝试了多个类引用(多个 <see cref="MyClass">,我工作得很好
  • 您不能引用在类中声明的类
  • 当您引用当前项目之外的类时,请在该项目中添加类的程序集 .getType(检查我上面的代码)
  • 在 <see cref> 中找到的任何未找到的类将在描述中打印它的全名(例如,如果您引用属性或命名空间,代码不会将其标识为类型/类,但会打印出来)