翼度科技»论坛 编程开发 .net 查看内容

使用WPF、OwinSelfHost和Swagger创建自托管的Web API

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
在本篇博客中,我将介绍如何在WPF应用程序中使用OwinSelfHost和Swagger来创建自托管的Web API。我们将使用WPF作为我们的应用程序界面,OwinSelfHost来自托管我们的Web API,并使用Swagger来为我们的API生成文档。
首先,确保你的计算机上已安装了以下组件:

  • Visual Studio2017
  • .NET Framework(至少需要4.5版本)
接下来,按照以下步骤进行操作:
步骤1:创建新的WPF项目 在Visual Studio中创建一个新的WPF项目。命名它为"SwaggerBlog"。
步骤2:安装必要的NuGet包 在解决方案资源管理器中,右键单击项目名称,选择"管理NuGet程序包"。然后,按照以下步骤安装所需的包:

  • Microsoft.AspNet.WebApi.OwinSelfHost
  • Microsoft.Owin.Cors
  • Swashbuckle
  • .。。。。
步骤3:创建API控制器 在解决方案资源管理器中,右键单击"Controllers"文件夹,选择"添加" -> "类"。命名为"模拟接口Controller.cs"。在类中添加以下代码:
  1. using Newtonsoft.Json.Linq;
  2. using System.Threading.Tasks;
  3. using System.Web.Http;
  4. namespace MockAPI.Controllers
  5. {
  6.     /// <summary>
  7.     /// 模拟接口
  8.     /// </summary>
  9.     [RoutePrefix("api")]
  10.     public class 模拟接口Controller : BaseController
  11.     {
  12.         /// <summary>
  13.         /// 同步信息
  14.         /// </summary>
  15.         /// <returns></returns>
  16.         [Route("fs_syncPayinfo")]
  17.         [HttpGet]
  18.         public IHttpActionResult SyncPayInfo()
  19.         {
  20.             string json = @"{""code"":1,""message"":""同步成功""}";
  21.             return Json(JObject.Parse(json));
  22.         }
  23. }
复制代码
步骤4:配置Swagger 在解决方案资源管理器中,右键单击"Properties"文件夹,选择"添加" -> "新建文件"。命名为"Startup.cs"。在文件中添加以下代码:
其中包含了记录日志中间件等类,具体看下载的代码
  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.Xml;
  11. using Microsoft.Owin;
  12. using Microsoft.Owin.Cors;
  13. using MockAPI.Common;
  14. using Newtonsoft.Json;
  15. using Newtonsoft.Json.Serialization;
  16. using Owin;
  17. using Swashbuckle.Application;
  18. using Swashbuckle.Swagger;
  19. [assembly: OwinStartup(typeof(MockAPI.Startup))]
  20. namespace MockAPI
  21. {
  22.     public class Startup
  23.     {
  24.         public void Configuration(IAppBuilder app)
  25.         {
  26.             HttpConfiguration config = new HttpConfiguration();
  27.             JsonSerializerSettings setting = new JsonSerializerSettings()
  28.             {
  29.                 //日期类型默认格式化处理
  30.                 DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
  31.                 DateFormatString = "yyyy-MM-dd HH:mm:ss",
  32.                 //驼峰样式
  33.                 ContractResolver = new CamelCasePropertyNamesContractResolver(),
  34.                 //空值处理
  35.                 //NullValueHandling = NullValueHandling.Ignore,
  36.                 //设置序列化的最大层数
  37.                 MaxDepth = 10,
  38.                 //解决json序列化时的循环引用问题
  39.                 ReferenceLoopHandling = ReferenceLoopHandling.Ignore
  40.             };
  41.             config.Formatters.JsonFormatter.SerializerSettings = setting;
  42.             config.Formatters.Remove(config.Formatters.XmlFormatter);
  43.             config.Filters.Add(new HandlerErrorAttribute());
  44.             //config.Routes.MapHttpRoute(
  45.             //    name: "DefaultApi",
  46.             //    routeTemplate: "api/{controller}/{action}/{id}",
  47.             //    defaults: new
  48.             //    {
  49.             //        id = RouteParameter.Optional
  50.             //    }
  51.             //);
  52.             ConfigureSwagger(config);
  53.             //添加路由路径
  54.             config.MapHttpAttributeRoutes();
  55.             app.UseCors(CorsOptions.AllowAll);
  56.             app.Use<LoggingMiddleware>();
  57.             app.UseWebApi(config);
  58.         }
  59.         private static void ConfigureSwagger(HttpConfiguration config)
  60.         {
  61.             var thisAssembly = typeof(Startup).Assembly;
  62.             config.EnableSwagger(c =>
  63.              {
  64.                  c.SingleApiVersion("v1", "MockAPI");
  65.                     //设置接口描述xml路径地址
  66.                     var webApiXmlPath = string.Format(string.Format("{0}/MockAPI.xml", AppDomain.CurrentDomain.BaseDirectory));
  67.                  c.IncludeXmlComments(webApiXmlPath);
  68.                  c.UseFullTypeNameInSchemaIds();
  69.                     //加入控制器描述
  70.                     c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, webApiXmlPath));
  71.              })
  72.              .EnableSwaggerUi(c =>
  73.              {
  74.                  c.DocumentTitle("MockAPI");
  75.                  c.InjectJavaScript(thisAssembly, "MockAPI.Common.Swagger.js");
  76.              });
  77.         }
  78.         public class HandlerErrorAttribute : ExceptionFilterAttribute
  79.         {
  80.             /// <summary>
  81.             /// 控制器方法中出现异常,会调用该方法捕获异常
  82.             /// </summary>
  83.             /// <param name="context">提供使用</param>
  84.             public override void OnException(HttpActionExecutedContext context)
  85.             {
  86.                 base.OnException(context);
  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 = "xxx",
  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. }
复制代码
View Code步骤5:配置OwinSelfHost 启动等等 
  1.   private void Window_Loaded(object sender, RoutedEventArgs e)
  2.         {
  3.             setMin();
  4.             wsl = this.WindowState;
  5.             this.Hide();//启动后直接最小化
  6.             this.ResizeMode = ResizeMode.CanMinimize;
  7.             this.txtDevice.Text = DeviceNo;
  8.             this.txtDevice.IsReadOnly = true;
  9.             var registry = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);//检索指定的子项
  10.             if (registry != null)
  11.             {
  12.                 object a = registry.GetValue(Path.GetFileName(System.Windows.Forms.Application.ExecutablePath));
  13.                 if (a != null) this.cboAuto.IsChecked = true;
  14.                 registry.Close();
  15.             }
  16.             this.cboAuto.Checked += BtnClickTurnOn;
  17.             this.cboAuto.Unchecked += BtnClickTurnOff;
  18.             StartOptions options = new StartOptions();
  19.             options.Urls.Add("http://+:8033");
  20.             // 启动 OWIN host
  21.             _disposable = WebApp.Start<Startup>(options);
  22.         }
复制代码
这里代码只有部分截图,具体下载代码查看   点击下载

 点击API地址打开文档界面

 
 
至此,我们已成功创建了一个使用WPF、OwinSelfHost和Swagger的自托管Web API。你可以根据自己的需求进一步扩展和定制这个应用程序。

来源:https://www.cnblogs.com/xxxin/archive/2023/06/01/17449038.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具