Winform+Owin带界面http服务器 菜鸟示例(含完整代码)

吐血原创,转载请注明出处!

目录

1.界面(控件自己拽一下):

2.安装OwinSelfHost插件

3.Startup类

4.LogController控制类

5.界面事件绑定

6.UI类(方便其他调用界面空间)

7.Main启动类(包含全局异常捕获弹窗显示)


 

假如我们有个Winform程序,这个程序有个表格,用户如何通过简单的http请求来增删改查这个表格,而不用手动去操作这个Winform程序呢?Winform+Owin正是其中一个挺不错的方案!表格操作代码量相对多一点,这里我就用简单的TextBox作为案例,简单的写一下这个方案!

解决方案目录:

1.界面(控件自己拽一下):


2.安装OwinSelfHost插件

 


3.Startup类

using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;

namespace WindowsFormsApp3 {
    class Startup {
        // This code configures Web API. The Startup class is specified as a type
        // parameter in the WebApp.Start method.
        public void Configuration(Owin.IAppBuilder appBuilder) {
            // Configure Web API for self-host. 
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

            //将默认xml返回数据格式改为json
            //config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            //config.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("datatype", "json", "application/json"));
            //json 序列化设置  
            //config.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings() {
            //        NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore //设置忽略值为 null 的属性  
            //    };
            appBuilder.UseWebApi(config);
        }
    }
}

4.LogController控制类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;

namespace WindowsFormsApp3 {
    public class LogController : ApiController {

        //这里用户请求的时候,如果不提交msg参数,那么将会404,建议将参数改成这种方式[FromUri] Obj obj
        [HttpGet]
        public string Get([FromUri] Obj obj) {
            if (obj == null) {
                return "msg参数不能为空!";
            }
            UI.GetF1().AppendText("用户发起了Get请求(http://xxx.xxx.x.xxx:9000/api/log/Get),msg参数:" + obj.msg);
            return "msg:" + obj.msg;
        }

        [HttpPost]
        public string Post ([FromBody]Obj obj) {
            if (obj==null) {
                return "msg参数不能为空!";
            }
            UI.GetF1().AppendText("用户发起了Post请求(http://xxx.xxx.x.xxx:9000/api/log/Post),msg参数:"+ obj.msg);
            return "msg:"+ obj.msg;
        }

        [HttpPost]
        public HttpResponseMessage log([FromBody] Obj obj) {
            HttpResponseMessage result;
            string response = "";
            if (obj == null) {
                response = "参数不能为空!";
            } else {
                if (obj.msg == null || obj.msg.Length == 0) {
                    response += "msg参数不能为空";
                }
                if (obj.log == null || obj.log.Length == 0) {
                    response += " log参数不能为空";
                }
            }
            if (response.Length>0) {
                result = new HttpResponseMessage(HttpStatusCode.OK) {
                    Content = new StringContent(response, System.Text.Encoding.UTF8)
                };
                return result;
            }
            UI.GetF1().AppendText("用户发起了Post请求(http://xxx.xxx.x.xxx:9000/api/log/log),msg=" + obj.msg+",log="+obj.log);
            result = new HttpResponseMessage(HttpStatusCode.OK) {
                Content = new StringContent("这是post log:msg=" + obj.msg + ",log=" + obj.log)
            };
            return result;
        }

        public class Obj {
            public string msg { get; set; }
            public string log { get; set; }
        }

    }
}

5.界面事件绑定

