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

我们大家都知道,自己写的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 != )
{
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[].Value, result.Groups[].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>@ViewBag.Domain@api.RelativePath</b></p>
<blockquote>
<b>Description:</b>@api.Documentation<br />
@if (api.ParameterDescriptions.Count > )
{
<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设计和实现了,无需要手工更改说明文档。

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

  1. asp.net core web api 生成 swagger 文档

    asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果 ...

  2. 关于ASP.NET Web Api的HelpPage文档注释问题

    关于ASP.NET Web Api的HelpPage文档注释问题 以前我用微软的HelpPage来自动生成的webAPI帮助文档.在使用了一段时间后发现只能显示Controller上面写的注释文档内容 ...

  3. ASP.NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档

    原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...

  4. Swagger 生成 ASP.NET Web API

    使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档 原文:ASP.NET Web API Help Pages using Swagger作者:Shayne Boyer翻译: ...

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

    本文介绍“ 为ASP.NET Web API生成TypeScript客户端API ”,重点介绍Angular 2+代码示例和各自的SDLC.如果您正在开发.NET Core Web API后端,则可能 ...

  6. 第二十节:Asp.Net Core WebApi生成在线文档

    一. 基本概念 1.背景 使用 Web API 时,了解其各种方法对开发人员来说可能是一项挑战. Swagger 也称为OpenAPI,解决了为 Web API 生成有用文档和帮助页的问题. 它具有诸 ...

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

    对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...

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

    默认情况下,ASP.NET Web API不从Controller的注释中生成帮助文档.如果要将注释作为Web API帮助文档的一部分,比如在帮助文档的Description栏目中显示方法注释中的su ...

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

    使用Visual Studio新建一个ASP.NET Web API项目,直接运行,查看Help文档可以看到如下的API帮助说明 如何在Description中显示描述. 1. 打开Controlle ...

随机推荐

  1. canvas知识01

    本文转自:http://www.cnblogs.com/jsdarkhorse/archive/2012/06/29/2568451.html 更多参考:http://www.cnblogs.com/ ...

  2. BZOJ 4823: [Cqoi2017]老C的方块

    分析: 我觉得我的网络流白学了...QAQ... 其实数据范围本是无法用网络流跑过去的,然而出题者想让他跑过去,也就跑过去了... 看到题目其实感觉很麻烦,不知道从哪里入手,那么仔细观察所给出的有用信 ...

  3. 【bzoj4310/hdu5030-跳蚤】后缀数组

    我真的是..调了一百年.. 傻逼的人生.. 而且这题好像可以用sam做哎!我Y出了一个奇怪的办法.. 好吧sam是不能做这题的.搞错了. 说说后缀数组好了.. 搞后缀数组 然后我们要二分一个子串,判断 ...

  4. [POJ2406&POJ1961]用KMP解决字符串的循环问题两例

    翻阅了一下网上资料,发现大部分都说这题是找规律...或是说YY出的一个算法..不会证明... 然后就脑补了一下证明 ~ 结论:对于一个字符串S[1..N],如果N mod (N-next[N])=0 ...

  5. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  6. js 触发LinkButton点击事件,执行后台方法

    页面 <asp:LinkButton ID="lbtButton" runat="server"  CssClass="lbtButton&qu ...

  7. Python与Mysql交互

    #转载请联系 在写内容之前,先放一张图,bling- 这张图算是比较详细的表达出了web开发都需要什么.用户访问网页,就是访问服务器的网页文件.这些网页文件由前端工程师编写的.服务器通常用nginx/ ...

  8. getResourceAsStream用法详解

    //使用绝对路径,否则无法读取config.properties //InputStream inStream=new FileInputStream("F:\\android\\test\ ...

  9. KVM(六)Nova 通过 libvirt 管理 QEMU/KVM 虚机

    1. Libvirt 在 OpenStack 架构中的位置 在 Nova Compute 节点上运行的 nova-compute 服务调用 Hypervisor API 去管理运行在该 Hypervi ...

  10. yii2中判断值是否存在二维数组中

    //在yii2中,在类里面的函数,可以不加action $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); / ...