基于Oracle的EntityFramework的WEBAPI2的实现(四)——自动生成在线帮助文档
打开我们项目中的Area文件夹,正常情况下,我们会发现已经有了一个名字叫做【HelpPage】的区域(Area),这个区域是vs帮助我们自动建立的,它是一个mvc(不是webapi),它有普通的Conroller和Action,以及View,Model等。我们可以在调试的时候输入地址:http://localhost:8080/Help,就可以看见一个页面,有没有看见自己熟悉的TestController(名字中去掉了Controller,只剩下Test了)。如果没有,那么,一定是我们的配置有问题,那么我们下面的检查一下。
首先,要达到自动生成在线帮助的页面,我们必须提示说明信息。其实我们的说明信息就是我们对我们的Controller类的注释以及每一个方法的注释。当然不是//这样的注释,而是如下的注释:
///<summary>
///这才是真的注释
///</summary>
这个注释放在我们的类和我们的Controller以及Controller下的各种Action上,然后把文字写清楚了。右击我们的项目·属性,然后设置如下:

在【生成】标签页里面设置好【XML文档文件】,在里面写好地址,应该和我们的项目的dll在一个位置(通常是主项目下的bin目录),然后全部保存。
这个时候我们所有对类和成员的注释在生成的时候都会被写入进这个xml文件中,但是,我们的在线帮助页要如何取得这些数据呢,当然,这就需要我们告诉它我们的这个xml文件在什么位置。先来看一下目录图。

