1.新建ASP.NET 项目,模板选择如图

2.选择Web API,并选择不进行身份验证方式

成功后我们看到这个结果。

至于其它三种身份验证方式,不太适合我的使用。而且这种方式也可以在代码里去实现身份验证,比较符合已有数据库的情况,这里不写。

3.给项目进行配置修改

3.1 修改对应项目生成路径。

这是单项目结构的,如果有多个项目并且有引用,把其它项目生成XML的地址改为接口项目的地址,当然也可以生成后再拷贝过去。

3.2修改WebAPITest\Areas\HelpPage\App_Start\HelpPageConfig.cs里面的代码。

反注释

 config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));

  里面的文档改成我们上面生成的文档名称,打开help接口就能看到注释了。

如果是引用了多个项目,就麻烦点。

先把刚刚这句改一下

 config.SetDocumentationProvider(new XmlDocumentationProvider(
HttpContext.Current.Server.MapPath("~/App_Data")));

  看见XmlDocumentationProvider这个类没有?转到定义过去看看,下面是原来的代码,不用看了。

 /// <summary>
/// A custom <see cref="IDocumentationProvider"/> that reads the API documentation from an XML documentation file.
/// </summary>
public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
private XPathNavigator _documentNavigator;
private const string TypeExpression = "/doc/members/member[@name='T:{0}']";
private const string MethodExpression = "/doc/members/member[@name='M:{0}']";
private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
private const string FieldExpression = "/doc/members/member[@name='F:{0}']";
private const string ParameterExpression = "param[@name='{0}']"; /// <summary>
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
/// </summary>
/// <param name="documentPath">The physical path to XML document.</param>
public XmlDocumentationProvider(string documentPath)
{
if (documentPath == null)
{
throw new ArgumentNullException("documentPath");
}
XPathDocument xpath = new XPathDocument(documentPath);
_documentNavigator = xpath.CreateNavigator();
} public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
{
XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);
return GetTagValue(typeNode, "summary");
} public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "summary");
} public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
if (methodNode != null)
{
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
if (parameterNode != null)
{
return parameterNode.Value.Trim();
}
}
} return null;
} public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "returns");
} public string GetDocumentation(MemberInfo member)
{
string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);
string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;
string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);
XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression);
return GetTagValue(propertyNode, "summary");
} public string GetDocumentation(Type type)
{
XPathNavigator typeNode = GetTypeNode(type);
return GetTagValue(typeNode, "summary");
} private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
return _documentNavigator.SelectSingleNode(selectExpression);
} return null;
} private static string GetMemberName(MethodInfo method)
{
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != )
{
string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();
name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));
} return name;
} private static string GetTagValue(XPathNavigator parentNode, string tagName)
{
if (parentNode != null)
{
XPathNavigator node = parentNode.SelectSingleNode(tagName);
if (node != null)
{
return node.Value.Trim();
}
} return null;
} private XPathNavigator GetTypeNode(Type type)
{
string controllerTypeName = GetTypeName(type);
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);
return _documentNavigator.SelectSingleNode(selectExpression);
} private static string GetTypeName(Type type)
{
string name = type.FullName;
if (type.IsGenericType)
{
// Format the generic type name to something like: Generic{System.Int32,System.String}
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.FullName; // Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));
}
if (type.IsNested)
{
// Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.
name = name.Replace("+", ".");
} return name;
}
}

  我们把它改下,整个类替换掉,没引用的自己右键引用。

 public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
// private XPathNavigator _documentNavigator;
private List<XPathNavigator> _documentNavigators = new List<XPathNavigator>();
private const string TypeExpression = "/doc/members/member[@name='T:{0}']";
private const string MethodExpression = "/doc/members/member[@name='M:{0}']";
private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
private const string FieldExpression = "/doc/members/member[@name='F:{0}']";
private const string ParameterExpression = "param[@name='{0}']"; /// <summary>
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
/// </summary>
/// <param name="documentPath">The physical path to XML document.</param>
//public XmlDocumentationProvider(string documentPath)
//{
// if (documentPath == null)
// {
// throw new ArgumentNullException("documentPath");
// }
// XPathDocument xpath = new XPathDocument(documentPath);
// _documentNavigator = xpath.CreateNavigator();
//}
/// <summary>
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
/// </summary>
/// <param name="appDataPath">The physical path to XML document.</param>
public XmlDocumentationProvider(string appDataPath)
{
if (appDataPath == null)
{
throw new ArgumentNullException("appDataPath");
} var files = new[] { "AuthSystem.xml", "AuthSystem.SQL.xml", "AuthSystem.Common.XML" };//这里是你其它dll的说明路径,自己可以改写。例如 var files = Directory.GetFiles(appDataPath, "TLSC.*.xml");//获取所有类似的xml
foreach (var file in files)
{
XPathDocument xpath = new XPathDocument(Path.Combine(appDataPath, file));
_documentNavigators.Add(xpath.CreateNavigator());
}
} private XPathNavigator SelectSingleNode(string selectExpression)
{
foreach (var navigator in _documentNavigators)
{
var propertyNode = navigator.SelectSingleNode(selectExpression);
if (propertyNode != null)
return propertyNode;
}
return null;
}
public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
{
XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);
return GetTagValue(typeNode, "summary");
} public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "summary");
} public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
if (methodNode != null)
{
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
if (parameterNode != null)
{
return parameterNode.Value.Trim();
}
}
} return null;
} public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "returns");
} public string GetDocumentation(MemberInfo member)
{
string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);
string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;
string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);
XPathNavigator propertyNode = SelectSingleNode(selectExpression);
return GetTagValue(propertyNode, "summary");
} public string GetDocumentation(Type type)
{
XPathNavigator typeNode = GetTypeNode(type);
return GetTagValue(typeNode, "summary");
} private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
return SelectSingleNode(selectExpression);
} return null;
} private static string GetMemberName(MethodInfo method)
{
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != )
{
string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();
name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));
} return name;
} private static string GetTagValue(XPathNavigator parentNode, string tagName)
{
if (parentNode != null)
{
XPathNavigator node = parentNode.SelectSingleNode(tagName);
if (node != null)
{
return node.Value.Trim();
}
} return null;
} private XPathNavigator GetTypeNode(Type type)
{
string controllerTypeName = GetTypeName(type);
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);
return SelectSingleNode(selectExpression);
} private static string GetTypeName(Type type)
{
string name = type.FullName;
if (type.IsGenericType)
{
// Format the generic type name to something like: Generic{System.Int32,System.String}
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.FullName; // Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));
}
if (type.IsNested)
{
// Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.
name = name.Replace("+", ".");
} return name;
}
}

