基于.net framework4.0框架下winform项目实现寄宿式web api

首先Nuget中下载包:Microsoft.AspNet.WebApi.SelfHost,如下:

注意版本哦,最高版本只能4.0.30506能用。

1.配置路由

public static class WebApiConfig{public static void Register(this HttpSelfHostConfiguration config){// 配置JSON序列化设置config.Formatters.Clear();config.Formatters.Add(new JsonMediaTypeFormatter());config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();// 配置路由//config.MapHttpAttributeRoutes();config.Routes.Clear();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}}

路由器不要搞错了,其实和老版本asp.net 差不多。

2.创建一个控制器

public class ValuesController : ApiController{[HttpGet]public string HelloWorld(){return "Hello World!";}[HttpGet]public ModelTest Test(){var model = new ModelTest();model.Id = Guid.NewGuid().ToString();model.Name = "Test";return model;}[HttpGet]public List<ModelTest> Test2(){List<ModelTest> modelTests = new List<ModelTest>();for (int i = 0; i < 3; i++){var model = new ModelTest();model.Id = Guid.NewGuid().ToString();model.Name = "Test";modelTests.Add(model);}return modelTests;}}

 创建一个WebServer,以来加载实现单例

public class WebServer{private static Lazy<WebServer> _lazy = new Lazy<WebServer>(() => new WebServer());private ManualResetEvent _webEvent;private WebServer(){}public static WebServer Instance => _lazy.Value;public string BaseAddress { get;set; }public Action<WebServer> StartSuccessfulCallback { get; set; }public Action<WebServer> RunEndCallback { get; set; }public Action<WebServer, AggregateException> StartExceptionCallback { get;set; }public void StartWebServer(){if (string.IsNullOrEmpty(BaseAddress)) return;_webEvent=new ManualResetEvent(false);Task.Factory.StartNew(() =>{HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(BaseAddress);config.Register();using (HttpSelfHostServer server = new HttpSelfHostServer(config)){try{server.OpenAsync().Wait();if (StartSuccessfulCallback != null)StartSuccessfulCallback(this);_webEvent.WaitOne();if (RunEndCallback != null)RunEndCallback(this);}catch (AggregateException ex){_webEvent.Set();_webEvent.Close();_webEvent = null;if (StartExceptionCallback != null)StartExceptionCallback(this,ex);}finally{server.CloseAsync().Wait();server.Dispose();}}});}public void StopWebServer(){if (_webEvent == null) return;_webEvent.Set();_webEvent.Close();}}

public class WebApiFactory{static string baseAddress = "http://localhost:9000/";static WebApiFactory(){Server = WebServer.Instance;Server.BaseAddress = baseAddress;}public static WebServer Server { get;private set; }}

 使用

public partial class Form1 : Form{public Form1(){InitializeComponent();WebApiFactory.Server.StartSuccessfulCallback = (t) =>{label1.Text = "Web API hosted on " + t.BaseAddress;};WebApiFactory.Server.RunEndCallback = (t) =>{label1.Text = "Web API End on " + t.BaseAddress;};WebApiFactory.Server.StartExceptionCallback = (t,ex) =>{MessageBox.Show(string.Join(";", ex.InnerExceptions.Select(x => x.Message)));};}private void button1_Click(object sender, EventArgs e){WebApiFactory.Server.StartWebServer();}private void button2_Click(object sender, EventArgs e){WebApiFactory.Server.StopWebServer();}private void Form1_FormClosing(object sender, FormClosingEventArgs e){WebApiFactory.Server.StopWebServer();}}

注:启动时必须以管理员身份启动程序