我们在App_Start文件夹里面找到【HelpPageConfig.cs】文件,这个文件是整个 HelpPage的配置所在。将此文件打开,找到如下的代码,解开注释,并修改为如下内容:
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/bin/WebApi.xml")));
此时,我们按照一开始时调试 一下,应该就可以看到在每个ApiController上的注释了。但是,我们发现,我们的Model类后面的注释都是空的,原因是我们的Model类是从数据库生成的,虽然数据库里面有注释,EF并没有帮我们把注释从数据库中取进来,有一些其它的第三方工具,可以实现此功能,但是事实上,数据库的注释是给我们看的,而我们的Model类的注释是给调用者看的,这是不一样的,比如我们的Model类型需要写明这个属性是否可以为空,而数据库中的注释有时候会泄露我们系统业务的内部秘密。所以,这个时候,我们打开我们的Model设计器(双击那个edmx文件)选择一个类的一个属性,右击,属性,就可以看见属性里面有一项叫文档,点开,在摘要里面写上我们的注释,即可。当然,详细内容也可以写(但是对HelpPage不做修改的情况下,是看不见详细内容的)。
这还不够,因为edmx只是生成映射文件,是数据库表与我们的类的映射,当然它还包含了一些我们自定义的信息(如刚刚的注释),但是,真正担任代码生成工作的是我们的.tt文件(T4代码模板?T4代码生成代码?随便你怎么叫)。我们点开edmx文件前面的三角号展开它,看见有一个与edmx文件同名但是扩展名为.tt的文件,双击打开它(等等,不要慌,这不是乱码,这是T4的代码,如果有高亮的话,你会觉得它和ASPX或者CSHTML一样让人喜爱,只是现在这个样子确实有点丑,丑得让人看不懂,不过没关系,大家通过无下划线的上下文搜索是可以搜索到相关位置的,然后加入有下划线的代码即可)。如下:
WriteHeader(codeStringGenerator, fileManager);
string summary=string.Empty;
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
if(entity.Documentation != null && entity.Documentation.Summary != null)
{
summary=entity.Documentation.Summary;
}else{
summary=entity.Name;
}
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
///<summary>
///<#=summary#>
///</summary>
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
if(edmProperty.Documentation !=null && edmProperty.Documentation.Summary != null)
{
summary=edmProperty.Documentation.Summary;
}else
{
summary="";
}
#>
///<summary>
///<#=summary#>
///</summary>
<#=codeStringGenerator.Property(edmProperty)#>
当我们部分注释是源于其它项目时,该怎么办,比如Model是单独的项目
那么问题来了,我们刚刚只讲到让HelpPage只取一个WebApi.xml,但是,如果我们的Model在WebApi.Model这个项目中怎么办。我可以告诉你,如果在WebApi.Model中,那么你写一万行的注释,HelpPage也不会让你看见的,因为你的WebApi.Model.Xml并没有给它,它取不到里面的信息。
那么我们右击WebApi.Model这个项目,点属性,然后在【生成】中将【XML文档生成】的位置设置到我们的WebApi项目的bin目录下,与WebApi.xml在 一起。
ok,还有下面一步,就是在HelpPageConfing.cs中,告诉系统我们xml的位置。这个时候,你会发现,【XmlDocumentationProvider】这个类很贱的没有两个参数的重载~~我操!!
那我们现在有两个xml文件,该怎么办?我们在上面的那个目录结构图中,发现,这个【XmlDocumentationProvider】类的源码就在那里,是不是很兴奋,有想改这个类的冲动?别吧,留着它,万一以后用得着呢?我们照着它新建一个继承IDocumentationProvider, IModelDocumentationProvider的类,名字叫【MultiXmlDocumentationProvider】(这个类是我很久之前从网上找的,不知道作者是谁了,在此表示深深的感谢),它的实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Description;
using WebApi.Areas.HelpPage.ModelDescriptions; namespace WebApi.Areas.HelpPage
{
/// <summary>A custom <see cref="IDocumentationProvider"/> that reads the API documentation from a collection of XML documentation files.</summary>
public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
/*********
** Properties
*********/
/// <summary>The internal documentation providers for specific files.</summary>
private readonly XmlDocumentationProvider[] Providers; /*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="paths">The physical paths to the XML documents.</param>
public MultiXmlDocumentationProvider(params string[] paths)
{
this.Providers = paths.Select(p => new XmlDocumentationProvider(p)).ToArray();
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(MemberInfo subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(Type subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpControllerDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpParameterDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetResponseDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
} /*********
** Private methods
*********/
/// <summary>Get the first valid result from the collection of XML documentation providers.</summary>
/// <param name="expr">The method to invoke.</param>
private string GetFirstMatch(Func<XmlDocumentationProvider, string> expr)
{
return this.Providers
.Select(expr)
.FirstOrDefault(p => !String.IsNullOrWhiteSpace(p));
}
}
}
这个时候,我们再回到HelpPageConfig.cs类中,找到刚刚那句:
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/bin/WebApi.xml")));
将它替换为:
config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/bin/WebApi.xml"), HttpContext.Current.Server.MapPath("~/bin/WebApi.Model.XML")));
这时候,我们再调试一下,倍儿爽!!~~~~
基于Oracle的EntityFramework的WEBAPI2的实现(四)——自动生成在线帮助文档的更多相关文章
- [转]基于Oracle的EntityFramework的WEBAPI2的实现(一)——准备工作
基于Oracle的EntityFramework的WEBAPI2的实现(一)——准备工作 转载请注明作者及来源:张峻崎,博客园 目前在.net的范围内,好的而且方便的ORM的真的不是很多,与VS集成 ...
- 基于数据库的自动化生成工具,自动生成JavaBean、自动生成数据库文档等(v4.1.2版)
目录: 第1版:http://blog.csdn.net/vipbooks/article/details/51912143 第2版:htt ...
- 基于Oracle的EntityFramework的WEBAPI2的实现(一)——准备工作
目前在.net的范围内,好的而且方便的ORM的真的不是很多,与VS集成方便的也就当属EntityFramework(以下简称EF,不知道为什么,总EF这个缩写好不专业).但是,好多公司使用的又是ORA ...
- 基于Oracle的EntityFramework的WEBAPI2的实现(三)—— 建立APIController及设置返回类型JSON、XML等
建立普通的ApiControler 右击项目中的controller文件夹·添加·控制器·包含操作的webapi2控制器(使用entity framework),写个名字,如果:Test.然后选择类, ...
- Asp.Net MVC WebApi2 自动生成帮助文档
WebAPI Help文档配置 开发环境VS2013+mvc5+WebApi2 一.通过NuGet引用Web API Test Client 安装后会多一个Areas文件夹 二.设置xml文档项目-- ...
- 基于Oracle的EntityFramework的WEBAPI2的实现(二)——使用DbFirst
之所以使用DbFirst而没有使用CodeFirst是因为考虑到现实的情况中,我们之所以会选择oracle而不是SQL SERVER,一方面是因为之前公司已经在使用Oracle,而且有好多我们需要用到 ...
- 基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(v6.0.0版)
TableGo v6.0.0 版震撼发布,此次版本更新如下: 1.UI界面大改版,组件大调整,提升界面功能的可扩展性. 2.新增BeautyEye主题,界面更加清新美观,也可以通过配置切换到原生Jav ...
- PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...
- PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...
随机推荐
- web前端 —— 移动端知识的一些总结
个人在移动端的一些总结归纳,有新的知识点会一直更新 一.css部分 1.meta标签 <meta name="viewport" content="width=de ...
- day6-面向对象补充篇--类的特殊成员
先说明一下,今天的内容主要转自师兄张其高的博客http://www.cnblogs.com/zhangqigao/articles/6935221.html 前面我们讲了类的方法,有普通方法,就是我们 ...
- vue router使用query和params传参的使用
传参是前端经常需要用的一个操作,很多场景都会需要用到上个页面的参数,本文将会详细介绍vue router 是如何进行传参的,以及一些小细节问题.有需要的朋友可以做一下参考,希望可以帮到大家. Vue ...
- 027——VUE中事件修饰符:stop prevent self capture
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SqlServer 转 Oracle 的几点注意
(转自:http://www.2cto.com/database/201208/146740.html) 1.字符型的字段相加需要用“||”,如果用“+”的话,会报“无效的数字”的错误. 2.类似 ...
- gzip压缩解压缩
压缩/解压缩压缩/解压缩之后的文件名称 必须是gz 解压缩
- MoreEffectiveC++Item35(效率)(条款16-24)
条款16 谨记80-20法则 条款17 考虑使用 lazy evaluation(缓释评估) 条款18 分期摊还预期的计算成本 条款19 了解临时对象的来源 条款20 协助完成"返回值的优化 ...
- 关于命名空间namespace
虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits).接口.函数和常量. 在声明命名空间之前唯一合法的代码是用于定义源文件编码方 ...
- 有关php的session
From:http://blog.csdn.net/sayigood/article/details/4850480 php中session的用法 PHP中的session默认情况下是使用客户端的Co ...
- cpu的用户态和内核态和内存的用户空间内核空间
谈到CPU的这两个工作状态,也就是处理器的这两个工作状态,那我们有必要说一下为什么搞出这两个鬼玩意出来. 用过电脑的娃娃们肯定知道在一个系统中既有操作系统的程序,也由普通用户的程序.但那么 ...