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 就是其中之一:
使用該API可以完成的工作有:
- 產生文檔
- 創建機器可讀的元數據
- 創建一個測試客戶端
微軟員工Yao發表了兩篇文章(ASP.NET Web API: Introducing IApiExplorer/ApiExplorer和ASP.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