Startup.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Net;
  6. using System.Net.Http;
  7. using System.Text;
  8. using System.Web.Http;
  9. using System.Web.Http.Filters;
  10. using System.Web.Http.Routing;
  11. using System.Xml;
  12. using Microsoft.Owin;
  13. using Microsoft.Owin.Cors;
  14. using Newtonsoft.Json;
  15. using Newtonsoft.Json.Serialization;
  16. using Owin;
  17. using Swashbuckle.Application;
  18. using Swashbuckle.Swagger;
  19. using XdCxRhDW.App.WebAPI;
  20. [assembly: OwinStartup(typeof(XdCxRhDW.App.WebAPI.Startup))]
  21. namespace XdCxRhDW.App.WebAPI
  22. {
  23. class Startup
  24. {
  25. public void Configuration(IAppBuilder app)
  26. {
  27. HttpConfiguration config = new HttpConfiguration();
  28. JsonSerializerSettings setting = new JsonSerializerSettings()
  29. {
  30. //日期类型默认格式化处理
  31. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
  32. DateFormatString = "yyyy-MM-dd HH:mm:ss",
  33. //驼峰样式
  34. ContractResolver = new CamelCasePropertyNamesContractResolver(),
  35. //空值处理
  36. //NullValueHandling = NullValueHandling.Ignore,
  37. //设置序列化的最大层数
  38. MaxDepth = 10,
  39. //解决json序列化时的循环引用问题
  40. ReferenceLoopHandling = ReferenceLoopHandling.Ignore
  41. };
  42. config.Formatters.JsonFormatter.SerializerSettings = setting;
  43. config.Formatters.Remove(config.Formatters.XmlFormatter);
  44. config.Filters.Add(new HandlerErrorAttribute());
  45. //config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
  46. config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");
  47. //config.Routes.MapHttpRoute("DefaultApiGet", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
  48. //config.Routes.MapHttpRoute("DefaultApiPost", "Api/{controller}", new { action = "Post" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) });
  49. ConfigureSwagger(config);
  50. //添加路由路径
  51. config.MapHttpAttributeRoutes();
  52. app.UseCors(CorsOptions.AllowAll);
  53. //app.Use<LoggingMiddleware>();
  54. app.UseWebApi(config);
  55. }
  56. private static void ConfigureSwagger(HttpConfiguration config)
  57. {
  58. var thisAssembly = typeof(Startup).Assembly;
  59. config.EnableSwagger(c =>
  60. {
  61. c.SingleApiVersion("v1", "多模式融合定位平台Http接口");
  62. //设置接口描述xml路径地址
  63. var webApiXmlPath1 = $"{AppDomain.CurrentDomain.BaseDirectory}{Path.GetFileNameWithoutExtension(System.AppDomain.CurrentDomain.FriendlyName)}.xml";
  64. c.IncludeXmlComments(webApiXmlPath1);
  65. var webApiXmlPath2 = $"{AppDomain.CurrentDomain.BaseDirectory}XdCxRhDw.Dto.xml";
  66. c.IncludeXmlComments(webApiXmlPath2);
  67. c.UseFullTypeNameInSchemaIds();
  68. //加入控制器描述
  69. c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, webApiXmlPath1));
  70. })
  71. .EnableSwaggerUi(c =>
  72. {
  73. c.InjectJavaScript(thisAssembly, "XdCxRhDW.App.WebAPI.Swagger.js");
  74. c.DocumentTitle("");
  75. });
  76. }
  77. public class HandlerErrorAttribute : ExceptionFilterAttribute
  78. {
  79. /// <summary>
  80. /// 控制器方法中出现异常,会调用该方法捕获异常
  81. /// </summary>
  82. /// <param name="context">提供使用</param>
  83. public override void OnException(HttpActionExecutedContext context)
  84. {
  85. base.OnException(context);
  86. Serilog.Log.Error(context.Exception, context.Exception.Message);
  87. //LogFile.WriteError(context.Exception.Message);
  88. throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.OK)
  89. {
  90. Content = new StringContent(
  91. JsonConvert.SerializeObject(
  92. new
  93. {
  94. code = -1,
  95. data = "",
  96. msg = context.Exception.Message
  97. }), Encoding.UTF8, "text/json")
  98. });
  99. }
  100. };
  101. public class SwaggerControllerDescProvider : ISwaggerProvider
  102. {
  103. private readonly ISwaggerProvider _swaggerProvider;
  104. private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
  105. private readonly string _xml;
  106. /// <summary>
  107. ///
  108. /// </summary>
  109. /// <param name="swaggerProvider"></param>
  110. /// <param name="xml">xml文档路径</param>
  111. public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
  112. {
  113. _swaggerProvider = swaggerProvider;
  114. _xml = xml;
  115. }
  116. public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
  117. {
  118. var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
  119. SwaggerDocument srcDoc = null;
  120. //只读取一次
  121. if (!_cache.TryGetValue(cacheKey, out srcDoc))
  122. {
  123. srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
  124. srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } };
  125. _cache.TryAdd(cacheKey, srcDoc);
  126. }
  127. return srcDoc;
  128. }
  129. /// <summary>
  130. /// 从API文档中读取控制器描述
  131. /// </summary>
  132. /// <returns>所有控制器描述</returns>
  133. public ConcurrentDictionary<string, string> GetControllerDesc()
  134. {
  135. string xmlpath = _xml;
  136. ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
  137. if (File.Exists(xmlpath))
  138. {
  139. XmlDocument xmldoc = new XmlDocument();
  140. xmldoc.Load(xmlpath);
  141. string type = string.Empty, path = string.Empty, controllerName = string.Empty;
  142. string[] arrPath;
  143. int length = -1, cCount = "Controller".Length;
  144. XmlNode summaryNode = null;
  145. foreach (XmlNode node in xmldoc.SelectNodes("//member"))
  146. {
  147. type = node.Attributes["name"].Value;
  148. if (type.StartsWith("T:"))
  149. {
  150. //控制器
  151. arrPath = type.Split('.');
  152. length = arrPath.Length;
  153. controllerName = arrPath[length - 1];
  154. if (controllerName.EndsWith("Controller"))
  155. {
  156. //获取控制器注释
  157. summaryNode = node.SelectSingleNode("summary");
  158. string key = controllerName.Remove(controllerName.Length - cCount, cCount);
  159. if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
  160. {
  161. controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
  162. }
  163. }
  164. }
  165. }
  166. }
  167. return controllerDescDict;
  168. }
  169. }
  170. }
  171. }