Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET Web Api文档-注释继承_Asp.net_Asp.net Mvc 4_Asp.net Web Api - Fatal编程技术网

ASP.NET Web Api文档-注释继承

ASP.NET Web Api文档-注释继承,asp.net,asp.net-mvc-4,asp.net-web-api,Asp.net,Asp.net Mvc 4,Asp.net Web Api,目前,我有一个ASP.NET Web Api与一个ASP.NET Web应用程序并行运行。使用姚黄在他的博客文章中概述的与HelpPage NuGet包相关的方法,特别是,我已经成功地记录了我的API-几乎 我遇到的问题是,特定的API方法调用继承(并可能重写)基类的行为,我们将其称为ApiBase。因此,这些方法没有自己的文档,因为它们是从基类继承方法的,通常不需要比ApiBase提供的更进一步的解释我试图做的(但没有如何做的方向)是,对于从基类继承实现的方法,找到一种方法来继承和显示与基类关

目前,我有一个ASP.NET Web Api与一个ASP.NET Web应用程序并行运行。使用姚黄在他的博客文章中概述的与HelpPage NuGet包相关的方法,特别是,我已经成功地记录了我的API-几乎

我遇到的问题是,特定的API方法调用继承(并可能重写)基类的行为,我们将其称为
ApiBase
。因此,这些方法没有自己的文档,因为它们是从基类继承方法的,通常不需要比
ApiBase
提供的更进一步的解释我试图做的(但没有如何做的方向)是,对于从基类继承实现的方法,找到一种方法来继承和显示与基类关联的XML注释,并在调用方法时显示它们。

为了澄清这一点,下面是来自
ApiBase
的一个示例方法:

public abstract class ApiBase
{
    /// <summary>
    /// Stub used as an example
    /// </summary>
    /// <param name="stub">Random boolean value</param>
    /// <returns>The boolean value</returns>
    public virtual bool returnBool(bool stub)
    {
        return stub;
    }

    /// <summary>
    /// Stub #2 used as an example
    /// </summary>
    /// <param name="stub">Random int value</param>
    /// <returns>A value less than the parameter</returns>
    public virtual int returnLess(int stub)
    {
        return (stub - 10);
    }
}
ApiChild
调用
returnBool
returnLess
时,我希望
XMLDocumentationProvider
从基类获取他们的注释。ApiExplorer已经成功地从基类中获取了其余的信息,例如返回类型、参数等,但是我不确定如何将此功能扩展到注释检索。我感谢你能提供的任何帮助。我自己的想法倾向于某种实现,这种实现在运行时使用反射来分析方法,以确定其属性,并在需要时适当地从其父级获取注释。非常感谢您的任何想法/指导

以下是
XMLDocumentationProvider
中使用的当前代码供参考:

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

namespace MyProject.Areas.HelpPage
{
    public interface IResponseDocumentationProvider
    {
            string GetResponseDocumentation(HttpActionDescriptor actionDescriptor);
    }

    /// <summary>
    /// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file.
    /// </summary>
    public class XmlDocumentationProvider : IDocumentationProvider, IResponseDocumentationProvider
    {
        private XPathNavigator _documentNavigator;
        private const string MethodExpression = "/doc/members/member[@name='M:{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 virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
        {
            XPathNavigator methodNode = GetMethodNode(actionDescriptor);
            if (methodNode != null)
            {
                XPathNavigator summaryNode = methodNode.SelectSingleNode("summary");
                if (summaryNode != null)
                {
                    return summaryNode.Value.Trim();
                }
            }

            return null;
        }

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

        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}", method.DeclaringType.FullName, 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 GetTypeName(Type type)
        {
            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 typeName = genericType.FullName;

                // Trim the generic parameter counts from the name
                typeName = typeName.Substring(0, typeName.IndexOf('`'));
                string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
                return String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", typeName, String.Join(",", argumentTypeNames));
            }

