|
在本篇博客中,我将介绍如何在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"。在类中添加以下代码:- using Newtonsoft.Json.Linq;
- using System.Threading.Tasks;
- using System.Web.Http;
- namespace MockAPI.Controllers
- {
- /// <summary>
- /// 模拟接口
- /// </summary>
- [RoutePrefix("api")]
- public class 模拟接口Controller : BaseController
- {
- /// <summary>
- /// 同步信息
- /// </summary>
- /// <returns></returns>
- [Route("fs_syncPayinfo")]
- [HttpGet]
- public IHttpActionResult SyncPayInfo()
- {
- string json = @"{""code"":1,""message"":""同步成功""}";
- return Json(JObject.Parse(json));
- }
- }
复制代码 步骤4:配置Swagger 在解决方案资源管理器中,右键单击"Properties"文件夹,选择"添加" -> "新建文件"。命名为"Startup.cs"。在文件中添加以下代码:
其中包含了记录日志中间件等类,具体看下载的代码
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Net.Http;
- using System.Text;
- using System.Web.Http;
- using System.Web.Http.Filters;
- using System.Xml;
- using Microsoft.Owin;
- using Microsoft.Owin.Cors;
- using MockAPI.Common;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Serialization;
- using Owin;
- using Swashbuckle.Application;
- using Swashbuckle.Swagger;
- [assembly: OwinStartup(typeof(MockAPI.Startup))]
- namespace MockAPI
- {
- public class Startup
- {
- public void Configuration(IAppBuilder app)
- {
- HttpConfiguration config = new HttpConfiguration();
- JsonSerializerSettings setting = new JsonSerializerSettings()
- {
- //日期类型默认格式化处理
- DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
- DateFormatString = "yyyy-MM-dd HH:mm:ss",
- //驼峰样式
- ContractResolver = new CamelCasePropertyNamesContractResolver(),
- //空值处理
- //NullValueHandling = NullValueHandling.Ignore,
- //设置序列化的最大层数
- MaxDepth = 10,
- //解决json序列化时的循环引用问题
- ReferenceLoopHandling = ReferenceLoopHandling.Ignore
- };
- config.Formatters.JsonFormatter.SerializerSettings = setting;
- config.Formatters.Remove(config.Formatters.XmlFormatter);
- config.Filters.Add(new HandlerErrorAttribute());
- //config.Routes.MapHttpRoute(
- // name: "DefaultApi",
- // routeTemplate: "api/{controller}/{action}/{id}",
- // defaults: new
- // {
- // id = RouteParameter.Optional
- // }
- //);
- ConfigureSwagger(config);
- //添加路由路径
- config.MapHttpAttributeRoutes();
- app.UseCors(CorsOptions.AllowAll);
- app.Use<LoggingMiddleware>();
- app.UseWebApi(config);
- }
- private static void ConfigureSwagger(HttpConfiguration config)
- {
- var thisAssembly = typeof(Startup).Assembly;
- config.EnableSwagger(c =>
- {
- c.SingleApiVersion("v1", "MockAPI");
- //设置接口描述xml路径地址
- var webApiXmlPath = string.Format(string.Format("{0}/MockAPI.xml", AppDomain.CurrentDomain.BaseDirectory));
- c.IncludeXmlComments(webApiXmlPath);
- c.UseFullTypeNameInSchemaIds();
- //加入控制器描述
- c.CustomProvider((defaultProvider) => new SwaggerControllerDescProvider(defaultProvider, webApiXmlPath));
- })
- .EnableSwaggerUi(c =>
- {
- c.DocumentTitle("MockAPI");
- c.InjectJavaScript(thisAssembly, "MockAPI.Common.Swagger.js");
- });
- }
- public class HandlerErrorAttribute : ExceptionFilterAttribute
- {
- /// <summary>
- /// 控制器方法中出现异常,会调用该方法捕获异常
- /// </summary>
- /// <param name="context">提供使用</param>
- public override void OnException(HttpActionExecutedContext context)
- {
- base.OnException(context);
- LogFile.WriteError(context.Exception.Message);
- throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.OK)
- {
- Content = new StringContent(
- JsonConvert.SerializeObject(
- new
- {
- code = -1,
- data = "xxx",
- msg = context.Exception.Message
- }), Encoding.UTF8, "text/json")
- });
- }
- };
- 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步骤5:配置OwinSelfHost 启动等等 - private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- setMin();
- wsl = this.WindowState;
- this.Hide();//启动后直接最小化
- this.ResizeMode = ResizeMode.CanMinimize;
- this.txtDevice.Text = DeviceNo;
- this.txtDevice.IsReadOnly = true;
- var registry = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);//检索指定的子项
- if (registry != null)
- {
- object a = registry.GetValue(Path.GetFileName(System.Windows.Forms.Application.ExecutablePath));
- if (a != null) this.cboAuto.IsChecked = true;
- registry.Close();
- }
- this.cboAuto.Checked += BtnClickTurnOn;
- this.cboAuto.Unchecked += BtnClickTurnOff;
- StartOptions options = new StartOptions();
- options.Urls.Add("http://+:8033");
- // 启动 OWIN host
- _disposable = WebApp.Start<Startup>(options);
- }
复制代码 这里代码只有部分截图,具体下载代码查看 点击下载
点击API地址打开文档界面
至此,我们已成功创建了一个使用WPF、OwinSelfHost和Swagger的自托管Web API。你可以根据自己的需求进一步扩展和定制这个应用程序。
来源:https://www.cnblogs.com/xxxin/archive/2023/06/01/17449038.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|