winform宿主webapi

本文详细介绍如何在Winform应用中集成WebAPI,包括配置、控制器编写及与UI交互的具体实现,通过实例演示了跨平台数据请求与响应的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引用的Dll

添加配置文件packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net461" />
  <package id="Microsoft.AspNet.WebApi.SelfHost" version="5.2.6" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net461" />
</packages>

新建Controller文件夹里面的ValuesConntroller.cs类

 [RoutePrefix("api/values")]
    public class ValuesController : ApiController
    {
        [HttpGet]
        [Route("st")]
        public string GetServerTim(string id)
        {
            try
            {
                string result = Program.FormCheck.GetJsonById(id);

                return result;
            }
            catch
            {
                return "failed :"+ id;
            }
        }
        protected HttpRequestBase GetRequest()
        {
            HttpContextBase context = (HttpContextBase)Request.Properties["MS_RequestContext"];//获取传统context

            HttpRequestBase request = context.Request;//定义传统request对象

            return request;
        }
        private string GetClientIp(HttpRequestMessage request = null)
        {
            request = request ?? Request;

            if (request.Properties.ContainsKey("MS_HttpContext"))
            {
                return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
            }
            else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
            {
                RemoteEndpointMessageProperty prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
                return string.Format("Address:{0}, Port: {1}", prop.Address, prop.Port.ToString());
            }
            else if (HttpContext.Current != null)
            {
                return HttpContext.Current.Request.UserHostAddress;
            }
            else
            {
                return null;
            }
        }
    }

Program类中这样写

 public static class Program
    {
        public static CheckInterface FormCheck = null;
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            FormCheck = new CheckInterface();
            Application.Run(FormCheck);
        }
    }

Form中这样写

  HttpSelfHostConfiguration config = null;
        HttpSelfHostServer server = null;
      
        public CheckInterface()
        {
            InitializeComponent();
            renderDgv_Interface.AllowUserToAddRows = false;
        }

        private void CheckInterface_Load(object sender, EventArgs e)
        {
            RefreshWebApi();
        }
        private void RefreshWebApi()
        {
            config = new HttpSelfHostConfiguration(Url);// "http://192.168.0.163:8085");
            config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
            server = new HttpSelfHostServer(config);
            server.OpenAsync().Wait();
        }

启动之后浏览器访问http://192.168.0.163:8085/api/values?id=001即可看到weiapi接口已经成功在Winform上运行。

如果想要访问Webapi执行方法与WinformUI界面交互,用委托另外还要判断几个属性

 

  delegate void DAddRdgvData(List<JsonData> DataSourse);

        private void AddRdgvData(List<JsonData> DataSourse)
        {
            if (renderDgv_Interface.InvokeRequired)
            {
                while (!this.renderDgv_Interface.IsHandleCreated)
                {
                    if (this.renderDgv_Interface.Disposing || this.renderDgv_Interface.IsDisposed)
                        return;
                }
                DAddRdgvData d = new DAddRdgvData(AddRdgvData);
                this.renderDgv_Interface.Invoke(d, new object[] { DataSourse });
            }
            else
            {

                for (int i = 0; i < DataSourse.Count; i++)
                {
                    if (ListId.Contains(DataSourse[i].Id))
                    {
                        for (int j = 0; j < renderDgv_Interface.RowCount; j++)
                        {
                            if (renderDgv_Interface.Rows[j].Cells["rdgv_Interface_id"].Value != null)
                            {

                                if (DataSourse[i].Id.Equals(renderDgv_Interface.Rows[j].Cells["rdgv_Interface_id"].Value.ToString()))
                                {
                                    renderDgv_Interface.Rows[j].Cells["rdgv_Name"].Value = DataSourse[i].Name;
                                    renderDgv_Interface.Rows[j].Cells["rdgv_Time"].Value = DataSourse[i].Time;
                                    renderDgv_Interface.Rows[j].Cells["Rdgv_NumberTimes"].Value = DataSourse[i].Numberoftimes;
                                    renderDgv_Interface.Rows[j].Cells["rdgv_Return"].Value = DataSourse[i].CheckResult;
                                }

                            }
                        }
                    }
                    else
                    {
                       //这里向控件传数据
                    }
                }
            }
        }

