C#搭建WebApi服务

1,OWIN的介绍

OWIN 的全称是 "Open Web Interface for .NET", OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一套标准的接口, 其目的是为了实现服务器与应用之间的解耦,使得便携式 .NET Web 应用以及跨平台的愿望成为现实, 标准的 OWIN 应用可以在任何 OWIN 兼容的服务器上运行,不再依赖于Windows和IIS 。

2,添加NutGet

添加Microsoft.AspNet.WebApi.Owin 和Microsoft.AspNet.WebApi.Owin Self Host包**(Self Host 用于开启OWIN Host,设置监听接受Http请求)**

3,添加Startup类

Startup是OWIN约定的,用于对OWIN做相关配置的,代码如下:

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;
using System.Web.Http.Cors;
namespace WebAPIServer
{
    /// <summary>
    /// Startup是OWIN约定的,用于对OWIN做相关配置
    /// </summary>
    public class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            try
            {
                HttpConfiguration config = new HttpConfiguration();
                config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
                config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
                //启用路由特性
                config.MapHttpAttributeRoutes();
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional },
                    constraints: new { id = @"d*" }//新增一个约束,指定id只能是数字,不能是其他
                );
                //再自定义一个路由,第一个路由匹配失败再匹配这个
                config.Routes.MapHttpRoute(
                   name: "ActionApi",
                   routeTemplate: "api/{controller}/{action}/{id}",
                   defaults: new { id = RouteParameter.Optional }
               );
                appBuilder.UseWebApi(config);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
4,新建Controllers文件夹,添加FileControllers类

