4

我發現姚明在微軟advanced help page customizations擴展的WebAPI 2.1的幫助頁面,包括額外的數據

一個漂亮的期票我試圖實施的步驟但是我不能讓我的自定義的註釋,以幫助中顯示文檔。

在我的

XmlDocumentationProvider.cs

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Linq; 
using System.Reflection; 
using System.Web.Http.Controllers; 
using System.Web.Http.Description; 
using System.Xml.XPath; 


namespace MyApp.Areas.HelpPage 
{ 
    /// <summary> 
    /// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file. 
    /// </summary> 
    public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider 
    { 
     private XPathNavigator _documentNavigator; 
     private const string TypeExpression = "/doc/members/member[@name='T:{0}']"; 
     private const string MethodExpression = "/doc/members/member[@name='M:{0}']"; 
     private const string PropertyExpression = "/doc/members/member[@name='P:{0}']"; 
     private const string FieldExpression = "/doc/members/member[@name='F:{0}']"; 
     private const string ParameterExpression = "param[@name='{0}']"; 

     /// <summary> 
     /// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class. 
     /// </summary> 
     /// <param name="documentPath">The physical path to XML document.</param> 
     public XmlDocumentationProvider(string documentPath) 
     { 
      if (documentPath == null) 
      { 
       throw new ArgumentNullException("documentPath"); 
      } 
      XPathDocument xpath = new XPathDocument(documentPath); 
      _documentNavigator = xpath.CreateNavigator(); 
     } 

     public string GetDocumentation(HttpControllerDescriptor controllerDescriptor) 
     { 
      XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType); 
      return GetTagValue(typeNode, "summary"); 
     } 

     public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor) 
     { 
      XPathNavigator methodNode = GetMethodNode(actionDescriptor); 
      return GetTagValue(methodNode, "summary"); 
     } 


     public virtual string GetActionTypes(HttpActionDescriptor actionDescriptor) 
     { 
      XPathNavigator methodNode = GetMethodNode(actionDescriptor); 
      return GetTagValue(methodNode, "action"); 
     } 


     public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor) 
     { 
      ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor; 
      if (reflectedParameterDescriptor != null) 
      { 
       XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor); 
       if (methodNode != null) 
       { 
        string parameterName = reflectedParameterDescriptor.ParameterInfo.Name; 
        XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName)); 
        if (parameterNode != null) 
        { 
         return parameterNode.Value.Trim(); 
        } 
       } 
      } 

      return null; 
     } 

     public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor) 
     { 
      XPathNavigator methodNode = GetMethodNode(actionDescriptor); 
      return GetTagValue(methodNode, "returns"); 
     } 



     public string GetDocumentation(MemberInfo member) 
     { 
      string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name); 
      string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression; 
      string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName); 
      XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression); 
      return GetTagValue(propertyNode, "summary"); 
     } 

     public string GetDocumentation(Type type) 
     { 
      XPathNavigator typeNode = GetTypeNode(type); 
      return GetTagValue(typeNode, "summary"); 
     } 

     private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor) 
     { 
      ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor; 
      if (reflectedActionDescriptor != null) 
      { 
       string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo)); 
       return _documentNavigator.SelectSingleNode(selectExpression); 
      } 

      return null; 
     } 

     private static string GetMemberName(MethodInfo method) 
     { 
      string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name); 
      ParameterInfo[] parameters = method.GetParameters(); 
      if (parameters.Length != 0) 
      { 
       string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray(); 
       name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames)); 
      } 

      return name; 
     } 

     private static string GetTagValue(XPathNavigator parentNode, string tagName) 
     { 
      if (parentNode != null) 
      { 
       XPathNavigator node = parentNode.SelectSingleNode(tagName); 
       if (node != null) 
       { 
        return node.Value.Trim(); 
       } 
      } 

      return null; 
     } 

     private XPathNavigator GetTypeNode(Type type) 
     { 
      string controllerTypeName = GetTypeName(type); 
      string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName); 
      return _documentNavigator.SelectSingleNode(selectExpression); 
     } 

     private static string GetTypeName(Type type) 
     { 
      string name = type.FullName; 
      if (type.IsGenericType) 
      { 
       // Format the generic type name to something like: Generic{System.Int32,System.String} 
       Type genericType = type.GetGenericTypeDefinition(); 
       Type[] genericArguments = type.GetGenericArguments(); 
       string genericTypeName = genericType.FullName; 

       // Trim the generic parameter counts from the name 
       genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); 
       string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray(); 
       name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames)); 
      } 
      if (type.IsNested) 
      { 
       // Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax. 
       name = name.Replace("+", "."); 
      } 

      return name; 
     } 

     public interface ICustomCommentProvider 
     { 
      string GetCustomComment(HttpActionDescriptor actionDescriptor); 
     } 

     public virtual string GetCustomComment(HttpActionDescriptor actionDescriptor) 
     { 
      XPathNavigator methodNode = GetMethodNode(actionDescriptor); 
      if (methodNode != null) 
      { 
       XPathNavigator returnsNode = methodNode.SelectSingleNode("customcomment"); 
       if (returnsNode != null) 
       { 
        return returnsNode.Value.Trim(); 
       } 
      } 

      return null; 
     } 
    } 
} 

