C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器

界面: 

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第1张图片 

结构:

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第2张图片

一、新建winform工程

NuGet安装以下几个包:

(1):Microsoft.AspNet.WebApi.OwinSelfHost

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第3张图片 

(2):Microsoft.AspNet.SignalR

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第4张图片

(3)静态文件处理的中间件:Beginor.Owin.StaticFile

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第5张图片

(4)Microsoft.Owin.Cors

 C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第6张图片

(5) 将其他dll打包成一个exe:Costura.Fody

C# Owin快速搭建网站(免IIS),一个.exe文件即是一个服务器_第7张图片

 

 二、代码

启动类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using OwinTest2.model;
using OwinTest2.view;

namespace OwinTest2
{
    static class Program
    {
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(GlobalData.GetForm1());
        }
    }
}

 

Form1 类:

using System;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Owin.Hosting;
using OwinTest2.server;
using OwinTest2.model;

namespace OwinTest2.view
{
    public partial class Form1 : Form
    {
        //Owin服务实例对象
        private IDisposable disposeable;

        public Form1()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            //非主线程亦可操作界面
            CheckForIllegalCrossThreadCalls = false;
            log_textBox.Text = "日志:\r\n";
            SetLog("开始获取本机IP...");
            //获取本机IP
            IPHostEntry here = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress _ip in here.AddressList)
            {
                if (_ip.AddressFamily.ToString().ToUpper() == "INTERNETWORK")
                {
                    GlobalData.ServerIp = _ip.ToString();
                    //GlobalData.Port = (9000 + new Random().Next(1000)).ToString();
                    new Thread(() =>
                    {
                        //本地Http服务器
                        string baseAddress = "http://" + GlobalData.ServerIp + ":" + GlobalData.Port;
                        disposeable = WebApp.Start(url: baseAddress);
                    })
                    { Name = "获取日志线程" }.Start();
                    break;
                }
            }
            this.Text = this.Text + "  " + GlobalData.ServerIp + ":" + GlobalData.Port;
            SetLog("本机IP端口:" + GlobalData.ServerIp + ":" + GlobalData.Port);
        }

        public void SetLog(string log)
        {
            log_textBox.AppendText(log + "\r\n");
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("确认退出吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
            if (result == DialogResult.OK)
            {
                disposeable.Dispose();
                //Dispose();
                //Application.Exit();
                System.Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }
        }
    }
}

Startup 配置类:

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;
using Beginor.Owin.StaticFile;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Owin;

[assembly: OwinStartup(typeof(OwinTest2.server.Startup))]
namespace OwinTest2.server
{
    class Startup
    {
        // This code configures Web API. The Startup class is specified as a type
        // parameter in the WebApp.Start method.
        public void Configuration(IAppBuilder appBuilder)
        {
            // Configure Web API for self-host. 
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}", //{action}目的是为了一个Controller能有多个Get Post方法
                defaults: new { id = RouteParameter.Optional });
            config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            appBuilder.UseWebApi(config);

            //静态文件托管
            appBuilder.Map("/page", map =>
            {
                // 允许跨域
                map.UseCors(CorsOptions.AllowAll);
                map.UseStaticFile(new StaticFileMiddlewareOptions
                {
                    RootDirectory = @"../Debug/page",
                    DefaultFile = "page/index.html",
                    EnableETag = true,
                    EnableHtml5LocationMode = true,
                    MimeTypeProvider = new MimeTypeProvider(new Dictionary
                    {
                        { ".html", "text/html" },
                        { ".htm", "text/html" },
                        { ".dtd", "text/xml" },
                        { ".xml", "text/xml" },
                        { ".ico", "image/x-icon" },
                        { ".css", "text/css" },
                        { ".js", "application/javascript" },
                        { ".json", "application/json" },
                        { ".jpg", "image/jpeg" },
                        { ".png", "image/png" },
                        { ".gif", "image/gif" },
                        { ".config", "text/xml" },
                        { ".woff2", "application/font-woff2"},
                        { ".eot", "application/vnd.ms-fontobject" },
                        { ".svg", "image/svg+xml" },
                        { ".woff", "font/x-woff" },
                        { ".txt", "text/plain" },
                        { ".log", "text/plain" }
                    })
                });
            });

            //SignalR托管
            appBuilder.Map("/signalr", map =>
            {
                // 允许跨域
                map.UseCors(CorsOptions.AllowAll);

                var hubConfiguration = new HubConfiguration
                {
                    //Resolver = **,
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    EnableJSONP = true,
                    EnableDetailedErrors = true
                };

                // Run the SignalR pipeline. We‘re not using MapSignalR
                // since this branch is already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });

            //该值表示连接在超时之前保持打开状态的时间长度。
            //默认为110秒
            //GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110);

            //该值表示在连接停止之后引发断开连接事件之前要等待的时间长度。
            //默认为30秒
            GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(60);
        }
    }
}

LoginController 控制类(可用来处理异步请求):

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

namespace OwinTest2.controllers
{
    public class LoginController:ApiController
    {
        [HttpPost]
        public HttpResponseMessage login([FromBody]Obj obj)
        {
            StringBuilder msg = new StringBuilder();
            if (obj == null)
            {
                msg.Append("参数不能为空");
            }
            else
            {
                if (string.IsNullOrEmpty(obj.u_id))
                {
                    msg.Append("u_id不能为空");
                }
                if (string.IsNullOrEmpty(obj.u_pwd))
                {
                    msg.Append("u_pwd不能为空");
                }
            }
            if (msg.Length > 0)
            {
                msg.Insert(0, "error:");
                return new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(msg.ToString(), System.Text.Encoding.UTF8)
                };
            }
            //GlobalData.GetForm1().SetLog(obj.u_id + "----" + obj.u_pwd);
            //HttpResponseMessage result = null;
            //msg.Append("账号:" + obj.u_id + " 密码:" + obj.u_pwd);
            //result = new HttpResponseMessage(HttpStatusCode.OK)
            //{
            //    Content = new StringContent(msg.ToString(), System.Text.Encoding.UTF8)
            //};
            //return result;

            var httpResponseMessage = new HttpResponseMessage();
            //设置Cookie
            var cookie = new CookieHeaderValue("u_id", obj.u_id);
            cookie.Expires = DateTimeOffset.Now.AddDays(1);
            cookie.Domain = Request.RequestUri.Host;
            cookie.Path = "/";
            httpResponseMessage.Headers.AddCookies(new CookieHeaderValue[] { cookie });
            //返回index.html页面
            httpResponseMessage.Content = new StringContent(File.ReadAllText(@".\page\index.html"), Encoding.UTF8);
            //指定返回什么类型的数据
            httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
            
            return httpResponseMessage;
        }

        public class Obj
        {
            public string u_id { get; set; }
            public string u_pwd { get; set; }
        }
    }
}

主要代码都在上面了,其他没放出来的无关紧要

访问地址:http://172.20.10.7:9000/page

客户端连接SignalR地址:http://172.20.10.7:9000/signalr

172.20.10.7这个ip根据你设置的来

你可能感兴趣的:(C#,Owin,免IIS)