zoukankan      html  css  js  c++  java
  • ASP.NET Web API RC版本新特性:Web API的帮助文档制作

    InfoQ上有一篇文章是 使用IAPIExplorer列举ASP.NET Web API,文章针对的版本是ASP.NET Web API Beta版本写,IAPIExplorer已经包含在RC版本里了,而且发现ASP.NET Web API的HttpConfiguration 的RC版本比Beta版本多了一个属性:

    public DefaultServices Services { get; internal set; }

    Debug进去可以看到默认有18个服务,IAPIExplorer 就是其中之一:

    image

    使用该API可以完成的工作有:

    • 产生文档
    • 创建机器可读的元数据
    • 创建一个测试客户端

    微软员工Yao发表了两篇文章(ASP.NET Web API: Introducing IApiExplorer/ApiExplorerASP.NET Web API: Generating a Web API help page using ApiExplorer)分别用于展示如何使用API打印Web API列表以及如何创建帮助文档。

    所以我们创建帮助文档主要就是参照这篇文章就可以了ASP.NET Web API: Generating a Web API help page using ApiExplorer;作者在文章里面已经实现了一个IDocumentationProvider,它是通过代码的注释XML文档去生成,这是一个非常好的实现了:

    public class XmlCommentDocumentationProvider : IDocumentationProvider 
        {
            XPathNavigator _documentNavigator;
            private const string _methodExpression = "/doc/members/member[@name='M:{0}']";
            private static Regex nullableTypeNameRegex = new Regex(@"(.*\.Nullable)" + Regex.Escape("`1[[") + "([^,]*),.*");
            public XmlCommentDocumentationProvider(string documentPath)
            {
                XPathDocument xpath = new XPathDocument(documentPath);
                _documentNavigator = xpath.CreateNavigator();
            } 
            public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor) 
        {
            ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
                if (reflectedParameterDescriptor != null)
                { 
                    XPathNavigator memberNode = GetMemberNode(reflectedParameterDescriptor.ActionDescriptor);
                    if (memberNode != null)
                    { 
                        string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
                        XPathNavigator parameterNode = memberNode.SelectSingleNode(string.Format("param[@name='{0}']", parameterName));
                        if (parameterNode != null)
                        { 
                            return parameterNode.Value.Trim();
                        } 
                    } 
                }
                return "No Documentation Found.";
            } 
            public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
            { 
                XPathNavigator memberNode = GetMemberNode(actionDescriptor);
                if (memberNode != null)
                { 
                    XPathNavigator summaryNode = memberNode.SelectSingleNode("summary");
                    if (summaryNode != null)
                    { 
                        return summaryNode.Value.Trim();
                    } 
                } 
                return "No Documentation Found.";
            } 
            private XPathNavigator GetMemberNode(HttpActionDescriptor actionDescriptor)
            {
                ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
                if (reflectedActionDescriptor != null)
                { 
                    string selectExpression = string.Format(_methodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
                    XPathNavigator node = _documentNavigator.SelectSingleNode(selectExpression);
                    if (node != null)
                    {
                        return node;
                    } 
                } 
                return null;
            } 
            private static string GetMemberName(MethodInfo method)
            {
                string name = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name); 
                var parameters = method.GetParameters();
                if (parameters.Length != 0) 
                { 
                    string[] parameterTypeNames = parameters.Select(param => ProcessTypeName(param.ParameterType.FullName)).ToArray();
                    name += string.Format("({0})", string.Join(",", parameterTypeNames));
                }
                return name;
            } 
            private static string ProcessTypeName(string typeName) 
            {
                //handle nullable
                var result = nullableTypeNameRegex.Match(typeName);
                if (result.Success)
                {
                    return string.Format("{0}{{{1}}}", result.Groups[1].Value, result.Groups[2].Value);
                } 
                return typeName;
            } 
        }

    把XML 文档的位置在Application_Start 中将IDocumentationProvider服务替换为我们的自定义服务。

    var config = GlobalConfiguration.Configuration;
    config.Services.Replace(typeof(IDocumentationProvider), new XmlCommentDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/MvcApplication2.XML")));

    有个ApiExplorerSettingsAttribute 可以控制API是否在帮助页面上出现:

    /// <summary>
    /// DELETE api/values/5
    /// </summary>
    /// <param name="id"></param> 
    [ApiExplorerSettings(IgnoreApi = true)]
    public void Delete(int id)
    {
    }

    还可以控制整个ApiController 的文档是否发布出来,只需要通过在类级别应用ApiExplorerSettingsAttribute

     [ApiExplorerSettings(IgnoreApi = true)]
     public class MySpecialController : ApiController

    通过IAPIExplorer 这个API我们可以为我们的Web API 做出很棒的文档了,而且这个接口的设计也是可扩展的。可以制作Web页面也可以制作一个HelpController来做,推荐封装成一个HelpController,这样就可以适应WebAPi的Web Host或者是Self Host了。 

    Part 1: Basic Help Page customizations

    Changing the help page URI

    Providing API documentations

    Customizing the view

    Part 2: Providing custom samples on the Help Page

    Setting custom sample objects

    Setting the samples when the action returns an HttpResponseMessage

    Part 3: Advanced Help Page customizations

    Adding additional information to the HelpPageApiModel

    Creating new sample display templates

    Making ASP.NET Web API Help Page work on self-hosted services

    Extending Web API Help Page with information from attributes

    Using curl to POST request into ASP.NET Web Api service

    欢迎大家扫描下面二维码成为我的客户,为你服务和上云

  • 相关阅读:
    E
    牛客比赛—身体训练
    前缀和例题
    欧拉函数模板
    3.30训练题
    poj1321棋盘问题
    记set学习
    B. K-th Beautiful String
    codeforces1293C
    LightOJ 1370 Bi-shoe and Phi-shoe
  • 原文地址:https://www.cnblogs.com/shanyou/p/2532370.html
Copyright © 2011-2022 走看看