<think>嗯,用户想在WinForms应用程序里搭建WebAPI服务器。首先,我需要回想一下之前的相关引用。比如引用[1]提到如何将WebApi自托管到WinForms中,使用Owin自托管技术。那我应该先考虑使用Owin和Katana库,因为这是.NET中常用的自托管方案。然后,用户可能需要具体的步骤。根据引用[1],首先需要安装Microsoft.AspNet.WebApi.OwinSelfHost包。接着创建Startup类配置路由,然后在WinForms中启动Owin服务器。代码示例可能包括初始化WebApp.Start,并处理启动和停止的逻辑。 还要考虑端口冲突的问题,比如提示用户检查端口是否被占用。另外,引用[2]中提到的HttpClient的使用,可能涉及到客户端如何调用这个API,但用户的问题主要是服务端搭建,所以这部分可能暂时不需要,但可以作为相关问题提出。 另外,引用[3]中的代码示例是关于WebApi的控制器,比如如何处理请求和返回数据。在示例中,用户需要创建ApiController的子类,并定义Get方法。这样,当客户端访问对应的URL时,就能得到响应。 可能还需要提到路由配置,确保控制器被正确识别。比如在Startup类里使用MapHttpAttributeRoutes和默认路由。此外,需要注意线程问题,因为WinForms是UI线程,而Owin服务器可能需要在后台运行,避免界面卡死。 用户可能还想知道如何测试搭建好的API,比如使用Postman或浏览器访问。同时,如何处理多个请求和并发,可能需要提到线程安全或者异步处理,但基础示例可能不需要太复杂。最后,生成相关问题的时候,可以考虑自托管与IIS托管的区别、如何实现HTTPS、如何处理并发请求、如何与WinForms界面交互,以及如何防止重复提交,如引用[2]中的幂等性处理。不过用户当前的问题集中在搭建服务器,所以相关问题应围绕这个主题展开。</think>### 在 WinForms 中实现 WebAPI 服务器的分步指南 #### 一、核心实现步骤 1. **引入 NuGet 包** - 安装 `Microsoft.AspNet.WebApi.OwinSelfHost`(Owin 自托管核心包) - 安装 `Microsoft.Owin.Hosting`(Owin 宿主库) 2. **配置 Owin 启动类** ```csharp using Owin; using System.Web.Http; public class Startup { public void Configuration(IAppBuilder appBuilder) { var config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); } } ``` 3. **在 WinForms 中启动服务** ```csharp using Microsoft.Owin.Hosting; using System.Net; private IDisposable _webApp; private void StartWebApi() { try { _webApp = WebApp.Start<Startup>(url: "http://localhost:9000/"); MessageBox.Show("WebAPI 服务已启动"); } catch (HttpListenerException ex) { MessageBox.Show($"端口冲突: {ex.Message}"); } } // 窗体关闭时释放资源 protected override void OnFormClosing(FormClosingEventArgs e) { _webApp?.Dispose(); base.OnFormClosing(e); } ``` 4. **创建 API 控制器** ```csharp public class DataController : ApiController { [HttpGet] public IHttpActionResult Get(string id) { return Ok($"接收参数: {id}"); } [HttpPost] public IHttpActionResult PostData([FromBody] dynamic data) { return Created($"api/data/{Guid.NewGuid()}", data); } } ``` #### 二、关键技术解析 1. **自托管原理** 通过 OWIN(Open Web Interface for .NET)规范解耦 Web 应用与宿主环境,实现 IIS 外托管[^1]。Katana 是微软的 OWIN 实现方案。 2. **路由配置要点** - 路由模板 `api/{controller}/{id}` 对应 URI 格式:`http://localhost:9000/api/data/123` - 支持 RESTful 风格:`[HttpGet]`、`[HttpPost]` 等特性标记方法 3. **线程管理** 建议在独立线程中启动服务,避免阻塞 UI 线程: ```csharp new Thread(() => StartWebApi()) { IsBackground = true }.Start(); ``` #### 三、进阶功能实现 1. **WinForms 与 WebAPI 交互** ```csharp // 通过静态变量共享数据 public static ConcurrentQueue<string> MessageQueue = new ConcurrentQueue<string>(); // 在控制器中操作队列 public class MessageController : ApiController { [HttpPost] public IHttpActionResult AddMessage(string msg) { MessageQueue.Enqueue(msg); return Ok(); } } // 窗体定时处理队列 private void timer1_Tick(object sender, EventArgs e) { while (MessageQueue.TryDequeue(out string msg)) { listBox1.Items.Add(msg); } } ``` 2. **跨域处理** 安装 `Microsoft.Owin.Cors` 包后添加配置: ```csharp appBuilder.UseCors(CorsOptions.AllowAll); ``` 3. **性能优化** - 使用 `HttpClientFactory` 管理连接池 - 启用响应压缩: ```csharp config.MessageHandlers.Add(new CompressionHandler()); ``` ####
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值