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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unity 2D像素种田游戏学习记录(自用)

一、透明度排序轴 改变sprite的排序方式&#xff0c;默认按照z轴进行排序&#xff08;离摄像机的远近&#xff09;。可以将其改变成y轴的排序方式&#xff0c;这样可以使2D人物走在草丛的下方就不被遮挡&#xff0c;走在草丛上方就被遮挡&#xff0c;如下图。 在项目设置-图形…

K8S服务突然中断无法访问:报The node had condition: [DiskPressure]异常

一、背景 程序在运行过程中&#xff0c;突然无法访问&#xff0c;发现后台接口也无法访问&#xff1b;查看kuboard&#xff0c;发现报如下异常&#xff1a;The node had condition: [DiskPressure]. 继续查看磁盘使用率&#xff0c;发现系统盘使用率已经高达93%。问题前后呼应…

VLDB 2024 | 时空数据(Spatial-temporal)论文总结

VLDB 2024于2024年8月26号-8月30号在中国广州举行。 本文总结了VLDB 2024有关时空数据&#xff08;time series data&#xff09;的相关论文&#xff0c;主要包含如有疏漏&#xff0c;欢迎大家补充。 &#x1f31f;【紧跟前沿】“时空探索之旅”与你一起探索时空奥秘&#xf…

GTC2024 回顾 | 优阅达携手 HubSpot 亮相上海,赋能企业数字营销与全球业务增长

从初创企业入门到成长型企业拓展&#xff0c;再到 AI 驱动智能化运营&#xff0c;HubSpot 为企业的每步成长提供了全方位支持。 2024 年 11 月下旬&#xff0c;备受瞩目的 GTC2024 全球流量大会&#xff08;上海&#xff09;成功举办。本次大会汇聚了全国内多家跨境出海领域企业…

如何使用go语言的gin库来搭建一个属于自己的网页版GPT

我们将会使用go语言的gin库来搭建一个属于自己的网页版GPT 一、准备工作 我们需要使用到ollama&#xff0c;如何下载和使用[ollama](Ollama完整教程&#xff1a;本地LLM管理、WebUI对话、Python/Java客户端API应用 - 老牛啊 - 博客园)请看这个文档 有过gin环境的直接运行就可…

用户登录流程详解

目录 前言1. 登录请求的发起1.1 表单设计与数据收集1.2 请求发送与状态反馈 2. 验证码校验2.1 验证码的生成与展示2.2 验证码的校验机制 3. 登录前置校验3.1 检查账户状态3.2 登录频率限制 4. SS认证管理器的用户校验4.1 密码校验机制4.2 用户角色与权限检查 5. 登录成功后的处…

虚拟机与Xshell5和Xftp4连接与虚拟机克隆

虚拟机与Xshell5和Xftp4连接与虚拟机克隆 虚拟机与Xshell5和Xftp4连接 虚拟机与Xshell5连接 下载Xshell5后启动出现如下界面&#xff0c;点击新建 新建会话输入虚拟机命名&#xff0c;如master&#xff0c;主机输入虚拟机IP&#xff0c;xxx.xxx.xxx.xxx然后确认&#xff0c;…

【大模型系列篇】LLaMA-Factory大模型微调实践 - 从零开始

前一次我们使用了NVIDIA TensorRT-LLM 大模型推理框架对智谱chatglm3-6b模型格式进行了转换和量化压缩&#xff0c;并成功部署了推理服务&#xff0c;有兴趣的同学可以翻阅《NVIDIA TensorRT-LLM 大模型推理框架实践》&#xff0c;今天我们来实践如何通过LLaMA-Factory对大模型…

最大值和最小值的差

最大值和最小值的差 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输出一个整数序列中最大的数和最小的数的差。 输入 第一行为M&#xff0c;表示整数个数&#xff0c;整数个数不会大于1…

【SH】微信小程序调用EasyDL零门槛AI开发平台的图像分类研发笔记

文章目录 微信小程序字符串字符串模板字符串拼接 上传图片GET请求测试编写测试代码域名不合法问题 GET和POST请求测试 微信小程序字符串 字符串模板 这是ES6引入的特性&#xff0c;允许你通过反引号&#xff08;&#xff09;创建模板字符串&#xff0c;并在其中嵌入变量或表达…

