为ASP.NET WEB API生成人性化说明文档

一、为什么要生成说明文档

我们大家都知道,自己写的API要供他人调用,就需要用文字的方式将调用方法和注意事项等写成一个文档以更好的展示我们设计时的想法和思路,便于调用者更加高效的使用我们的API。

当然,您可以不借助任何工具,自己手工写文档,然后做成chm或者html的形式交给客户,就是效率有点低,并且在API更改后有需要手工更改说明文档。

那有没有一种既方便,又能在API发生改变时,自动更新说明文档呢?答案是肯定的。

二、自动生成说明文档的具体实现

我们这里主要是将GlobalConfiguration.Configuration.Services的描述的实现换一种实现,具体是实现IDocumentationProvider这个接口,然后在调用Replace方法替换实现。

百度搜XmlCommentDocumentationProvider,有很多结果哦。这些都源于微软官方的大牛这篇文章:

http://blogs.msdn.com/b/yaohuang1/archive/2012/05/21/asp-net-web-api-generating-a-web-api-help-page-using-apiexplorer.aspx

下面是XmlCommentDocumentationProvider的实现:

using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using System.Web.Mvc;
using System.Xml.XPath;

namespace Deepleo.API
{
    /// <summary>
    /// XmlCommentDocumentationProvider
    /// </summary>
    public class XmlCommentDocumentationProvider : IDocumentationProvider
    {
        readonly XPathNavigator _documentNavigator;
        private const string _methodExpression = "/doc/members/member[@name=‘M:{0}‘]";
        private static readonly Regex _nullableTypeNameRegex = new Regex(@"(.*\.Nullable)" + Regex.Escape("`1[[") + "([^,]*),.*");

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="documentPath">document path</param>
        public XmlCommentDocumentationProvider(string documentPath)
        {
            XPathDocument xpath = new XPathDocument(documentPath);
            _documentNavigator = xpath.CreateNavigator();
        }

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

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

        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)
        {
            if (method.DeclaringType == null)
                return string.Empty;

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

这个代码是通用的,直接copy过去就ok了。

这篇博客园大牛张善友老师的博客有更详细的说明:http://www.cnblogs.com/shanyou/archive/2012/06/02/2532370.html

我主要说说后面的怎么实现:

第一步:需要在Project的Build里面打开生成xml注释文件选项,如下图所示:

第二步:改造HomeController.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Http.Description;
using System.Web.Http;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var config = GlobalConfiguration.Configuration;
            config.Services.Replace(typeof(IDocumentationProvider),
                                    new XmlCommentDocumentationProvider(HttpContext.Server.MapPath("~/bin/MvcApplication1.XML")));
            var apiExplorer = config.Services.GetApiExplorer();
            return View(apiExplorer);
        }
    }
}

代码的大意就是读取那个xml文件,然后替换掉以前的实现,换成我们的XmlCommentDocumentationProvider。

下面最后一步,修改View.

@model System.Web.Http.Description.IApiExplorer
@{
    ViewBag.Title = "API说明文档";
}
<div id="body">
    <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <h1>API说明文档</h1>
            </hgroup>
        </div>
    </section>
    <section class="content-wrapper main-content clear-fix">
        <ul>
        @foreach (var api in Model.ApiDescriptions)
        {
            <li>
                <p>@api.HttpMethod : <b>@[email protected]</b></p>
                <blockquote>
                    <b>Description:</b>@api.Documentation<br />
                    @if (api.ParameterDescriptions.Count > 0)
                    {
                        <b>Parameters</b>
                        <ul>
                            @foreach (var parameter in api.ParameterDescriptions)
                            {
                                <li>@parameter.Name: @parameter.Documentation {@parameter.Source}</li>
                            }
                        </ul>
                    }
                </blockquote>
            </li>
            <hr/>
        }
        <li>
          <small>来源:http://www.cnblogs.com/deepleo/p/XmlCommentDocumentationProvider.html</small>
        </li>
        </ul>
    </section>
</div>

大功告成,在线浏览效果:http://weishangapi.deepleo.com

