.net framework4.0框架下winform 实现寄宿式web api

news2024/12/29 13:44:54

首先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());

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

echarts 实时刷新图表

2023.11.23今天我学习了如何对echarts图表进行实时刷新&#xff0c;如&#xff1a;一分钟刷新一次&#xff0c;或是五分钟刷新一次。 代码如下&#xff1a; <template><div ref"bar" style"width:200px;height:200px"/> </template>&l…

电商API接口|电商数据接入|拼多多平台根据商品ID查商品详情SKU和商品价格参数

随着科技的不断进步&#xff0c;API开发领域也逐渐呈现出蓬勃发展的势头。今天我将向大家介绍API接口&#xff0c;电商API接口具备独特的特点&#xff0c;使得数据获取变得更加高效便捷。 快速获取API数据——优化数据访问速度 传统的数据获取方式可能需要经过多个中介环节&…

【开源】基于JAVA的在线课程教学系统

项目编号&#xff1a; S 014 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S014&#xff0c;文末获取源码。} 项目编号&#xff1a;S014&#xff0c;文末获取源码。 目录 一、摘要1.1 系统介绍1.2 项目录屏 二、研究内容2.1 课程类型管理模块2.2 课程管理模块2…

office 365企业版安装教程

1.下载所需工具&#xff08;防火墙和防毒软件记得关闭&#xff09; 下载链接&#xff1a;所需文件 2.安装激活office 1.安装 office tool plus 2.已安装过office 先进行office的移除&#xff0c;再进行未安装office的步骤进行 3.未安装过office 1.设置部署 按照以下来进行安…

【MATLAB源码-第85期】基于farrow结构的滤波器仿真,截止频率等参数可调。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 Farrow结构是一种用于实现可变数字滤波器的方法&#xff0c;尤其适用于数字信号处理中的采样率转换和时变滤波。它通过多项式近似来实现对滤波器系数的平滑变化&#xff0c;使得滤波器具有可变的群延时或其他参数。 Farrow结…

详解——菱形继承及菱形虚拟继承

目录 一&#xff0c;菱形继承 1.1单继承 1.2多继承 1.3菱形继承 1.4菱形继承的问题 1.5虚拟继承解决数据冗余和二义性的原理 二.继承的总结和反思 一&#xff0c;菱形继承 C三大特性——继承-CSDN博客 1.1单继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继…

【HarmonyOS】 低代码平台组件拖拽使用技巧之登录组件

【关键字】 HarmonyOS、低代码平台、组件拖拽、登录组件、代码编辑器 1、写在前面 前面我们介绍了低代码中堆叠容器、滚动容器、网格布局、页签容器以及一些常用容器和组件的拖拽使用方法&#xff0c;本篇我们来介绍一个新的组件&#xff0c;这个组件是属于业务组件——登录组…

WPF实战项目十六(客户端):备忘录接口

1、新增IMemoService接口&#xff0c;继承IBaseService接口 public interface IMemoService : IBaseService<MemoDto>{} 2、新增MemoService类&#xff0c;继承BaseService和IMemoService接口 public class MemoService : BaseService<MemoDto>, IMemoService{pub…

毕业设计ASP.NET 1400动漫公司网站【程序源码+文档+调试运行】

摘要 本系统将实现一个动漫公司网站&#xff0c;包括前台用户模块和后台管理员模块。前台用户模块主要包括最新动漫、注册登录、公司简介、公司新闻、动漫中心、联系我们和会员中心等功能。后台管理员模块包括用户管理、公司简介管理、公司新闻管理、动漫类别管理、动漫管理、…

快速上手Banana Pi BPI-M4 Zero 全志科技H618开源硬件开发开发板

Linux[编辑] 准备[编辑] 1. Linux镜像支持SD卡或EMMC启动&#xff0c;并且会优先从SD卡启动。 2. 建议使用A1级卡&#xff0c;至少8GB。 3. 如果您想从 SD 卡启动&#xff0c;请确保可启动 EMMC 已格式化。 4. 如果您想从 EMMC 启动并使用 Sdcard 作为存储&#xff0c;请确…

