標籤:des style blog http color 使用 os io strong
一、為什麼要產生說明文檔
我們大家都知道,自己寫的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; } }}
View Code
這個代碼是通用的,直接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設計和實現了,無需要手工更改說明文檔。
為ASP.NET WEB API產生人性化說明文檔