演示代码下载:http://files.cnblogs.com/deepleo/WebApplication1.rar

可以看到,你在代码里面的注释,会自动显示到说明文档里面,这样你就可以专注于你的API设计和实现了,无需要手工更改说明文档。

时间: 2024-10-27 12:39:11

为ASP.NET WEB API生成人性化说明文档的相关文章

asp.net core web api 生成 swagger 文档

asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果接口多了就有点不适用了,没有接口文档会大大提高前后端的沟通成本.而 asp.net core 可以通过 Swashbuckle.AspNetCore 很方便的集成 swagger 文档,相比之前 nodejs(express) 和 swagger 集成就很麻烦了,大概这就是强类型语言的优势吧.C#

使用ASP.NET Web API和Web API Client Gen使Angular 2应用程序的开发更加高效

本文介绍“ 为ASP.NET Web API生成TypeScript客户端API ”,重点介绍Angular 2+代码示例和各自的SDLC.如果您正在开发.NET Core Web API后端,则可能需要阅读为ASP.NET Core Web API生成C#Client API. 背景 自WebApiClientGenAngular 2仍然在RC2时,自2016年6月v1.9.0-beta 以来,对Angular2的支持已经可用.并且在WebApiClientGenv2.0中提供了对Angula

ASP.NET Web API从注释生成帮助文档

ASP.NET Web API从注释生成帮助文档 默认情况下,ASP.NET Web API不从Controller的注释中生成帮助文档.如果要将注释作为Web API帮助文档的一部分,比如在帮助文档的Description栏目中显示方法注释中的summary,需要进行一些配置操作. 首先在Visual Studio中打开Web API项目的属性页,在Build设置页,选中XML document file,输入将要生成的XML文件放置的路径,比如:App_Data\OpenAPI.XML. 1

使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)

对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你创建良好的文档和帮助页面. Swashbuckle 可以通过修改 Startup.cs 作为一组 NuGet 包方便的加入项目.Swashbuckle 是一个开源项目,为使用 ASP.NET Core MVC 构建的 Web APIs 生成 Swagger 文档.Swagger 是一个机器可读的 R

ASP.NET Web API根据代码注释生成Help文档

使用Visual Studio新建一个ASP.NET Web API项目,直接运行,查看Help文档可以看到如下的API帮助说明 如何在Description中显示描述. 1. 打开Controllers=>ValuesController,为每个API增加注释(Summary) public class ValuesController : ApiController { /// <summary> /// GET api/values /// </summary> ///

asp.net web api帮助文档的说明

为asp.net的mvc web api填写自己的帮助文档 1. 加入Help的area(能够通过命令行或其它方式加入) 命令行:Install-Package Microsoft.AspNet.WebApi.HelpPage NuGet搜索:HelpPage,找到Microsoft asp.net web api help page 2. 为api等加入凝视 3. 生成凝视为xml文件 4. 将xml赋予Help的configuration 在help的config文件里 HelpPageCo

通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用

REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站,企业级Web应用对用户体验的要求要低一些.不过客户对“用户体验”的要求是“与日俱增”的,很多被“惯坏了”的用户已经不能忍受Postback带来的页面刷新,所以Ajax在企业级Web应用中得到了广泛的应用.企业级Web应用的一个特点是以“数据处理”为主,所以“面向绑定”的Knockout.js 是一

ASP.NET Web API中使用OData

在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(create, read, update, and delete)应用比传统WebAPI增加了很大的灵活性只要正确使用相关的协议,可以在同等情况下对一个CRUD应用可以节约很多开发时间,从而提高开发效率 二.怎么搭建 做一个简单的订单查询示例我们使用Code First模式创建两个实体对象Product(产品

Asp.Net Web API 2第八课——Web API 2中的属性路由

参考页面: http://www.yuanjiaocheng.net/webapi/web-api-gaisu.html http://www.yuanjiaocheng.net/webapi/create-web-api-proj.html http://www.yuanjiaocheng.net/webapi/test-webapi.html http://www.yuanjiaocheng.net/webapi/web-api-controller.html http://www.yuan