 我们挂的是http://localhost:9000/,接下来我们去请求:http://localhost:9000/api/Values/Test2

扩展:简单添加权限验证,不通过路由

public class BasicAuthorizationHandler : DelegatingHandler{protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){if (request.Method == HttpMethod.Options){var optRes =  base.SendAsync(request, cancellationToken);return optRes;}if (!ValidateRequest(request)){var response = new HttpResponseMessage(HttpStatusCode.Forbidden);var content = new Result{success = false,errs = new[] { "服务端拒绝访问:你没有权限" }};response.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");var tsc = new TaskCompletionSource<HttpResponseMessage>();tsc.SetResult(response); return tsc.Task;}var res =  base.SendAsync(request, cancellationToken);return res;}/// <summary>/// 验证信息解密并对比/// </summary>/// <param name="message"></param>/// <returns></returns>private bool ValidateRequest(HttpRequestMessage message){var authorization = message.Headers.Authorization;//如果此header为空或不是basic方式则返回未授权if (authorization != null && authorization.Scheme == "Basic" && authorization.Parameter != null){string Parameter = authorization.Parameter;// 按理说发送过来的做了加密,这里需要解密return Parameter == "111";// 身份验证码}else{return false;}}}/// <summary>/// 构建用于返回错误信息的对象/// </summary>public class Result{public bool success { get; set; }public string[] errs { get; set; }}

然后在WebApiConfig中注册

// 注册身份验证
config.MessageHandlers.Add(new BasicAuthorizationHandler());

根据自己需求做扩展吧,这里由于时间问题简单做身份验证(全局)

根据控制器或方法添加身份验证(非全局):

public class AuthorizationAttribute : AuthorizationFilterAttribute{public override void OnAuthorization(HttpActionContext actionContext){// 如果验证失败,返回未授权的响应if (!IsUserAuthorized(actionContext)){// 如果身份验证失败,返回未授权的响应var content = new Result{success = false,errs = new[] { "服务端拒绝访问:你没有权限" }};actionContext.Response= actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized");actionContext.Response.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");}}private bool IsUserAuthorized(HttpActionContext actionContext){var authorizationHeader = actionContext.Request.Headers.Authorization;if (authorizationHeader != null && authorizationHeader.Scheme == "Bearer" && authorizationHeader.Parameter != null){// 根据实际需求,进行适当的身份验证逻辑// 比较 authorizationHeader.Parameter 和预期的授权参数值return authorizationHeader.Parameter == "111";}return false;}}
public static class WebApiConfig{public static void Register(this HttpSelfHostConfiguration config){// 注册身份验证(全局)//config.MessageHandlers.Add(new BasicAuthorizationHandler());config.Filters.Add(new AuthorizationAttribute());// 配置JSON序列化设置config.RegisterJsonFormatter();// 配置路由config.RegisterRoutes();}private static void RegisterJsonFormatter(this HttpSelfHostConfiguration config){config.Formatters.Clear();config.Formatters.Add(new JsonMediaTypeFormatter());config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();}private static void RegisterRoutes(this HttpSelfHostConfiguration config){//config.MapHttpAttributeRoutes();config.Routes.Clear();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}}

然后在控制器中:

 public class ValuesController : ApiController{[HttpGet]public string HelloWorld(){return "Hello World!";}[HttpGet]public ModelTest Test(){var model = new ModelTest();model.Id = Guid.NewGuid().ToString();model.Name = "Test";return model;}[Authorization][HttpGet]public List<ModelTest> Test2(){List<ModelTest> modelTests = new List<ModelTest>();for (int i = 0; i < 3; i++){var model = new ModelTest();model.Id = Guid.NewGuid().ToString();model.Name = "Test";modelTests.Add(model);}return modelTests;}}

全局异常处理:

 public class GlobalExceptionFilter : IExceptionFilter{public bool AllowMultiple => false;public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken){// 在这里实现自定义的异常处理逻辑// 根据实际需求,处理异常并生成适当的响应// 示例:将异常信息记录到日志中LogException(actionExecutedContext.Exception);// 示例:返回带有错误信息的响应var content = new Result{success = false,errs = new[] { "发生了一个错误" }};actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Internal Server Error");actionExecutedContext.Response.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");var tcs = new TaskCompletionSource<object>();tcs.SetResult(null);return tcs.Task;}private void LogException(Exception exception){// 在这里编写将异常信息记录到日志的逻辑}}
public static class WebApiConfig{public static void Register(this HttpSelfHostConfiguration config){// 注册身份验证(全局)//config.MessageHandlers.Add(new BasicAuthorizationHandler());config.Filters.Add(new AuthorizationAttribute());// 注册全局异常过滤器config.Filters.Add(new GlobalExceptionFilter());// 配置JSON序列化设置config.RegisterJsonFormatter();// 配置路由config.RegisterRoutes();}private static void RegisterJsonFormatter(this HttpSelfHostConfiguration config){config.Formatters.Clear();config.Formatters.Add(new JsonMediaTypeFormatter());config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();}private static void RegisterRoutes(this HttpSelfHostConfiguration config){//config.MapHttpAttributeRoutes();config.Routes.Clear();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}}

写一个测试接口:

        [HttpGet]public int Test3(){int a = 3;int b = 0;return a / b;}

我们知道有5个Filter,这里只用到了其中的两个,其它自定义实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/214059.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信原生小程序构建表格模板控件

导语 在原生微信小程序开发中&#xff0c;有时候会遇到需要通过表格来呈现一定的数据&#xff0c;尽管在移动端&#xff0c;使用表格来呈现数据&#xff0c;并不是常见的&#xff0c;但是也保不齐会遇到这样的需求&#xff0c;然而在原生微信小程序中&#xff0c;也 并没有提供…

展现天津援疆工作成果 “团结村里看振兴”媒体采风团走进和田

央广网天津11月19日消息(记者周思杨)11月18日&#xff0c;由媒体记者、书法和摄影家、旅行社企业代表等40余人组成的“团结村里看振兴”媒体采风团走进新疆和田。在接下来的一周时间里&#xff0c;采风团将走访天津援疆和田地区策勒县、于田县、民丰县乡村振兴示范村&#xff0…

精通Nginx(18)-FastCGI/SCGI/uWSGI支持

最初用浏览器浏览的网页只能是静态html页面。随着社会发展,动态获取数据、操作数据需要变得日益强烈,CGI应运而生。CGI(Common Gateway Interface)公共网关接口,是外部扩展应用程序与静态Web服务器交互的一个标准接口。它可以使外部程序处理浏览器送来的表单数据并对此作出…

概要设计文档案例分享

1引言 1.1编写目的 1.2项目背景 1.3参考资料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4运行环境设计 2.5设计目标 3系统功能模块设计 3.1个人办公 4性能设计 4.1响应时间 4.2并发用户数 5接口设计 5.1接口设计原则 5.2接口实现方式 6运行设计 6.1运行模块…

UNETR:用于三维医学图像分割的Transformer

论文链接&#xff1a;https://arxiv.org/abs/2103.10504 代码链接&#xff1a; https://monai.io/research/unetr 机构&#xff1a;Vanderbilt University, NVIDIA 最近琢磨不出来怎么把3d体数据和文本在cnn中融合&#xff0c;因为确实存在在2d里面用的transformer用在3d里面…

快手ConnectionError

因为运行的程序被中断导致 top然后查看站用处内存高的accelerate kill进程号 9回车

风口下的危与机:如何抓住生成式AI黄金发展期?

回顾AI的发展历程&#xff0c;我们见证过几次重大突破&#xff0c;比如2012年ImageNet大赛的图像识别&#xff0c;2016年AlphaGo与李世石的围棋对决&#xff0c;这些进展都为AI的普及应用铺设了道路。而ChatGPT的出现&#xff0c;真正让AI作为一个通用的产品&#xff0c;走入大…

深入学习pytorch笔记

两个重要的函数 dir()&#xff1a; 一个内置函数&#xff0c;用于列出对象的所有属性和方法 help()&#xff1a;一个内置函数&#xff0c;用于获取关于Python对象、模块、函数、类等的详细信息 Dateset类 Dataset&#xff1a;pytorch中的一个类&#xff0c;开发者在训练和…

基于springboot实现大学生就业服务平台系统项目【项目源码】计算机毕业设计

基于springboot实现大学生就业服务平台系统演示 Java技术 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著…

产品经理面试必看!To B和To C产品的隐秘差异,你了解多少?

大家好&#xff0c;我是小米&#xff0c;一位对技术充满热情的产品经理。最近在和小伙伴们交流中发现一个热门话题&#xff1a;To B&#xff08;面向企业&#xff09;和To C&#xff08;面向消费者&#xff09;的产品经理究竟有何异同&#xff1f;这可是我们产品经理面试中的经…

【SpringCloud】微服务的扩展性及其与 SOA 的区别

一、微服务的扩展性 由上一篇文章&#xff08;没看过的可点击传送阅读&#xff09;可知&#xff0c; 微服务具有极强的可扩展性&#xff0c;这些扩展性包含以下几个方面&#xff1a; 性能可扩展&#xff1a;性能无法完全实现线性扩展&#xff0c;但要尽量使用具有并发性和异步…

视频剪辑新招:批量随机分割,分享精彩瞬间

随着社交媒体的普及&#xff0c;短视频已经成为分享生活、交流信息的重要方式。为制作出吸引的短视频&#xff0c;许多创作者都投入了大量的时间和精力进行剪辑。然而&#xff0c;对于一些没有剪辑经验的新手来说&#xff0c;这个过程可能会非常繁琐。现在一起来看云炫AI智剪批…