我已經modifie

public interface ICustomCommentProvider 
    { 
     string GetCustomComment(HttpActionDescriptor actionDescriptor); 
    } 

    public virtual string GetCustomComment(HttpActionDescriptor actionDescriptor) 
    { 
     XPathNavigator methodNode = GetMethodNode(actionDescriptor); 
     if (methodNode != null) 
     { 
      XPathNavigator returnsNode = methodNode.SelectSingleNode("customcomment"); 
      if (returnsNode != null) 
      { 
       return returnsNode.Value.Trim(); 
      } 
     } 

     return null; 
    } 

我已經更新了

HelpPageModel.cs

包括

public string CustomMessage { get; set; } 

我已經更新了最後一件事是GenerateApiModel

private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config) 
    { 
     HelpPageApiModel apiModel = new HelpPageApiModel() 
     { 
      ApiDescription = apiDescription, 
     }; 



     var responseDocProvider = 
      config.Services.GetDocumentationProvider() as XmlDocumentationProvider.ICustomCommentProvider; 
     if (responseDocProvider != null) 
     { 
      apiModel.CustomMessage = responseDocProvider.GetCustomComment(apiDescription.ActionDescriptor); 
     } 

每次我運行該應用程序responseDocProvider爲空。有什麼突出的,看起來像我做錯了嗎?

幫助的問題將是非常讚賞

回答

2

您需要設置文件提供商。您可以取消以下部分代碼存在下Areas\HelpPage\App_Start\HelpPageConfig.cs

//// Uncomment the following to use the documentation from XML documentation file. 
//config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml"))); 

回答COMMENT(吉蘭Challa):

但不會和工作right..as你的類型不實現該接口你試圖投它...改變

XmlDocumentationProvider

來實現ICustomCommentProvider接口

,並做了

var responseDocProvider =config.Services.GetDocumentationProvider() as ICustomCommentProvider;

+0

嗨基蘭。我已經完成了該步驟,並顯示了所有其他默認屬性。其唯一的不會在GenerateApiModel內返回。我已經檢查過xml文檔,並且已經包含了自定義註釋。 –

+0

@DiverDan:我無法重現你的問題(我在5.0版本中試過)..你可以分享你的'XmlDocumentationProvider'類的實現......它是否也實現了'ICustomCommentProvider'接口? –

+0

我剛剛用XmlDocumentationProvider更新了我的帖子。我相信我正在執行我的GenerateApiModel方法中的接口var responseDocProvider = config.Services.GetDocumentationProvider()作爲XmlDocumentationProvider。ICustomCommentProvider; –