C#搭建WebApi服务

news2024/11/9 10:15:06

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/lingxiao16888/89726657

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

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

相关文章

MongoDB事务机制

事务机制 1.事务概念 在对数据的操作的过程中&#xff0c;涉及到一连串的操作&#xff0c;这些操作如果失败&#xff0c;会导致我们的数据部分变化了&#xff0c;部分没变化。这个过程就好比如你去吃早餐&#xff0c;你点完餐了&#xff0c;并且吃完早餐了&#xff0c;没付钱你…

ES6标准---【五】【看这一篇就够了!!!】

目录 ES6以往文章 箭头函数的基本用法 箭头函数的用处 简化回调函数 rest参数与箭头函数结合 箭头函数使用注意点 this指向的问题 其它不存在的变量 不能使用call()、apply()、bind()方法改变this的指向 箭头函数不适用场合 定义对象时&#xff0c;对象方法内部包含…

信创环境下源代码防泄露解决方案

在当今数字化时代&#xff0c;信息安全已成为企业生存与发展的基石&#xff0c;尤其是在信息技术应用创新&#xff08;信创&#xff09;环境下&#xff0c;数据保护更是被提升至前所未有的高度。SDC沙盒防泄露系统以其独特的技术架构和卓越的安全性能&#xff0c;在信创环境中构…

ES6标准---【六】【学习ES6标准看这一篇就够了!!!】

目录 以往ES6文章 前言 对象属性的简洁表示法 一个实际例子 简介写法在打印对象时也很有用 注意 对象属性名表达式 用表达式做属性名 用表达式定义方法名 注意 对象方法的name属性 对象属性的可枚举性和遍历 可枚举性 属性的遍历 属性比那里次序规则 super关键…

图片生成PPT!首推这款一站式AI制作PPT工具!

在当今快节奏的工作中&#xff0c;制作一份精美的PPT演示文稿往往是一项费时费力的工作&#xff0c;特别是当我们需要将大量的图片转化为PPT时&#xff0c;传统的方法显得尤为繁琐。幸运的是&#xff0c;随着AI人工智能技术的飞速发展&#xff0c;一种更便捷地将图片转为ppt的解…

计算机毕业设计 《计算机基础》网上考试系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Java之线程篇三

​​​​​​​ 目录 线程状态 观察线程的所有状态 线程状态及其描述 线程状态转换 代码示例1 代码示例2 线程安全 概念 线程不安全的代码示例 线程不安全的原因 线程安全的代码示例-加锁 synchronized关键字 synchronized的特性 小结 形成死锁的四个必要条件 …

Java设计模式之命令模式介绍和案例示范

一、命令模式简介 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使你可以用不同的请求对客户端进行参数化、对请求排队或记录日志&#xff0c;以及支持可撤销的操作。命令模式的核心思想是将发出请…

kvm 虚拟机命令行虚拟机操作、制作快照和恢复快照以及工作常用总结

文章目录 kvm 虚拟机命令行虚拟机操作、制作快照和恢复快照一、kvm 虚拟机命令行虚拟机操作(创建和删除)查看虚拟机virt-install创建一个虚拟机关闭虚拟机重启虚拟机销毁虚拟机 二、kvm 制作快照和恢复快照**创建快照**工作常见问题创建快照报错&#xff1a;&#xff1a;intern…

超详细、史上最全pytorch安装教程

一、anaconda安装 1.下载 Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirrorhttps://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 这里划到最下面选择5.3.1最新版&#xff1a; 2.下载完成后安装 点击next 点击 I agree 选择All Us…

ignav的INS的状态更新

ignav的代码 static void updstat(const insopt_t *opt,insstate_t *ins,const double dt,const double *x0,const double *P0,double *phi,double *P,double *x,double *Q) {opt->exprn?getprn(ins,opt,dt,Q): getQ(opt,dt,Q); // //phi 状态转移矩阵 &#xff0c;离散化…

算法学习攻略总结 : 入门至进阶,通关之路指南

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; <搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到…

CircleProgressView 鸿蒙ArkTS自定义View实现圆形进度条

上篇的截图中除了一个上下的箭头&#xff0c;还有一个圆形进度条&#xff0c;今天我们来讲讲这个如何进行实现 我们看这个图形的构造&#xff0c;其实很简单&#xff1a;一个圆形图形&#xff0c;以及一个文本来显示进度 所以我们用一个层叠布局 绘制一个带颜色的圆形&#xff…

『功能项目』播放动画时禁止点击移动【40】

我们打开上一篇39GameObject对象池 - 第三职业的项目&#xff0c; 本章要做的事情是在第三职业播放续航攻击动画时禁止点击时触发的移动函数&#xff0c;换句话说是在播放攻击动画时禁止移动 修改脚本&#xff1a;PlayerRayClickNavigation.cs 运行项目 - 播放第三职业续航技能…

2-92 基于matlab的KPCA的TE过程的故障监测

基于matlab的KPCA的TE过程的故障监测&#xff0c;利用核主元分析法(KPCA)来进行故障检测的思想,将输入空间中复杂的非线性问题转化为特征空间中的线性问题&#xff0c;计算步骤&#xff1a;&#xff08;1&#xff09; 选择监控变量&#xff0c;收集正常工况下的各变量的样本&am…

【警告 C6031:返回值被忽略:scanf】

警告 C6031 返回值被忽略: “scanf”。 错误 C4996 scanf: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. #include <stdio.h> int max(int x, int y…

OKHttp实现原理分享

前言介绍 大约在2年半之前&#xff0c;就想写一篇关于OKHttp原理的文章&#xff0c;一来深入了解一下其原理&#xff0c;二来希望能在了解原理之后进行更好的使用。但是因为种种原因&#xff0c;一直无限往后推迟&#xff0c;最近因为我们情景智能半个月一次的分享轮到我了&…

手势识别&手势控制系统-OpenCV&Python(源码和教程)

项目特点 手部手势识别&#xff1a; 项目利用计算机视觉技术来识别手部的各种手势。这种技术可以应用于多种场景&#xff0c;比如人机交互、游戏控制、无障碍技术等。 自定义手势&#xff1a; 用户可以自定义手势&#xff0c;这意味着可以通过训练新的手势模式来扩展系统的功能…

基于vue框架的城市网约车管理系统v34td(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,司机,订单评价,完成订单,司机接单,打车订单 开题报告内容 基于Vue框架的城市网约车管理系统开题报告 一、研究背景与意义 1.1 研究背景 随着城市化进程的加速和互联网技术的飞速发展&#xff0c;网约车服务作为一种新兴的出行方…

基于java+SpringBoot+Vue的阿博图书馆管理系统设计与实现

开发语言:Java 数据库:MySQL技术:SpringBootMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统简介 阿博图书馆管理系统是一款基于Java、SpringBoot和Vue.js技术开发的信息化管理系统&#xff0c;旨在为图书馆提供一个高效、便捷的图书管理与借阅服务。系统通过B/S架构&#x…