            return type.FullName;
        }

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

            return null;
        }
    }
}
使用系统;
利用制度全球化;
使用System.Linq;
运用系统反思;
使用System.Web.Http.Controller;
使用System.Web.Http.Description;
使用System.Xml.XPath;
名称空间MyProject.Areas.HelpPage
{
公共接口IResponseDocumentationProvider
{
字符串GetResponseDocumentation(HttpActionDescriptor actionDescriptor);
}
/// 
///从XML文档文件读取API文档的自定义。
/// 
公共类XmlDocumentationProvider:IDocumentationProvider,IResponseDocumentationProvider
{
私有XPathNavigator\u documentNavigator;
private const string MethodExpression=“/doc/members/member[@name='M:{0}']”;
private const string ParameterExpression=“param[@name='{0}']”;
/// 
///初始化类的新实例。
/// 
///XML文档的物理路径。
公共XmlDocumentationProvider(字符串documentPath)
{
if(documentPath==null)
{
抛出新的ArgumentNullException(“documentPath”);
}
XPathDocument xpath=新的XPathDocument(documentPath);
_documentNavigator=xpath.CreateNavigator();
}
公共虚拟字符串GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode=GetMethodNode(actionDescriptor);
if(methodNode!=null)
{
XPathNavigator summaryNode=methodNode.SelectSingleNode(“summary”);
if(summaryNode!=null)
{
返回summaryNode.Value.Trim();
}
}
返回null;
}
公共虚拟字符串GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor=作为ReflectedHttpParameterDescriptor的parameterDescriptor;
if(reflectedParameterDescriptor!=null)
{
XPathNavigator methodNode=GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
if(methodNode!=null)
{
字符串parameterName=reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode=methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture,ParameterExpression,parameterName));
if(parameterNode!=null)
{
返回parameterNode.Value.Trim();
}
}
}
返回null;
}
专用XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor=actionDescriptor作为ReflectedHttpActionDescriptor;
if(reflectedActionDescriptor!=null)
{
string selectExpression=string.Format(CultureInfo.InvariantCulture,MethodExpression,GetMemberName(reflectedActionDescriptor.MethodInfo));
return\u documentNavigator.SelectSingleNode(selectExpression);
}
返回null;
}
私有静态字符串GetMemberName(MethodInfo方法)
{
string name=string.Format(CultureInfo.InvariantCulture,“{0}.{1}”、method.DeclaringType.FullName、method.name);
ParameterInfo[]parameters=method.GetParameters();
如果(parameters.Length!=0)
{
string[]parameterTypeNames=参数。选择(param=>GetTypeName(param.ParameterType)).ToArray();
name+=String.Format(CultureInfo.InvariantCulture,({0})”,String.Join(“,”,parameterTypeNames));
}
返回名称;
}
私有静态字符串GetTypeName(类型)
{
if(type.IsGenericType)
{
//将泛型类型名称的格式设置为:泛型{System.Int32,System.String}
类型genericType=Type.GetGenericTypeDefinition();
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using System.Xml.XPath;

namespace MyProject.Areas.HelpPage
{
    public interface IResponseDocumentationProvider
    {
            string GetResponseDocumentation(HttpActionDescriptor actionDescriptor);
    }

    /// <summary>
    /// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file.
    /// </summary>
    public class XmlDocumentationProvider : IDocumentationProvider, IResponseDocumentationProvider
    {
        private XPathNavigator _documentNavigator;
        private const string MethodExpression = "/doc/members/member[@name='M:{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 virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
        {
            XPathNavigator methodNode = GetMethodNode(actionDescriptor);
            if (methodNode != null)
            {
                XPathNavigator summaryNode = methodNode.SelectSingleNode("summary");
                if (summaryNode != null)
                {
                    return summaryNode.Value.Trim();
                }
            }

            return null;
        }

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

        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}", method.DeclaringType.FullName, 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 GetTypeName(Type type)
        {
            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 typeName = genericType.FullName;

                // Trim the generic parameter counts from the name
                typeName = typeName.Substring(0, typeName.IndexOf('`'));
                string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
                return String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", typeName, String.Join(",", argumentTypeNames));
            }

            return type.FullName;
        }

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

            return null;
        }
    }
}