為ASP.NET WEB API產生人性化說明文檔

來源:互聯網
上載者:User

標籤: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產生人性化說明文檔

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.