C# WinForm中提供webapi服务

        云川给我提了一个需求,要我开发一个API服务程序,他来调用,程序再去明道云取数,计算出一个结果返回。网上找到了一篇文章:C# 在Windform程序中搭建Webapi - 小码哥-风云 - 博客园,可以使用微软提供的Microsoft.Owin包来搭建。转载一下,万一原文丢失了呢。

1. 在NuGet引用owin

Microsoft.AspNet.WebApi.Owin
Microsoft.AspNet.WebApi.OwinSelfHost
Microsoft.Owin.StaticFiles

2. 添加服务启动配置类 Startup

using WebapiTest.App_Start;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;namespace WebapiTest
{public class Startup{public void Configuration(IAppBuilder appBuilder){// 创建 Web API 的配置var config = new HttpConfiguration();// 启用标记路由config.MapHttpAttributeRoutes();// 默认的 Web API 路由config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });FormatterConfig.Configure(config);SwaggerConfig.Register(config);FilterConfig.Register(config);var physicalFileSystem = new PhysicalFileSystem(@".\Web"); //静态网站根目录var options = new FileServerOptions{EnableDefaultFiles = true,FileSystem = physicalFileSystem};options.StaticFileOptions.FileSystem = physicalFileSystem;options.StaticFileOptions.ServeUnknownFileTypes = true;options.StaticFileOptions.DefaultContentType = "text/plain";options.DefaultFilesOptions.DefaultFileNames = new[] { "Index.html" }; //默认页面(填写与静态网站根目录的相对路径)appBuilder.UseFileServer(options);// 将路由配置附加到 appBuilderappBuilder.UseWebApi(config);}}
}

3. 添加 Controllers 目录,创建 QueryController Web服务类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;namespace WebapiTest.Controllers
{public class QueryController : ApiController{//// GET api//[HttpGet]//public IHttpActionResult Json(string id)//{//    return Json($"hello123:{id}");//}// GET apipublic string Get(string id){return "hello:" + id;}// POST apipublic string Post([FromBody] string value){return value;}// PUT apipublic void Put(int id, string value){}// DELETE apipublic void Delete(int id){}}}

4. 在程序中调用如下代码启动Web服务

// 打开Web服务
var server = WebApp.Start<Startup>(url: "http://localhost:9099/");

// 停止Web服务
server.Dispose();
server = null;

5. 在生成的文件目录,创建Web文件夹,放入静态Web资源(index.html)

6. 访问Web资源
浏览器访问静态资源 http://localhost:9099/ 
浏览器访问WebApi  http://localhost:9099/api/Query/123

OK。

那我们的程序界面如下:

从这个winform程序再去通过Flurl包去访问其它服务器的api,比如明道云。安装包如下:

全部代码:

Startup.cs

using Microsoft.Owin.FileSystems;
using Microsoft.Owin.StaticFiles;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;namespace mdy2
{internal class Startup{public void Configuration(IAppBuilder appBuilder){// 创建 Web API 的配置var config = new HttpConfiguration();// 启用标记路由config.MapHttpAttributeRoutes();// 默认的 Web API 路由config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });/*var physicalFileSystem = new PhysicalFileSystem(@".\Web"); //静态网站根目录var options = new FileServerOptions{EnableDefaultFiles = true,FileSystem = physicalFileSystem};options.StaticFileOptions.FileSystem = physicalFileSystem;options.StaticFileOptions.ServeUnknownFileTypes = true;options.StaticFileOptions.DefaultContentType = "text/plain";options.DefaultFilesOptions.DefaultFileNames = new[] { "Index.html" }; //默认页面(填写与静态网站根目录的相对路径)appBuilder.UseFileServer(options);*/// 将路由配置附加到 appBuilderappBuilder.UseWebApi(config);}}
}

QueryController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using static System.Net.Mime.MediaTypeNames;namespace mdy2.Controllers
{public class QueryController : ApiController{//// GET api//[HttpGet]//public IHttpActionResult Json(string id)//{//    return Json($"hello123:{id}");//}// GET apipublic string Get(string id){      Task<string> task = Form1.get_mdy_fa(id);     return task.Result;}/*// POST apipublic string Post([FromBody] string value){return value;}// PUT apipublic void Put(int id, string value){}// DELETE apipublic void Delete(int id){}*/}
}

Form1.cs

using Flurl.Http;
using Microsoft.Owin.Hosting;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;namespace mdy2
{public partial class Form1 : Form{public static Form1 form1; //静态函数中使用UI控件public static List<zgd> gdlist = new List<zgd>();           //工单表public static List<cl> cllist = new List<cl>();             //处理方式public static List<clren> clrenlist = new List<clren>();    //处理人public Form1(){InitializeComponent();form1 = this; //静态函数中使用UI控件            Control.CheckForIllegalCrossThreadCalls = false; //静态函数中使用UI控件var server = WebApp.Start<Startup>(url: "http://localhost:9099/"); // 打开Web服务cllist.Add(new cl { way = "人工回复", score = 0.1 });cllist.Add(new cl { way = "处理后回复", score = 0.5 });cllist.Add(new cl { way = "二次沟通", score = 1 });clrenlist.Add(new clren { name = "刘欣", upper_score = 20 });clrenlist.Add(new clren { name = "一洋", upper_score = 30 });clrenlist.Add(new clren { name = "云川", upper_score = 30 });Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + "=======服务webapi地址=============" + "\r\n";Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + "http://localhost:9099/api/Query/xxxxxx" + "\r\n\r\n";}// fa方案工时子表public static async Task<string> get_mdy_fa(string xxx){//  faList.Clear();var url = "https://innoshare.seres.cn/api/v2/open/worksheet/getFilterRows";var objData = new{appKey = "52c4be3e",sign = "MTY4ZmU0MGE3YWQ3NjAzMjVlMGJkMjczNzBNg==",worksheetId = "gdtz",pageSize = "1000"};string txt = await url.PostJsonAsync(objData).ReceiveString();   var obj = JsonConvert.DeserializeObject<dynamic>(txt); // 从JSON中拉出来动态对象/////////处理数据////////////////////////gdlist.Clear();foreach (var item in obj.data.rows) //每一行数据{if (item.gdzt == "处理中")  //只处理“处理中”的工单{                zgd one = new zgd();one.gongdanhao = item.gongdanhao;one.clfs = item.clfs;   var line = JsonConvert.DeserializeObject<dynamic>((string)item.chuliren); //处理人if (line != null){foreach (var l in line){zchengyuan tmp = new zchengyuan();tmp.accountId = l.accountId;tmp.fullname = l.fullname;one.chuliren.Add(tmp);}               }gdlist.Add(one);}}//把分数匹配上去foreach (var item in gdlist){item.score = cllist.Where(p => p.way.Equals(item.clfs)).FirstOrDefault().score;}Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + "=======读取明道云数据=========" + "\r\n";foreach (var item in gdlist){Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + item.gongdanhao + "," + item.clfs + "," + item.chuliren[0].fullname +"," +item.score + "\r\n";}Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + "=======计算处理人积分=========" + "\r\n";//按人配匹积分foreach (var item in clrenlist){item.do_score = gdlist.Where(p => p.chuliren[0].fullname.Equals(item.name)).Select(p => p.score).Sum();Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + item.name+ "," + item.do_score + "\r\n";}Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + "=======输出结果=============" + "\r\n";Form1.form1.textBox1.Text = Form1.form1.textBox1.Text + xxx +"," + clrenlist.OrderBy(p => p.do_score).FirstOrDefault().name;////////////////////////////////return xxx + "," + clrenlist.OrderBy(p => p.do_score).FirstOrDefault().name;}}//===============工时子表========================public partial class zgd{public string gongdanhao { get; set; }  //工单号        public string clfs { get; set; }  //处理方式public List<zchengyuan> chuliren { get; set; }    //处理人public double score { get; set; }    //分数public zgd(){chuliren = new List<zchengyuan>();}}public partial class zchengyuan  //成员 子项{public string accountId { get; set; }  //idpublic string fullname { get; set; } //fullname}public  class cl  //处理方式{public string way { get; set; }  //方式public double score { get; set; }    //分数}public class clren  //处理人{public string name { get; set; }  //姓名public double do_score { get; set; }    //积分public double upper_score { get; set; }    //上限}}

        注意最后这个函数返回,需要给IHttpActionResult,明道云接收放只能接收标准的json。用string返回给高级点的系统,它们不能识别文本报文,只能识别很标准的json。

public IHttpActionResult Get(string id)

        // GET apipublic IHttpActionResult Get(string id){      Task<string> task = Form1.get_mdy_fa(id);var data = new Person { WON = id, NAME = task.Result };return Json(data);}

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

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

相关文章

Linux中使用docker部署solr

1. 运行一次&#xff0c;然后拉取镜像 [rootinstance-yo4hab98 ~]# docker run -d -p 8983:8983 --name solr-8.11.3 -t solr:8.11.3 ps 镜像相关指令 # 查看镜像 docker images# 删除镜像 指定名称和版本删除 docker rmi nginx:latest # 删除镜像 指定id删除 docker rm…

代谢组学分析指南

摘要代谢组学是个新兴领域&#xff0c;系统性地定量众多代谢物。关键目的是识别与每种生物表型相对应的代谢物&#xff0c;并进一步分析其中涉及的机制。尽管代谢组学对于理解相关的生物学现象至关重要&#xff0c;但在全面描述过程的能力上存在局限性。推荐采用综合分析策略&a…

vue2使用el-form动态参数展示并非空校验

需求&#xff1a;需要根据类型type动态显示某些参数&#xff0c;并且后端需要的参数也不同&#xff0c;比如type为1&#xff1a;后端要aa和bb参数&#xff0c;type为2&#xff1a;后端要cc和dd参数&#xff0c;前端显示的字段名也不一样&#xff0c;但是样式是不变的。1.效果2.…

(附源码)基于Vue的教师档案管理系统的设计与实现

摘 要 随着信息技术的不断发展&#xff0c;学校管理工作正逐渐从纸质化向数字化转型。教师档案管理作为学校管理的重要环节&#xff0c;其信息化和高效化对于提升学校管理水平具有重要意义。本文设计并实现了一个基于Vue框架的教师档案管理系统&#xff0c;旨在通过前端技术的…

运算电源抑制比(PSRR)测量及设计注意事项

1、简介如果运放的供电电源发生变化&#xff0c;输出不应发生变化&#xff0c;但实际运放随着供电电源的波动&#xff0c;运放输出也将会发生波动。折合到输出端&#xff0c;PSRR定义 Xv(电源电压波动) / Yv&#xff08;输出电压波动&#xff09;&#xff0c;该量为无量纲&…

YOLOv8-SMOT:一种高效鲁棒的实时小目标跟踪框架:基于切片辅助训练与自适应关联

https://arxiv.org/pdf/2507.12087 摘要 从无人机&#xff08;UAV&#xff09;视角对小型敏捷多目标&#xff08;SMOT&#xff09;——例如鸟类——进行跟踪是一项极具挑战性的计算机视觉任务。该任务的难点主要源于三个方面&#xff1a;目标外观特征极度稀缺、相机与目标自身复…

深入理解QLabel:Qt中的文本与图像显示控件

在Qt框架中&#xff0c;QLabel是一个功能强大且灵活的控件&#xff0c;主要用于在用户界面上显示文本或图像。无论是在简单的信息提示&#xff0c;还是在复杂的图形界面中&#xff0c;QLabel都能发挥重要作用。本文将详细介绍QLabel的主要功能、使用方法以及一些高级技巧&#…

hintcon2025 Verilog OJ

#web题目要求我们执行 /readflag give me the flagif ((strcmp(argv[1], "give") | strcmp(argv[2], "me") | strcmp(argv[3], "the") | strcmp(argv[4], "flag")) ! 0) {puts("You are not worthy");return 1; }首先&#…

佳易王钟表维修养护管理系统:开启钟表维修高效管理新篇章​就#软件操作教程

前言&#xff1a; &#xff08;一&#xff09;试用版获取方式 资源下载路径&#xff1a;进入博主头像主页第一篇文章末尾&#xff0c;点击卡片按钮&#xff1b;或访问左上角博客主页&#xff0c;通过右侧按钮获取详细资料。 说明&#xff1a;下载文件为压缩包&#xff0c;使用…

mysql组提交

Binlog Group Commit1. 背景&#xff1a;没有组提交时的问题&#xff08;MySQL 5.7及更早版本的痛点&#xff09;在早期版本的MySQL中&#xff0c;为了保证二进制日志&#xff08;Binlog&#xff09; 和 存储引擎&#xff08;如InnoDB&#xff09; 之间的一致性&#xff08;即一…

C#简单组态软件开发

C#简单组态软件开发 组态软件(SCADA/HMI)是工业自动化领域的核心软件&#xff0c;用于监控和控制工业过程。 系统架构设计 一个基本的组态软件应包含以下模块&#xff1a; 图形界面编辑器设备通信模块实时数据库运行时引擎报警系统历史数据存储 开发环境搭建开发工具&#xff1…

Maya绑定:人物绑定详细案例(创建骨骼、镜像骨骼、IK创建、IK打组、IK控制器、FK控制器、烘焙动画、导出)

目录 壹 创建骨骼 1 准备一个模型 2 创建骨骼 腿部骨骼 躯体骨骼 嘴巴骨骼 披风骨骼 手臂骨骼 手指骨骼 3 给骨骼命名 4 调整关节的坐标轴 测试 5 镜像骨骼 贰 控制器 一 脚部控制 IK 1 脚部IK创建 腿部IK 脚掌IK 2 脚部IK打组 动作1&#xff1a;脚掌着地&…

手写MyBatis第46弹:多插件责任链模式的实现原理与执行顺序奥秘--MyBatis插件架构深度解析

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e;&#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论&#x1f525;&#x1f525;&am…

宜春城区光纤铺设及接口实地调研

一、研究方向与近期关注 因为课题研究的原因&#xff0c;最近对城市骨干网非常感兴趣。前期我讨论了5G&#xff0c;WiFi及自组网等无线通信网络情况&#xff0c;感兴趣的朋友可以移步我的博客阅读&#xff1a; 5G无线通信网络场景&#xff08;日常、工业&#xff09;及拓扑结…

Tomcat 企业级运维实战系列(六):综合项目实战:Java 前后端分离架构部署

Tomcat 企业级运维实战系列&#xff08;六&#xff09;&#xff1a;综合项目实战&#xff1a;Java 前后端分离架构部署一&#xff1a;概述二&#xff1a;部署1&#xff09;环境准备2&#xff09;部署数据库3&#xff09;部署后端4&#xff09;部署前端总结&#x1f680; Tomcat…

《Unity Shader入门精要》学习笔记四(高级纹理)

1、立方体纹理解释&#xff1a;站在一个完全透明的玻璃盒子中心&#xff0c;就可以看到6个面。把这个玻璃盒子的6个面都贴上一张照片。这6张照片合起来&#xff0c;就记录了周围360度的环境&#xff0c;比如蓝天、地面、建筑、树木等。在2D纹理中&#xff0c;使用坐标来找颜色&…

局域网中使用Nginx部署https前端和后端

目录 一.前端部署https 二.后端部署https 一.前端部署https 1.前端正常创建项目即可,打包后,文件夹的格式是dist 2.下载认证的证书 也可以使用其他软件,这里推荐使用mkcert,下载地址如下: Releases FiloSottile/mkcert GitHub 3.输入 mkcert -install

K8s卷机制:数据持久化与共享

在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c;卷&#xff08;Volume&#xff09; 是用于解决容器内数据持久化、容器间数据共享以及与外部存储交互的核心机制。它本质上是一个可供 Pod 中容器访问的存储目录&#xff0c;生命周期独立于容器&#xff08;容器重启或销…

线性回归原理推导与应用(十一):多重共线性

多重共线性的定义与影响 多重共线性&#xff08;Multicollinearity&#xff09;是指线性回归模型中的解释变量之间由于存在精确相关关系或高度相关关系而使模型估计失真或难以估计准确。 根据定义和影响程度&#xff0c;可以将多重共线性分为极端共线性和一般共线性。极端共线…

day082-初识ElasticStack

文章目录0. 老男孩思想-人性十大需求1. ElasticStack介绍1.1 ELK&#xff08;**Elastic Stack**&#xff09;1.2 logstash和filebeat的区别2. ElasticSearch单点部署2.1 下载ElasticSearch软件包2.2 安装软件并修改配置文件2.3 启动并测试服务3. ElasticSearch集群部署3.1 安装…