一、下载O/RM框架Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
二、下载PgSql的Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
三、下载AutoFac组件Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
四、下载AutoFac.Mvc5组件Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
五、下载AutoFac.WebApi2组件Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
六、下载Swagger组件Nuget包
1、右键解决方案名称,选择"解决方案的Nuget程序包",进行安装。如图:
七、对各层的引用关系进行配置
1、CK.Project.Web.Core无需引用任何项,默认跳过从CK.Project.Web.Application开始。
2、配置CK.Project.Web.EntityFramework.Core的引用关系
3、配置CK.Project.Web.WebApi的引用关系
八、配置PgSql的仓储类
1、选中CK.Project.Web.EntityFramework.Core,右键选择"新建文件夹",命名为"Repository",如图:
2、选中Repository,右键选择"添加"------>"类",命名为"PgRepository.cs",如图:
3、编写如下代码:
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CK.Project.Web.EntityFramework.Core
{
/// <summary>
/// PgSql仓储模块
/// </summary>
public class PgRepository<T> : SimpleClient<T> where T : class, new()
{
public PgRepository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
{
if (context == null)
{
base.Context = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.PostgreSQL,//此处为设置数据库,支持各大主流数据库
InitKeyType = InitKeyType.Attribute,//此处为初始化配置类型,有按特性进行初始化,也有其他的进行初始化
IsAutoCloseConnection = true,//此处为是否自动关闭数据库连接,可以理解为是DBHelper里的Close()方法
MoreSettings = new ConnMoreSettings()
{
PgSqlIsAutoToLower = true //数据库存在大写字段的
//,需要把这个设为false ,并且实体和字段名称要一样
//如果数据库里的数据表本身就为小写,则改成true
//详细可以参考官网https://www.donet5.com/Home/Doc
},
ConnectionString = ConfigurationManager.AppSettings["pgsqlStr"] //此处为数据库连接字符串
});
base.Context.Aop.OnError = (ex) =&gt;
{
//此处为AOP切面编程代码块,常用于数据库连接日志记录
//或者查看详细的报错信息,打印ex的内容即可
};
}
}
}
}
4、在WebApi层的Web.Config的节点下编写数据库字符串,代码如下:
<add key="pgsqlStr" value="PORT={数据库端口号};DATABASE={数据库名};HOST={IP地址};PASSWORD={数据库密码};USER ID={数据库账号}" />
九、配置AutoFac.IoC依赖注入
1、在CK.Project.Web.WebApi层里的App_Start文件夹中新建名为"AutofacConfig.cs"文件。
2、编写如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using Autofac;
using Autofac.Integration.Mvc;
using Autofac.Integration.WebApi;
using CK.Project.Web.EntityFramework.Core;
namespace CK.Project.Web.WebApi.App_Start
{
/// &lt;summary&gt;
/// 依赖注入配置类
/// &lt;/summary&gt;
public class AutofacConfig
{
public static void CoreAutoFacInit()
{
var builder = new ContainerBuilder();
HttpConfiguration config = GlobalConfiguration.Configuration;
SetupResolveRules(builder);
//注册所有的ApiControllers
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
var container = builder.Build();
//注册api容器需要使用HttpConfiguration对象
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
private static void SetupResolveRules(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(PgRepository&lt;&gt;)).As(typeof(PgRepository&lt;&gt;));
//WebAPI只用引用services和repository的接口,不用引用实现的dll。
//如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll
// 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组
string[] fileList = System.IO.Directory.GetFileSystemEntries(System.AppDomain.CurrentDomain.BaseDirectory + &quot;/bin&quot;);
// 遍历所有的文件和目录
foreach (string file in fileList)
{
var _file = file.Substring(file.LastIndexOf(&quot;\\&quot;) + 1);
if ((_file.ToUpper().IndexOf(&quot;CK.Project.Web&quot;) == 0 || _file.ToUpper().IndexOf(&quot;CK.PROJECT.WEB&quot;) == 0) &amp;amp;&amp;amp; _file.ToUpper().EndsWith(&quot;.DLL&quot;))
{
var Application = Assembly.Load(_file.ToUpper().Replace(&quot;.DLL&quot;, &quot;&quot;));
builder.RegisterAssemblyTypes(Application, Application)
.Where(t =&amp;gt; t.Name.EndsWith(&quot;AppService&quot;))
.AsImplementedInterfaces();
}
}
}
}
}
</code>
</pre>
3、在Global.asax的Application_Start方法中加入如下代码:
//依赖注入
AutofacConfig.CoreAutoFacInit();
十、部署Swagger文档
1、在CK.Project.Web.WebApi层里的App_Start文件夹中新建名为"SwaggerConfig.cs"文件(如果已存在,则无需新建)。
using System.Web.Http;
using WebActivatorEx;
using CK.Project.Web.WebApi;
using Swashbuckle.Application;
using CK.Project.Web.WebApi.App_Start;
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), &quot;Register&quot;)]
namespace CK.Project.Web.WebApi
{
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
var xmlFile = string.Format(&quot;{0}/bin/CK.Project.Web.WebApi.XML&quot;, System.AppDomain.CurrentDomain.BaseDirectory);
GlobalConfiguration.Configuration
.EnableSwagger(c =&amp;amp;gt;
{
c.SingleApiVersion(&amp;quot;v1&amp;quot;, &amp;quot;CK.Project.Web.WebAPI接口文档&amp;quot;);
if (System.IO.File.Exists(xmlFile))
{
c.IncludeXmlComments(xmlFile);
}
// 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组
string[] fileList = System.IO.Directory.GetFileSystemEntries(System.AppDomain.CurrentDomain.BaseDirectory + &amp;quot;/bin&amp;quot;);
// 遍历所有的文件和目录
foreach (string file in fileList)
{
var _file = file.Substring(file.LastIndexOf(&amp;quot;\\&amp;quot;) + 1);
if (_file.ToUpper().IndexOf(&amp;quot;CK.PROJECT.WEB&amp;quot;) == 0)
{
if (_file.ToUpper().EndsWith(&amp;quot;APPLICATION.XML&amp;quot;) || _file.ToUpper().EndsWith(&amp;quot;CORE.XML&amp;quot;))
{
if (System.IO.File.Exists(GetXmlCommentsPath(_file)))
{
c.IncludeXmlComments(GetXmlCommentsPath(_file));
}
}
}
}
c.IncludeXmlComments(string.Format(&amp;quot;{0}/bin/CK.Project.Web.WebApi.XML&amp;quot;, System.AppDomain.CurrentDomain.BaseDirectory));
c.CustomProvider((defaultProvider) =&amp;amp;gt; new CachingSwaggerProvider(defaultProvider));
})
.EnableSwaggerUi(c =&amp;amp;gt;
{
//路径规则,项目命名空间.文件夹名称.js文件名称
c.InjectJavaScript(thisAssembly, &amp;quot;CK.Project.Web.WebApi.Scripts.Swaggerui.swagger_lang.js&amp;quot;);
});
}
private static string GetXmlCommentsPath(string name)
{
return string.Format(&amp;amp;quot;{0}/bin/{1}&amp;amp;quot;, System.AppDomain.CurrentDomain.BaseDirectory, name);
}
}
}
&lt;/code&gt;
&lt;/pre&gt;
2、在CK.Project.Web.WebApi层里的App_Start文件夹中新建名为"CachingSwaggerProvider.cs"文件。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using Swashbuckle.Swagger;
namespace CK.Project.Web.WebApi.App_Start
{
/// &amp;amp;lt;summary&amp;amp;gt;
/// swagger显示控制器的描述
/// &amp;amp;lt;/summary&amp;amp;gt;
public class CachingSwaggerProvider : ISwaggerProvider
{
private static ConcurrentDictionary&amp;amp;lt;string, SwaggerDocument&amp;amp;gt; _cache =
new ConcurrentDictionary&amp;amp;lt;string, SwaggerDocument&amp;amp;gt;();
private readonly ISwaggerProvider _swaggerProvider;
/// &amp;amp;amp;lt;summary&amp;amp;amp;gt;
/// &amp;amp;amp;lt;/summary&amp;amp;amp;gt;
/// &amp;amp;amp;lt;param name=&amp;amp;quot;swaggerProvider&amp;amp;quot;&amp;amp;amp;gt;&amp;amp;amp;lt;/param&amp;amp;amp;gt;
public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
{
_swaggerProvider = swaggerProvider;
}
/// &amp;amp;amp;lt;summary&amp;amp;amp;gt;
/// &amp;amp;amp;lt;/summary&amp;amp;amp;gt;
/// &amp;amp;amp;lt;param name=&amp;amp;quot;rootUrl&amp;amp;quot;&amp;amp;amp;gt;&amp;amp;amp;lt;/param&amp;amp;amp;gt;
/// &amp;amp;amp;lt;param name=&amp;amp;quot;apiVersion&amp;amp;quot;&amp;amp;amp;gt;&amp;amp;amp;lt;/param&amp;amp;amp;gt;
/// &amp;amp;amp;lt;returns&amp;amp;amp;gt;&amp;amp;amp;lt;/returns&amp;amp;amp;gt;
public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
{
var cacheKey = string.Format(&amp;amp;quot;{0}_{1}&amp;amp;quot;, rootUrl, apiVersion);
SwaggerDocument srcDoc = null;
//只读取一次
if (!_cache.TryGetValue(cacheKey, out srcDoc))
{
srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
srcDoc.vendorExtensions = new Dictionary&amp;amp;amp;amp;lt;string, object&amp;amp;amp;amp;gt; { { &amp;amp;amp;quot;ControllerDesc&amp;amp;amp;quot;, GetControllerDesc() } };
_cache.TryAdd(cacheKey, srcDoc);
}
return srcDoc;
}
/// &amp;amp;amp;amp;lt;summary&amp;amp;amp;amp;gt;
/// 从API文档中读取控制器描述
/// &amp;amp;amp;amp;lt;/summary&amp;amp;amp;amp;gt;
/// &amp;amp;amp;amp;lt;returns&amp;amp;amp;amp;gt;所有控制器描述&amp;amp;amp;amp;lt;/returns&amp;amp;amp;amp;gt;
public static ConcurrentDictionary&amp;amp;amp;amp;lt;string, string&amp;amp;amp;amp;gt; GetControllerDesc()
{
string xmlpath = string.Format(&amp;amp;amp;quot;{0}/bin/CK.Project.Web.WebApi.XML&amp;amp;amp;quot;, System.AppDomain.CurrentDomain.BaseDirectory);
ConcurrentDictionary&amp;amp;amp;amp;lt;string, string&amp;amp;amp;amp;gt; controllerDescDict = new ConcurrentDictionary&amp;amp;amp;amp;lt;string, string&amp;amp;amp;amp;gt;();
if (File.Exists(xmlpath))
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(xmlpath);
string type = string.Empty, path = string.Empty, controllerName = string.Empty;
string[] arrPath;
int length = -1, cCount = &amp;amp;amp;quot;Controller&amp;amp;amp;quot;.Length;
XmlNode summaryNode = null;
foreach (XmlNode node in xmldoc.SelectNodes(&amp;amp;amp;quot;//member&amp;amp;amp;quot;))
{
type = node.Attributes[&amp;amp;amp;quot;name&amp;amp;amp;quot;].Value;
if (type.StartsWith(&amp;amp;amp;quot;T:&amp;amp;amp;quot;))
{
//控制器
arrPath = type.Split('.');
length = arrPath.Length;
controllerName = arrPath[length - 1];
if (controllerName.EndsWith(&amp;amp;amp;quot;Controller&amp;amp;amp;quot;))
{
//获取控制器注释
summaryNode = node.SelectSingleNode(&amp;amp;amp;quot;summary&amp;amp;amp;quot;);
string key = controllerName.Remove(controllerName.Length - cCount, cCount);
if (summaryNode != null &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; !string.IsNullOrEmpty(summaryNode.InnerText) &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; !controllerDescDict.ContainsKey(key))
{
controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
}
}
}
}
}
return controllerDescDict;
}
}
}
&amp;lt;/code&amp;gt;
&amp;lt;/pre&amp;gt;
3、新建&quot;Scripts&quot;文件夹------&amp;gt;在里面新建&quot;Swaggerui&quot;文件夹------&amp;gt;在里面新建&quot;swagger_lang.js&quot;文件,用于对Swagger进行中文汉化脚本。
4、js内容如下:
/// &amp;lt;summary&amp;gt;
/// 中文转换
/// &amp;lt;/summary&amp;gt;
var SwaggerTranslator = (function () {
//定时执行检测是否转换成中文,最多执行500次 即500*50/1000=25s
var iexcute = 0,
//中文语言包
_words = {
&amp;quot;Warning: Deprecated&amp;quot;: &amp;quot;警告:已过时&amp;quot;,
&amp;quot;Implementation Notes&amp;quot;: &amp;quot;实现备注&amp;quot;,
&amp;quot;Response Class&amp;quot;: &amp;quot;响应类&amp;quot;,
&amp;quot;Status&amp;quot;: &amp;quot;状态&amp;quot;,
&amp;quot;Parameters&amp;quot;: &amp;quot;参数&amp;quot;,
&amp;quot;Parameter&amp;quot;: &amp;quot;参数&amp;quot;,
&amp;quot;Value&amp;quot;: &amp;quot;值&amp;quot;,
&amp;quot;Description&amp;quot;: &amp;quot;描述&amp;quot;,
&amp;quot;Parameter Type&amp;quot;: &amp;quot;参数类型&amp;quot;,
&amp;quot;Data Type&amp;quot;: &amp;quot;数据类型&amp;quot;,
&amp;quot;Response Messages&amp;quot;: &amp;quot;响应消息&amp;quot;,
&amp;quot;HTTP Status Code&amp;quot;: &amp;quot;HTTP状态码&amp;quot;,
&amp;quot;Reason&amp;quot;: &amp;quot;原因&amp;quot;,
&amp;quot;Response Model&amp;quot;: &amp;quot;响应模型&amp;quot;,
&amp;quot;Request URL&amp;quot;: &amp;quot;请求URL&amp;quot;,
&amp;quot;Response Body&amp;quot;: &amp;quot;响应体&amp;quot;,
&amp;quot;Response Code&amp;quot;: &amp;quot;响应码&amp;quot;,
&amp;quot;Response Headers&amp;quot;: &amp;quot;响应头&amp;quot;,
&amp;quot;Hide Response&amp;quot;: &amp;quot;隐藏响应&amp;quot;,
&amp;quot;Headers&amp;quot;: &amp;quot;头&amp;quot;,
&amp;quot;Try it out!&amp;quot;: &amp;quot;试一下!&amp;quot;,
&amp;quot;Show/Hide&amp;quot;: &amp;quot;显示/隐藏&amp;quot;,
&amp;quot;List Operations&amp;quot;: &amp;quot;显示操作&amp;quot;,
&amp;quot;Expand Operations&amp;quot;: &amp;quot;展开操作&amp;quot;,
&amp;quot;Raw&amp;quot;: &amp;quot;原始&amp;quot;,
&amp;quot;can't parse JSON. Raw result&amp;quot;: &amp;quot;无法解析JSON. 原始结果&amp;quot;,
&amp;quot;Model Schema&amp;quot;: &amp;quot;模型架构&amp;quot;,
&amp;quot;Model&amp;quot;: &amp;quot;模型&amp;quot;,
&amp;quot;apply&amp;quot;: &amp;quot;应用&amp;quot;,
&amp;quot;Username&amp;quot;: &amp;quot;用户名&amp;quot;,
&amp;quot;Password&amp;quot;: &amp;quot;密码&amp;quot;,
&amp;quot;Terms of service&amp;quot;: &amp;quot;服务条款&amp;quot;,
&amp;quot;Created by&amp;quot;: &amp;quot;创建者&amp;quot;,
&amp;quot;See more at&amp;quot;: &amp;quot;查看更多:&amp;quot;,
&amp;quot;Contact the developer&amp;quot;: &amp;quot;联系开发者&amp;quot;,
&amp;quot;api version&amp;quot;: &amp;quot;api版本&amp;quot;,
&amp;quot;Response Content Type&amp;quot;: &amp;quot;响应Content Type&amp;quot;,
&amp;quot;fetching resource&amp;quot;: &amp;quot;正在获取资源&amp;quot;,
&amp;quot;fetching resource list&amp;quot;: &amp;quot;正在获取资源列表&amp;quot;,
&amp;quot;Explore&amp;quot;: &amp;quot;浏览&amp;quot;,
&amp;quot;Show Swagger Petstore Example Apis&amp;quot;: &amp;quot;显示 Swagger Petstore 示例 Apis&amp;quot;,
&amp;quot;Can't read from server. It may not have the appropriate access-control-origin settings.&amp;quot;: &amp;quot;无法从服务器读取。可能没有正确设置access-control-origin。&amp;quot;,
&amp;quot;Please specify the protocol for&amp;quot;: &amp;quot;请指定协议:&amp;quot;,
&amp;quot;Can't read swagger JSON from&amp;quot;: &amp;quot;无法读取swagger JSON于&amp;quot;,
&amp;quot;Finished Loading Resource Information. Rendering Swagger UI&amp;quot;: &amp;quot;已加载资源信息。正在渲染Swagger UI&amp;quot;,
&amp;quot;Unable to read api&amp;quot;: &amp;quot;无法读取api&amp;quot;,
&amp;quot;from path&amp;quot;: &amp;quot;从路径&amp;quot;,
&amp;quot;Click to set as parameter value&amp;quot;: &amp;quot;点击设置参数&amp;quot;,
&amp;quot;server returned&amp;quot;: &amp;quot;服务器返回&amp;quot;
},
//定时执行转换
_translator2Cn = function () {
if ($(&amp;quot;#resources_container .resource&amp;quot;).length &amp;gt; 0) {
_tryTranslate();
}
if ($(&amp;amp;quot;#explore&amp;amp;quot;).text() == &amp;amp;quot;Explore&amp;amp;quot; &amp;amp;amp;amp;&amp;amp;amp;amp; iexcute &amp;amp;amp;gt; 500) {
iexcute++;
setTimeout(_translator2Cn, 50);
}
},
//设置控制器注释
_setControllerSummary = function () {
$.ajax({
type: &amp;amp;quot;get&amp;amp;quot;,
async: true,
url: $(&amp;amp;quot;#input_baseUrl&amp;amp;quot;).val(),
dataType: &amp;amp;quot;json&amp;amp;quot;,
success: function (data) {
var summaryDict = data.ControllerDesc;
var id, controllerName, strSummary;
$(&amp;amp;quot;#resources_container .resource&amp;amp;quot;).each(function (i, item) {
id = $(item).attr(&amp;amp;quot;id&amp;amp;quot;);
if (id) {
controllerName = id.substring(9);
strSummary = summaryDict[controllerName];
if (strSummary) {
$(item).children(&amp;amp;quot;.heading&amp;amp;quot;).children(&amp;amp;quot;.options&amp;amp;quot;).prepend('&amp;amp;amp;lt;li class=&amp;amp;quot;controller-summary&amp;amp;quot; title=&amp;amp;quot;' + strSummary + '&amp;amp;quot;&amp;amp;amp;gt;' + strSummary + '&amp;amp;amp;lt;/li&amp;amp;amp;gt;');
}
}
});
}
});
},
//尝试将英文转换成中文
_tryTranslate = function () {
$('[data-sw-translate]').each(function () {
$(this).html(_getLangDesc($(this).html()));
$(this).val(_getLangDesc($(this).val()));
$(this).attr('title', _getLangDesc($(this).attr('title')));
});
},
_getLangDesc = function (word) {
return _words[$.trim(word)] !== undefined ? _words[$.trim(word)] : word;
};
return {
Translator: function () {
console.warn(&amp;amp;quot;1&amp;amp;quot;);
document.title = &amp;amp;quot;API描述文档&amp;amp;quot;;
$('body').append('&amp;amp;amp;lt;style type=&amp;amp;quot;text/css&amp;amp;quot;&amp;amp;amp;gt;.controller-summary{color:#10a54a !important;word-break:keep-all;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:250px;text-align:right;cursor:default;} &amp;amp;amp;lt;/style&amp;amp;amp;gt;');
$(&amp;amp;quot;#logo&amp;amp;quot;).html(&amp;amp;quot;接口描述&amp;amp;quot;).attr(&amp;amp;quot;href&amp;amp;quot;, &amp;amp;quot;/Home/Index&amp;amp;quot;);
//设置控制器描述
_setControllerSummary();
_translator2Cn();
}
}
})();
//执行转换
SwaggerTranslator.Translator();
&amp;amp;lt;/code&amp;amp;gt;
&amp;amp;lt;/pre&amp;amp;gt;
5、将项目的起始页设置为Swagger主页。
6、在特定页的右侧文本框写入&amp;quot;swagger/ui/index&amp;quot;后,按Ctrl+S保存即可。