阿里云服务器ECS产品知识及购买和使用常见问题及答案汇总

本文总结了阿里云用户在购买和使用阿里云服务器中的一些常见的问题&#xff0c;包括什么是云服务器ECS&#xff0c;特性与优势&#xff0c;应用场景&#xff0c;基本概念&#xff0c;使用限制等众多问题&#xff0c;让您全方位了解阿里云服务器&#xff0c;并根据自己的需求选择…

Modbus转Profinet网关:PLC与天信流量计通讯的经典案例

无论您是PLC或工业设备的制造商&#xff0c;还是工业自动化系统的维护人员&#xff0c;可能会遇到需要将不同协议的设备连接组合并通讯的情况&#xff0c;Modbus和Profinet是现代工业自动化中常见的两种通信协议&#xff0c;在工业控制领域中被广泛应用。 在这种情况绝大多数会…

Matlab通信仿真系列——滤波器及其分类

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、滤波器定义 二、滤波…

FastAPI通过SSE进行流式输出

服务端推送 在服务器推送技术中&#xff0c;服务器在消息可用后立即主动向客户端发送消息。其中&#xff0c;有两种类型的服务器推送&#xff1a;SSE和 WebSocket。 SSE&#xff08;Server-Send Events&#xff09; SSE 是一种在基于浏览器的 Web 应用程序中仅从服务器向客户…

解决Android端libc++_shared.so库冲突问题

前言 随着App功能增多&#xff0c;集成的so库也会增多&#xff0c;如果系统中多个so库都使用系统自动生成的libc_shared.so库&#xff0c;如果多个SDK都有该so包&#xff0c;就会出现报错&#xff1a; 解决办法 如果出现该问题&#xff0c;说明您的项目中有多个SDK共同依赖了C标…

《微信小程序开发从入门到实战》学习二十五

3.3 开发创建投票页面 3.3.13 使用页面路径参数 写了很多重复代码&#xff0c;现在想办法将多选和单选投票页面合二为一。 将单选页面改造作为单选多选共同页面。 修改index.js中的代码&#xff0c;将路径都跳转到第一个单选页面&#xff0c;带上单选或多选的标志&#xff…

【搜维尔科技】产品推荐:Virtuose 6D RV,大型工作空间触觉设备

Virtuose 6D RV为一款具有大工作空间并在所有6自由度上提供力反馈的触觉设备&#xff0c;设计专用于虚拟现实环境&#xff0c;特别适合于大型虚拟物体的处理。 Virtuose 6D RV是当今市场上唯一将高工作效率与高工作量相结合在一起的产品。6D RV特别适合于缩放与操纵等应用&…

CentOS 7 使用cJSON 库

什么是JSON JSON是一种轻量级的数据交换格式&#xff0c;可读性强、编写简单。键值对组合编写规则&#xff0c;键名使用双引号包裹&#xff0c;冒号&#xff1a;分隔符后面紧跟着数值&#xff0c;有两种常用的数据类型是对象和数组。 对象&#xff1a;使用花括号{}包裹起来的…

[Android]使用Retrofit进行网络请求

以下是使用 Retrofit 发送 POST 请求获取分页城市列表的 Kotlin 代码示例 1.在你的 build.gradle 文件中添加 Retrofit 和 Gson 的依赖 dependencies {......implementation("com.squareup.retrofit2:retrofit:2.9.0")implementation("com.squareup.retrofit2…

解锁电力安全密码:迅软DSE助您保护机密无忧

电力行业信息化水平不断提高&#xff0c;明显提升了电力企业的生产运营能力&#xff0c;然而随着越来越多重要信息存储在终端计算机中&#xff0c;电力面临的信息安全挑战也越来越多。 作为关键基础设施的基础&#xff0c;电力企业各部门产生的资料文档涵盖着大量机密信息&…