按照 Web API 项目的约定,在项目中添加一个名称为 Controllers 的文件夹,然后新建 一个FileController类,设置其基类为 System.Web.Http.ApiController ,作为示例,其内容与 Visual Studio 自带的 Web API Controller 模板一致,包含4种请求方式(GET/POST/PUT/DELETE),用于演示,重写GET方法(直接返回请求参数)和POST方法(接受实体类参数直接返回),FileController代码如下:

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.Threading.Tasks;
using System.Web;
using System.Web.Http;
using WebAPIServer.Services;
namespace WebAPIServer.Controllers
{
    /// <summary>
    /// 文件类控制器
    /// </summary>
    public class FileController : ApiController
    {
        private string UploadFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadFolder");
        private MediaServer _mediaServer = new MediaServer();
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IHttpActionResult> UploadFolder()
        {
            if (!Request.Content.IsMimeMultipartContent("form-data"))
            {
                return StatusCode(HttpStatusCode.UnsupportedMediaType);
            }
            var provider = new MultipartMemoryStreamProvider();
            await Request.Content.ReadAsMultipartAsync(provider);
            await _mediaServer.UploadFolder(provider, UploadFolderPath);
            // 创建文件夹(如果尚未存在)
            return Ok();
        }
        [HttpGet]
        public async Task<HttpResponseMessage> DownloadFile(string fileName)
        {
            // 获取文件路径
            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "~/UploadFolder/" + fileName);
            // 检查文件是否存在
            if (!File.Exists(filePath))
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "The specified file does not exist.");
            }
            // 创建 HTTP 响应消息
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            // 设置响应内容
            using (FileStream fileStream = File.OpenRead(filePath))
            {
                response.Content = new StreamContent(fileStream);
                // 设置响应头
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileName = fileName
                };
                await response.Content.LoadIntoBufferAsync();
            }
            return response;
        }
    }

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
namespace WebAPIServer.Services
{
    public class MediaServer
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="_uploadFolder"></param>
        /// <returns></returns>
        public async Task UploadFolder(MultipartMemoryStreamProvider provider, string _uploadFolder)
        {
            // 创建文件夹(如果尚未存在)
            Directory.CreateDirectory(_uploadFolder);
            foreach (var content in provider.Contents)
            {
                var disposition = content.Headers.ContentDisposition;
                var fileName = disposition.FileName.Trim('"');
                fileName = Path.GetFileName(fileName);
                var fileData = await content.ReadAsByteArrayAsync();
                // 将文件保存到本地文件夹中
                var filePath = Path.Combine(_uploadFolder, fileName);
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    await fileStream.WriteAsync(fileData, 0, fileData.Length);
                }
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
namespace WebAPIServer.Controllers
{
    /// <summary>
    /// 验证管理控制器
    /// </summary>
    public class AuthorizationController : ApiController
    {
        // GET api/<controller>
        public string Get()
        {
            return "ok";
        }
        // GET api/<controller>/5
        public string Get(int id)
        {
            return string.Format("owin {0} by:linezero", id);
        }
        /// <summary>
        /// 获取授权码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [Route("api/Authorization"), HttpPost] // 自定义路由
        public async Task<HttpResponseMessage> GetAuthorizationCode([FromBody] AuthorizationInfo info)
        {         
            await Task.Run(() =>
            {
                //进行计算并将相应值保存至服务器
                WebAPIOWINServer.AuthorizationInfoRequest?.Invoke(this, info);
            });
            HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
            response.Content = new StringContent($"感谢您的支持,我们将以邮件的形式将授权码发送给您的Email:{info.Email},请注意查收。", Encoding.UTF8);
            return response;
        }
        // PUT api/<controller>/5
        public string Put([FromBody] string value)
        {
            return "Success";
        }
        // DELETE api/<controller>/5
        public string Delete([FromBody] string value)
        {
            return "Success";
        }
    }
    public class AuthorizationInfo
    {
        public string Id { get; set; }
        public string CPUSerialNumber { get; set; }
        public string BIOSSerialNumber { get; set; }
        public string Email { get; set; }
        public DateTime CreateDate { get; set; }
    }
}
5,添加WebApi服务类,代码如下:
using Microsoft.Owin.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WebAPIServer.Controllers;
namespace WebAPIServer
{
    /// <summary>
    /// WebAPI服务类,提供WebApi服务
    /// </summary>
    public class WebAPIOWINServer 
    {
        static IDisposable webApiObject = null;
        /// <summary>
        /// 开启WebApi服务
        /// </summary>
        /// <param name="ServerUrl">绑定的服务uri</param>
        /// <returns></returns>
        public  bool Start(string ServerUrl)
        {
            try
            {
                //调用Startup启动owin,url需要调用方传入
                webApiObject = WebApp.Start<Startup>(url: ServerUrl);
                HttpClient client = new HttpClient();
                //通过get请求数据,测试owin服务是否正常开启
                Uri uri = new Uri(new Uri(ServerUrl), "api/Authorization/get");                     
                var response = client.GetAsync(uri).Result;
                if (response.IsSuccessStatusCode)
                {
                    return true;
                }
                else
                {
                    webApiObject?.Dispose();
                    throw new Exception("Owin loacal server start failed!");
                }
            }
            catch (Exception)
            {
                webApiObject?.Dispose();
                throw;
            }
        }
        #region 定义应用于webapi接口
        /// <summary>
        /// 请求获取授权码
        /// </summary>
        public static Action<object, Controllers.AuthorizationInfo> AuthorizationInfoRequest;
        #endregion
        /// <summary>
        /// 关闭服务
        /// </summary>
        public void Close()
        {
            webApiObject?.Dispose();
        }
    }
}
6,实例:

效果:

特别注意事项:非管理员权限只用于绑定localhost,若绑定其他地址如:http;//127.0.0.1将抛出"调用目标发生异常"的异常。如果想绑定其他地址请使用管理员权限。

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Demo
{
    public partial class Form1 : Form
    {
        WebAPIServer.WebAPIOWINServer server = new WebAPIServer.WebAPIOWINServer();
        public Form1()
        {
            InitializeComponent();
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "启动服务")
            {
                if (Uri.IsWellFormedUriString(txtIP.Text.Trim(), UriKind.RelativeOrAbsolute))
                {
                    try
                    {
                        if (server.Start(txtIP.Text.Trim()))
                        {
                            SetStatus(true);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else
                {
                    MessageBox.Show("网址格式错误");
                }
            }
            else
            {
                server.Close();
                SetStatus(false);
            }
        }
        void SetStatus(bool isOpen)
        {
            if (isOpen)
            {
                btnStart.BackColor = Color.Green;
                btnStart.Text = "停止服务";
                btnStart.ForeColor = Color.Black;
                txtIP.Enabled = false;
            }
            else
            {
                btnStart.BackColor = Color.Red;
                btnStart.Text = "启动服务";
                btnStart.ForeColor = Color.White;
                txtIP.Enabled = true;
            }
        }
    }
}

API控制器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
namespace WebAPIServer.Controllers
{
    /// <summary>
    /// 验证管理控制器
    /// </summary>
    public class AuthorizationController : ApiController
    {
        // GET api/<controller>
        public string Get()
        {
            return "ok";
        }
        // GET api/<controller>/5
        public IHttpActionResult Get(int id)
        {
            return Json(new {Method="Get",Value=id });
        }
        /// <summary>
        /// 获取授权码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [Route("api/Authorization"), HttpPost] // 自定义路由
        public async Task<HttpResponseMessage> GetAuthorizationCode([FromBody] AuthorizationInfo info)
        {         
            await Task.Run(() =>
            {
                //进行计算并将相应值保存至服务器
                WebAPIOWINServer.AuthorizationInfoRequest?.Invoke(this, info);
            });
            HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
            response.Content = new StringContent($"感谢您的支持,我们将以邮件的形式将授权码发送给您的Email:{info.Email},请注意查收。", Encoding.UTF8);
            return response;
        }
        // PUT api/<controller>/5
        public string Put([FromBody] string value)
        {
            return "Success";
        }
        // DELETE api/<controller>/5
        public string Delete([FromBody] string value)
        {
            return "Success";
        }
    }
    public class AuthorizationInfo
    {
        public string Id { get; set; }
        public string CPUSerialNumber { get; set; }
        public string BIOSSerialNumber { get; set; }
        public string Email { get; set; }
        public DateTime CreateDate { get; set; }
    }
}

调用WebApi服务时,不仅仅需要引用上述自定义的程序集WebApiServer.dll,还需要再次添加Microsoft.AspNet.WebApi.Owin 和Microsoft.AspNet.WebApi.Owin Self Host包,否则将报错。

7,WebApiDemo链接。

https://download.csdn.net/download//89726657

相关推荐
悟道茶一杯3 分钟前
服务器开发 的泛型(Generics)基础知识
开发语言·后端·golang
zeijiershuai27 分钟前
Java jdk8新特性:Stream 流
java·开发语言
YOULANSHENGMENG28 分钟前
linux上使用cmake编译的方法
开发语言·c++
学计算机的睿智大学生41 分钟前
关于python的数据分析与应用
开发语言·python·数据分析
晚安~~44 分钟前
共享充电宝系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
找了一圈尾巴1 小时前
Wend看源码-Java-Arrays 工具集学习
java·开发语言·学习
HelloZheQ1 小时前
Java与AI:构建智能应用的强大组合
java·开发语言·人工智能
自律小仔1 小时前
前端开发语言涉及到 的基本数据类型(Primitive Data Types)
开发语言·后端·golang
S-X-S1 小时前
八万字Java面试高频题目汇总(冲刺春招!)
java·开发语言·面试
Chenglin_Yu1 小时前
Python嵌套列表的浅拷贝与深拷贝
开发语言·python