zoukankan      html  css  js  c++  java
  • 部署WebApi随笔

    一、跨域

    NuGet引用Microsoft.AspNet.WebApi.Cors

    WebApiConfig.cs中配置:

    // Web API 配置和服务
    config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

    二、清除默认返回XML格式

    Global.asax中配置:

    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
    

    三、Oracle配置

    NuGet引用Oracle.ManagedDataAccess

    1、根据插件生成App.config中的配置添加到Web.config中

    2、引用Oracle.ManagedDataAccess.Client

    四、log4net

    1、NuGet引用log4net

    2、AssemblyInfo.cs中配置:

    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
    

    3、新建Log4Net.config配置文件

    属性-复制到输出目录改为如果较新则复制

    Log4Net.config中配置:

    <!-- Level的级别,由高到低 -->
    <!-- None > Fatal > ERROR > WARN > DEBUG > INFO > ALL-->
    <log4net>
      <!--信息日志类-->
      <logger name="loginfo">
        <level value="INFO" />
        <appender-ref ref="InfoAppender" />
      </logger>
      <!--错误日志类-->
      <logger name="logerror">
        <level value="ERROR" />
        <appender-ref ref="ErrorAppender" />
      </logger>
      <!--信息日志附加介质-->
      <!-- name属性指定其名称,type则是log4net.Appender命名空间的一个类的名称-->
      <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
        <!--日志输出到exe程序这个相对目录下-->
        <param name="File" value="Log4Net\LogInfo\" />
        <!--输出的日志不会覆盖以前的信息-->
        <param name="AppendToFile" value="true" />
        <!--日志文件的最大大小-->
        <param name="MaximumFileSize" value="2MB" />
        <!--备份文件的个数-->
        <param name="MaxSizeRollBackups" value="10" />
        <!--是否使用静态文件名-->
        <param name="StaticLogFileName" value="false" />
        <!--日志文件名-->
        <param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" />
        <!--文件创建的方式-->
        <param name="RollingStyle" value="Composite" />
        <!--过滤器-->
        <lockingMode type="Asia.Mobile.ApiService.Filter.MinimalLockDeleteEmpty"></lockingMode>
        <!--信息日志布局-->
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="日志时间:%d [%t] &lt;BR&gt;%n日志级别:%-5p &lt;BR&gt;%n日 志 类:%c [%x] &lt;BR&gt;%n%m &lt;BR&gt;%n &#xD;&#xA;" />
        </layout>
      </appender>
      <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="Log4Net\LogError\" />
        <param name="AppendToFile" value="true" />
        <param name="MaxSizeRollBackups" value="100" />
        <param name="MaxFileSize" value="10240" />
        <param name="StaticLogFileName" value="false" />
        <param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" />
        <param name="RollingStyle" value="Date" />
        <lockingMode type="Asia.Mobile.ApiService.Filter.MinimalLockDeleteEmpty"></lockingMode>
        <!--错误日志布局-->
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="&lt;HR COLOR=red&gt;%n异常时间:%d [%t] &lt;BR&gt;%n异常级别:%-5p &#xD;&#xA;   &lt;BR&gt;%n异 常 类:%c [%x] &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;" />
        </layout>
      </appender>
    </log4net>
    View Code

    4、新增Log4NetHelper.cs帮助类

    public class Log4NetHelper
        {
            public static readonly log4net.ILog loginfo = log4net.LogManager.GetLogger("loginfo");
            public static readonly log4net.ILog logerror = log4net.LogManager.GetLogger("logerror");
    
            public static void WriteLog(string info)
            {
                if (loginfo.IsInfoEnabled)
                {
                    loginfo.Info(info);
                }
            }
    
            public static void WriteLog(string info, Exception ex)
            {
                if (logerror.IsErrorEnabled)
                {
                    logerror.Error(info, ex);
                }
            }
        }
    View Code

    5、新建logFilter.cs过滤器

    在控制器上添加:[ApiLogFilterAttribute]

    五、swagger

    1、NuGet引用Swashbuckle

     2、新增实现了ISwaggerProvider的接口类:

    在App_Start文件夹中添加SwaggerControllerDescProvider.cs

    /// <summary>
        /// 显示swagger控制器的描述
        /// </summary>
        public class SwaggerControllerDescProvider : ISwaggerProvider
        {
            private readonly ISwaggerProvider _swaggerProvider;
            private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
            private readonly string _xml;
            /// <summary>
            /// 
            /// </summary>
            /// <param name="swaggerProvider"></param>
            /// <param name="xml">xml文档路径</param>
            public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
            {
                _swaggerProvider = swaggerProvider;
                _xml = xml;
            }
    
            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 ConcurrentDictionary<string, string> GetControllerDesc()
            {
                string xmlpath = _xml;
                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;
            }
        }
    View Code

    3、新增SwaggerConfig.js,设置成嵌入式资源

    功能:1、汉化 2、界面控制器的面熟

    'use strict';
    window.SwaggerTranslator = {
        _words: [],
    
        translate: function () {
            var $this = this;
            $('[data-sw-translate]').each(function () {
                $(this).html($this._tryTranslate($(this).html()));
                $(this).val($this._tryTranslate($(this).val()));
                $(this).attr('title', $this._tryTranslate($(this).attr('title')));
            });
        },
    
        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").first().prepend('<li class="controller-summary" title="' + strSummary + '">' + strSummary + '</li>');
                            }
                        }
                    });
                }
            });
        },
        _tryTranslate: function (word) {
            return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
        },
    
        learn: function (wordsMap) {
            this._words = wordsMap;
        }
    };
    
    
    /* jshint quotmark: double */
    window.SwaggerTranslator.learn({
        "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": "从路径",
        "server returned": "服务器返回"
    });
    $(function () {
        window.SwaggerTranslator.translate();
        window.SwaggerTranslator.setControllerSummary();
    });
    View Code

    4、配置SwaggerConfig.cs

    public class SwaggerConfig
        {
            public static void Register()
            {
                var thisAssembly = typeof(SwaggerConfig).Assembly;
    
                GlobalConfiguration.Configuration
                    .EnableSwagger(c =>
                        {
                            c.SingleApiVersion("v1", "Asia.Mobile.ApiService");
                            //添加下述代码                        
                            var xmlFile = string.Format("{0}/bin/Asia.Mobile.ApiService.XML", System.AppDomain.CurrentDomain.BaseDirectory);
                            if (System.IO.File.Exists(xmlFile))
                            {
                                c.IncludeXmlComments(xmlFile);
                            }
                            c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                            c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, xmlFile));
                        })
                    .EnableSwaggerUi(c =>
                        {
                            c.InjectJavaScript(Assembly.GetExecutingAssembly(), "Asia.Mobile.ApiService.Scripts.SwaggerConfig.js");
                        });
            }
        }
    View Code

    5、配置项目的XML文档文件

     6、取消警告提示

    6、分组

    新增描述信息过滤器:

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
        public class ControllerGroupAttribute : Attribute
        {
            /// <summary>
            /// 当前Controller所属模块 请用中文
            /// </summary>
            public string GroupName { get; private set; }
    
            /// <summary>
            /// 当前controller用途    请用中文
            /// </summary>
            public string Useage { get; private set; }
    
            /// <summary>
            ///  Controller描述信息 构造
            /// </summary>
            /// <param name="groupName">模块名称</param>
            /// <param name="useage">当前controller用途</param>
            public ControllerGroupAttribute(string groupName, string useage)
            {
                if (string.IsNullOrEmpty(groupName) || string.IsNullOrEmpty(useage))
                {
                    throw new ArgumentNullException("groupName||useage");
                }
                GroupName = groupName;
                Useage = useage;
            }
        }
    View Code

    给Controller加上这个Attribute,再给SwaggerConfig.cs进行分组操作:

    c.GroupActionsBy(apiDesc => apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().Any() ? 
    apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().First().GroupName + "_" + 
    apiDesc.GetControllerAndActionAttributes<ControllerGroupAttribute>().First().Useage : "无模块归类");
    View Code
  • 相关阅读:
    软件测试人员的年终绩效考核怎么应对
    收藏
    顶踩组件 前后两版
    订阅组件
    hdu 1963 Investment 完全背包
    hdu 4939 Stupid Tower Defense 动态规划
    hdu 4405 Aeroplane chess 动态规划
    cf 414B Mashmokh and ACM 动态规划
    BUPT 202 Chocolate Machine 动态规划
    hdu 3853 LOOPS 动态规划
  • 原文地址:https://www.cnblogs.com/mutare/p/12433620.html
Copyright © 2011-2022 走看看