原理就是从只读一个文档改成读取多个文档。这样就能在help中看到我们写的注释(summary)了。

效果图就不贴了,免得浪费大家流量哈哈。

1.0 添加WEB API项目并按注释生成文档(多项目结构)的更多相关文章

  1. newlisp 注释生成文档

    最近写了一个newlisp_armory库,用来实现一些newlisp自身不支持的操作.比如跨windows和ubuntu的目录拷贝功能等. 自己用的时候,发现没有API reference文档参考, ...

  2. 使用swagger在netcorewebapi项目中自动生成文档

    一.背景 随着前后端分离模式大行其道,我们需要将后端接口撰写成文档提供给前端,前端可以查看我们的接口,并测试,提高我们的开发效率,减少无效的沟通.在此情况下,通过代码自动生成文档,这种需求应运而生,s ...

  3. Sphinx将python代码注释生成文档

    安装 使用pip进行安装: pip install sphinx 初始化 进入你代码所在的目录,输入: sphinx-quickstart 下图:PRD是代码所在目录,生成的文档保存目录设成doc  ...

  4. eoLinker 新功能发布,增加了识别代码注释自动生成文档功能

    产品地址:https://www.eolinker.com开源代码:https://www.eolinker.com/#/os/download在线生成代码注释工具:http://tool.eolin ...

  5. List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac

    List多个字段标识过滤 class Program{  public static void Main(string[] args) { List<T> list = new List& ...

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

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

  7. MVC WEB api 自动生成文档

    最近在一直在用webapi做接口给移动端用.但是让我纠结的时候每次新加接口或者改动接口的时候,就需要重新修改文档这让我很是苦恼.无意中发现.webapi居然有自动生成文档的功能....真是看见了救星啊 ...

  8. xcode 自动添加注释,生成文档

    一.自动生成注释代码        添加一个快捷键,生成 注释代码        ThisService 下载连接:http://wafflesoftware.net/thisservice/     ...

  9. ASP.NET Core 1.0 中使用 Swagger 生成文档

    github:https://github.com/domaindrivendev/Ahoy 之前文章有介绍在ASP.NET WebAPI 中使用Swagger生成文档,ASP.NET Core 1. ...

随机推荐

  1. Java面试宝典-2017

    Java面试宝典2017版 一. Java基础部分........................................................................... ...

  2. 笔记:I/O流-ZIP文档

    ZIP文档以压缩格式存储了一个或多个文件,每个ZIP文档都有一个头,包含诸如每个文件名字和所使用的压缩方法等信息,在 Java 中可以使用 ZipInputStream 来读入ZIP 文档,getNe ...

  3. 源码实现 --> strdel

    删除字符串中某个字符strdel 函数 char *strDel(char* str,const char chToDel) 不是库里面的函数,自己实现的原型,删除str中所有的chToDel字符. ...

  4. Python 自学 之 String 常见操作

    这是在Python 3.5.3版本下测试的.# Author Taylor_Manitoname ="my name is alex"#capitalized 大写的print(& ...

  5. 2018.3.29 div格式设置

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  6. 20162320刘先润第三周Bag类测试

    前言 以下内容是本周Bag代码的课后作业,要求是完成伪代码.产品代码和测试代码,为了书写方便我将伪代码以注释的形式写在了产品代码的后面 测试步骤 1.首先对Bag类引用BagInterface的代码进 ...

  7. alpha-咸鱼冲刺day3-紫仪

    总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 今天把数据库的表给建好了,学长那边把登陆跟注册页面也做好了(纯页面,html5+css的那种) 四,问题困难   日常 ...

  8. Java作业-网络编程

    Java网络编程 关于结合以前的大作业(即我的图书馆管理系统) 我感觉,图书馆管理系统更像是一个偏向于B/S模式的体系,如果想让他可用性变得更好,可以优化的地方只有使用数据库来代替文件,我个人是没有想 ...

  9. Bate版敏捷冲刺每日报告--day1

    1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285)  Git链接:https://github.com/WHUSE2017/C-team 2 ...

  10. OptaPlanner - 把example运行起来(运行并浅析Cloud balancing)

    经过上面篇长篇大论的理论之后,在开始讲解Optaplanner相关基本概念及用法之前,我们先把他们提供的示例运行起来,好先让大家看看它是如何工作的.OptaPlanner的优点不仅仅是提供详细丰富的文 ...