using Microsoft.Owin.Hosting;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp3 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
            //非主线程亦可操作界面
            CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e) {
            //获取本机IP
            string IP = "";
            IPHostEntry here = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress _ip in here.AddressList) {
                if (_ip.AddressFamily.ToString().ToUpper() == "INTERNETWORK") {
                    IP = _ip.ToString();
                    break;
                }
            }
            string baseAddress = "http://"+ IP+":9000/";
            WebApp.Start<Startup>(url: baseAddress);
            AppendText("服务器IP及端口:"+ baseAddress);
            AppendText("开始监听...");
        }

        private void button2_Click(object sender, EventArgs e) {
            //测试API(这里就没写测试的了,自己用Http工具自己试一下)
            //http://192.168.1.3:9000/api/log/Get?msg=234234
            //URL:http://192.168.1.3:9000/api/log/Post  请求体:msg=testMsg&log=testLog
            //URL:http://192.168.1.3:9000/api/log/log  请求体:msg=testMsg&log=testLog
        }


        public void AppendText(string msg) {
            textBox1.AppendText(msg+"\r\n");
        }
    }
}

6.UI类(方便其他调用界面空间)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp3 {
    class UI {
        private static Form1 f1;
        public static Form1 GetF1() {
            if (f1==null) {
                f1 = new Form1();
            }
            return f1;
        }
    }
}

7.Main启动类(包含全局异常捕获弹窗显示)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp3 {
    static class Program {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main() {
            try {
                //处理未捕获的异常   
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                //处理UI线程异常   
                Application.ThreadException += Application_ThreadException;
                //处理非UI线程异常   
                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //Application.Run(new Form1());
                Application.Run(UI.GetF1());
            } catch (Exception ex) {
                var strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now + "\r\n";
                var str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
                              ex.GetType().Name, ex.Message, ex.StackTrace);
                MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);//进行弹窗提示
                //Environment.Exit(0);
            }
        }

        /// <summary>
        ///错误弹窗
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
            string str;
            var strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now + "\r\n";
            var error = e.Exception;
            if (error != null) {
                str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
                    error.GetType().Name, error.Message, error.StackTrace);
            } else {
                str = string.Format("应用程序线程错误:{0}", e);
            }
            MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //Environment.Exit(0);
        }


        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            var error = e.ExceptionObject as Exception;
            var strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now + "\r\n";
            var str = error != null ? string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆栈信息:{1}", error.Message, error.StackTrace) : string.Format("Application UnhandledError:{0}", e);
            MessageBox.Show(str, "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //Environment.Exit(0);
        }

    }
}

 

TestController类是我自己瞎写测试的,这里没什么关联就不放上来了....

有什么不对的欢迎指出批评,写博不易,转载请注明出处


 

 

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
OWIN(Open Web Interface for .NET)是一个开放的Web应用程序接口,可以让你在.NET应用程序中使用不同的Web服务器和Web框架。OWIN允许你将Web服务器和应用程序分离开来,这样你可以使用不同的Web服务器来运行你的应用程序,而无需修改应用程序的代码。 在Winform应用程序中调用OWIN,你需要先安装 Microsoft.Owin.Hosting NuGet 包,然后在代码中使用以下代码启动OWIN: ```csharp using Microsoft.Owin.Hosting; using System; namespace WinformApp { public partial class Form1 : Form { private IDisposable _webApp; public Form1() { InitializeComponent(); } private void btnStart_Click(object sender, EventArgs e) { string baseAddress = "http://localhost:9000/"; _webApp = WebApp.Start<Startup>(url: baseAddress); MessageBox.Show("OWIN web server started at " + baseAddress); } private void btnStop_Click(object sender, EventArgs e) { _webApp.Dispose(); MessageBox.Show("OWIN web server stopped"); } } } ``` 在上面的代码中,我们使用WebApp.Start方法来启动OWIN服务器。我们还提供了一个名为Startup的类,该类用于配置OWIN应用程序。在这个类中,你可以添加中间件和路由,以确保请求被正确地路由到你的应用程序中。 ```csharp using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WinformApp.Startup))] namespace WinformApp { public class Startup { public void Configuration(IAppBuilder app) { // Add middleware and configure routes here } } } ``` 在上面的代码中,我们使用OwinStartup属性告诉OWIN要使用Startup类来配置应用程序。在Configuration方法中,我们可以添加中间件和路由来处理请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值