首页 编程语言 正文
  • 本文约10025字,阅读需50分钟
  • 684
  • 2

基于.Net Framework471搭建的WebAPI简单框架(下)

摘要

一、下载O/RM框架Nuget包 1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图: 二、下载PgSql的Nuget包 1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图: 三、下载AutoFac组件Nuget包 1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图: 四、下载AutoFac....

一、下载O/RM框架Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
25bebba723844a90916524a61946ca3f.png

二、下载PgSql的Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
c2ab96121b934fb981f6278e61aebfa7.png

三、下载AutoFac组件Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
44311dd80b884024b3795346d69ee597.png

四、下载AutoFac.Mvc5组件Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
c2ab96121b934fb981f6278e61aebfa7.png

五、下载AutoFac.WebApi2组件Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
7d45bedc402e45389a63deaebbc45951.png

六、下载Swagger组件Nuget包

1、右键解决方案名称,选择“解决方案的Nuget程序包”,进行安装。如图:
74fc754e9a5e4df786e1aabc51395204.png

七、对各层的引用关系进行配置

1、CK.Project.Web.Core无需引用任何项,默认跳过从CK.Project.Web.Application开始。

326af6091bc8418baf49ef40197fcc78.png

6e28cb370f294bb0949a138212b7a31a.png

2、配置CK.Project.Web.EntityFramework.Core的引用关系

bbc51ee4dbeb4a63b5d2c392f16a412a.png

37d5be9b598d4b31b96bd6ea68d02010.png

3、配置CK.Project.Web.WebApi的引用关系

55db5e14497d421788403705c15fb5ef.png

a5a0e4cdb4574f35a7b3bf0b01d0a941.png

八、配置PgSql的仓储类

1、选中CK.Project.Web.EntityFramework.Core,右键选择“新建文件夹”,命名为“Repository”,如图:

70ee5135e4424da787df281bcb533f54.png

2、选中Repository,右键选择“添加“——>”类“,命名为“PgRepository.cs”,如图:

f16bf7b6caad4f84aad706154fc0dfdb.png

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) =>
                {
                    //此处为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”文件。

ae5211fcf42f476391fce3fdc0310011.png

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
    {
        /// <summary>
        /// 依赖注入配置类
        /// </summary>
        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<>)).As(typeof(PgRepository<>));
                //WebAPI只用引用services和repository的接口,不用引用实现的dll。
                //如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll

                // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组
                string[] fileList = System.IO.Directory.GetFileSystemEntries(System.AppDomain.CurrentDomain.BaseDirectory + "/bin");
                // 遍历所有的文件和目录
                foreach (string file in fileList)
                {
                    var _file = file.Substring(file.LastIndexOf("\\") + 1);
                    if ((_file.ToUpper().IndexOf("CK.Project.Web") == 0 || _file.ToUpper().IndexOf("CK.PROJECT.WEB") == 0) && _file.ToUpper().EndsWith(".DLL"))
                    {
                        var Application = Assembly.Load(_file.ToUpper().Replace(".DLL", ""));
                        builder.RegisterAssemblyTypes(Application, Application)
                          .Where(t => t.Name.EndsWith("AppService"))
                          .AsImplementedInterfaces();
                    }
                }
            }
        }
    }

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), "Register")]

    namespace CK.Project.Web.WebApi
    {
        public class SwaggerConfig
        {
            public static void Register()
            {
                var thisAssembly = typeof(SwaggerConfig).Assembly;
                var xmlFile = string.Format("{0}/bin/CK.Project.Web.WebApi.XML", System.AppDomain.CurrentDomain.BaseDirectory);

                GlobalConfiguration.Configuration
                    .EnableSwagger(c =>
                        {
                            c.SingleApiVersion("v1", "CK.Project.Web.WebAPI接口文档");
                            if (System.IO.File.Exists(xmlFile))
                            {
                                c.IncludeXmlComments(xmlFile);
                            }
                            // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组
                            string[] fileList = System.IO.Directory.GetFileSystemEntries(System.AppDomain.CurrentDomain.BaseDirectory + "/bin");
                            // 遍历所有的文件和目录
                            foreach (string file in fileList)
                            {
                                var _file = file.Substring(file.LastIndexOf("\\") + 1);
                                if (_file.ToUpper().IndexOf("CK.PROJECT.WEB") == 0)
                                {
                                    if (_file.ToUpper().EndsWith("APPLICATION.XML") || _file.ToUpper().EndsWith("CORE.XML"))
                                    {
                                        if (System.IO.File.Exists(GetXmlCommentsPath(_file)))
                                        {
                                            c.IncludeXmlComments(GetXmlCommentsPath(_file));
                                        }
                                    }
                                }
                            }
                            c.IncludeXmlComments(string.Format("{0}/bin/CK.Project.Web.WebApi.XML", System.AppDomain.CurrentDomain.BaseDirectory));
                            c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
                        })
                    .EnableSwaggerUi(c =>
                        {
                            //路径规则,项目命名空间.文件夹名称.js文件名称
                            c.InjectJavaScript(thisAssembly, "CK.Project.Web.WebApi.Scripts.Swaggerui.swagger_lang.js");
                        });
            }

            private static string GetXmlCommentsPath(string name)
            {
                return string.Format("{0}/bin/{1}", System.AppDomain.CurrentDomain.BaseDirectory, name);
            }
        }
    }

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
    {
        /// <summary>
        /// swagger显示控制器的描述
        /// </summary>
        public class CachingSwaggerProvider : ISwaggerProvider
        {
            private static ConcurrentDictionary<string, SwaggerDocument> _cache =
                new ConcurrentDictionary<string, SwaggerDocument>();

            private readonly ISwaggerProvider _swaggerProvider;
            /// <summary>
            /// </summary>
            /// <param name="swaggerProvider"></param>
            public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
            {
                _swaggerProvider = swaggerProvider;
            }
            /// <summary>
            /// </summary>
            /// <param name="rootUrl"></param>
            /// <param name="apiVersion"></param>
            /// <returns></returns>
            public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
            {
                var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
                SwaggerDocument srcDoc = null;
                //只读取一次
                if (!_cache.TryGetValue(cacheKey, out srcDoc))
                {
                    srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);

                    srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } };
                    _cache.TryAdd(cacheKey, srcDoc);
                }
                return srcDoc;
            }

            /// <summary>
            /// 从API文档中读取控制器描述
            /// </summary>
            /// <returns>所有控制器描述</returns>
            public static ConcurrentDictionary<string, string> GetControllerDesc()
            {
                string xmlpath = string.Format("{0}/bin/CK.Project.Web.WebApi.XML", System.AppDomain.CurrentDomain.BaseDirectory);
                ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
                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 = "Controller".Length;
                    XmlNode summaryNode = null;
                    foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                    {
                        type = node.Attributes["name"].Value;
                        if (type.StartsWith("T:"))
                        {
                            //控制器
                            arrPath = type.Split('.');
                            length = arrPath.Length;
                            controllerName = arrPath[length - 1];
                            if (controllerName.EndsWith("Controller"))
                            {
                                //获取控制器注释
                                summaryNode = node.SelectSingleNode("summary");
                                string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                                if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                                {
                                    controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
                                }
                            }
                        }
                    }
                }
                return controllerDescDict;
            }
        }
    }