Certimate自动化SSL证书部署至IIS服务器

前言&#xff1a;笔者上一篇内容已经部署好了Certimate开源系统&#xff0c;于是开始搭建部署至Linux和Windows服务器&#xff0c;Linux服务器十分的顺利&#xff0c;申请证书-部署证书很快的完成了&#xff0c;但是部署至Windows Server的IIS服务时&#xff0c;遇到一些阻碍&a…

【C++算法】38.模拟_替换所有的问号

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a; 题目链接&#xff1a; 1576. 替换所有的问号 题目描述&#xff1a; 解法 模拟算法就是依葫芦画瓢 特点是思路简单&#xff0c;主要考察代码能力 模拟算法流程&#xff08;一定要在草稿纸上过一遍…

三菱FX3uPLC输入接线注意事项

FX3u微型控制器(DC输入型)的输入根据外部接线&#xff0c;漏型输入和源型输入都可使用。 但是,一定要连接S/S端子的接线。 详细事宜请参考“FX3U系列微型控制器硬件说明手册 AC电源型的输入接线事例(FX3U-囗MR/UA1除外) DC电源型的输入接线事例 *请不要与(0V)、(24V)端子接线…

Milvus向量数据库03-搜索理论

Milvus向量数据库03-搜索理论 1-ANN搜索 通过 k-最近邻&#xff08;kNN&#xff09;搜索可以找到一个查询向量的 k 个最近向量。kNN 算法将查询向量与向量空间中的每个向量进行比较&#xff0c;直到出现 k 个完全匹配的结果。尽管 kNN 搜索可以确保准确性&#xff0c;但十分耗…

链表刷题笔记(题解出自灵茶山)

反转链表 class Solution { public:ListNode* reverseList(ListNode* head){ListNode* cur head;ListNode* prv nullptr;while (cur){ ListNode* nxt cur->next; cur->next prv;prv cur;cur nxt; }return prv;} };反转倒数第n个链表 难点在于怎么找到要反转的头…

【JavaEE初阶】HTML

&#x1f334;什么是HTML&#xff1f; HTML 是用来描述网页的一种语言。 HTML 指的是超文本标记语言: HyperText Markup LanguageHTML 不是一种编程语言&#xff0c;而是一种标记语言标记语言是一套标记标签 (markup tag)HTML 使用标记标签来描述网页HTML 文档包含了HTML 标签…

一文理解 “Bootstrap“ 在统计学背景下的含义

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一文理解 “Bootstrap“ 在统计学背景下的含义 类比&#xff1a;重新抽样 假设我参加了班级的考试&#xff0c;每位同学都获得了一个成绩。现在&#xff0c;我想了解整个班级的平均成绩&#xff0c;但…

2024年下半年郑州大学ACM招新赛题解(ABCDEFGHIJKL)

A n-th 题意 已知公式 π ∑ k 0 ∞ 1 1 6 k ( 4 8 k 1 − 2 8 k 4 − 1 8 k 5 − 1 8 k 6 ) \pi \sum_{k0}^{\infty} \frac{1}{16^k} (\frac{4}{8k1} - \frac{2}{8k4} - \frac{1}{8k5} - \frac{1}{8k6}) π∑k0∞​16k1​(8k14​−8k42​−8k51​−8k61​) 请你求出…

Flutter:开发环境搭建和Android Studio创建Flutter Project

一、系统要求 在安装和运行 Flutter 前&#xff0c;你的 macOS 或者 Windows 环境必须满足以下要求&#xff1a; 二、硬件要求 macOS Flutter 开发环境必须满足以下最低硬件要求。 Windows Flutter 开发环境必须满足以下最低硬件要求。 三、软件要求 要为 Android 编写和编译…

观察者模式的理解和实践

引言 在软件开发中&#xff0c;设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式&#xff08;Observer Pattern&#xff09;是其中一种非常经典且使用率极高的设计模式。它主要用于定义对象之间的一对多关系&#xff0c;使得当一个对象的状态发…