3、新建“Scripts”文件夹——>在里面新建"Swaggerui"文件夹——>在里面新建“swagger_lang.js”文件,用于对Swagger进行中文汉化脚本。

7615e0fe82584ef999015331f9dad67c.png

4、js内容如下:

    /// <summary>
    /// 中文转换
    /// </summary>
    var SwaggerTranslator = (function () {
        //定时执行检测是否转换成中文,最多执行500次  即500*50/1000=25s
        var iexcute = 0,
            //中文语言包
            _words = {
                "Warning: Deprecated": "警告:已过时",
                "Implementation Notes": "实现备注",
                "Response Class": "响应类",
                "Status": "状态",
                "Parameters": "参数",
                "Parameter": "参数",
                "Value": "值",
                "Description": "描述",
                "Parameter Type": "参数类型",
                "Data Type": "数据类型",
                "Response Messages": "响应消息",
                "HTTP Status Code": "HTTP状态码",
                "Reason": "原因",
                "Response Model": "响应模型",
                "Request URL": "请求URL",
                "Response Body": "响应体",
                "Response Code": "响应码",
                "Response Headers": "响应头",
                "Hide Response": "隐藏响应",
                "Headers": "头",
                "Try it out!": "试一下!",
                "Show/Hide": "显示/隐藏",
                "List Operations": "显示操作",
                "Expand Operations": "展开操作",
                "Raw": "原始",
                "can't parse JSON.  Raw result": "无法解析JSON. 原始结果",
                "Model Schema": "模型架构",
                "Model": "模型",
                "apply": "应用",
                "Username": "用户名",
                "Password": "密码",
                "Terms of service": "服务条款",
                "Created by": "创建者",
                "See more at": "查看更多:",
                "Contact the developer": "联系开发者",
                "api version": "api版本",
                "Response Content Type": "响应Content Type",
                "fetching resource": "正在获取资源",
                "fetching resource list": "正在获取资源列表",
                "Explore": "浏览",
                "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis",
                "Can't read from server.  It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。",
                "Please specify the protocol for": "请指定协议:",
                "Can't read swagger JSON from": "无法读取swagger JSON于",
                "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI",
                "Unable to read api": "无法读取api",
                "from path": "从路径",
                "Click to set as parameter value": "点击设置参数",
                "server returned": "服务器返回"
            },
            //定时执行转换
            _translator2Cn = function () {
                if ($("#resources_container .resource").length > 0) {
                    _tryTranslate();
                }

                if ($("#explore").text() == "Explore" && iexcute > 500) {
                    iexcute++;
                    setTimeout(_translator2Cn, 50);
                }
            },
            //设置控制器注释
            _setControllerSummary = function () {
                $.ajax({
                    type: "get",
                    async: true,
                    url: $("#input_baseUrl").val(),
                    dataType: "json",
                    success: function (data) {
                        var summaryDict = data.ControllerDesc;
                        var id, controllerName, strSummary;
                        $("#resources_container .resource").each(function (i, item) {
                            id = $(item).attr("id");
                            if (id) {
                                controllerName = id.substring(9);
                                strSummary = summaryDict[controllerName];
                                if (strSummary) {
                                    $(item).children(".heading").children(".options").prepend('<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
                                }
                            }
                        });
                    }
                });
            },
            //尝试将英文转换成中文
            _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("1");
                document.title = "API描述文档";
                $('body').append('<style type="text/css">.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;} </style>');
                $("#logo").html("接口描述").attr("href", "/Home/Index");
                //设置控制器描述
                _setControllerSummary();
                _translator2Cn();
            }
        }
    })();
    //执行转换
    SwaggerTranslator.Translator();

5、将项目的起始页设置为Swagger主页。

19533d2fc94949059ea8c17eea762c68.png

6、在特定页的右侧文本框写入“swagger/ui/index”后,按Ctrl+S保存即可。

934525abb8ae4599861e9662e5d38259.png

标签:.netwebApi
友情链接