Owin学习笔记(二) 中间件开发
原文网址:http://t.zoukankan.com/lwqlun-p-9095102.html
Owin中也有类似于ASP.NET的管道,以前在做ASP.NET项目的时候,可以制作很多不同功能HttpHandler或者HttpModule并注册在Web.config中重复使用。在Owin的管道中,我们可以注册中间件(Middleware)来实现相似的功能。
所有的Owin中间件需要继承OwinMiddleware这个抽象类。
public abstract class OwinMiddleware { //构造函数,定义了下一个需要运行的中间件 protected OwinMiddleware(OwinMiddleware next); //下一个需要运行的中间件 protected OwinMiddleware Next { get; set; } //中间件的执行方法 public abstract Task Invoke(IOwinContext context); }
当一个请求发送到Owin服务器之后,Owin服务器会自动获取Request中信息并转换成一个IOwinContext对象,然后依次运行定义在Owin管道中的中间件的Invoke方法。在每个中间件的Invoke方法中,开发人员都可以获取到请求的上下文,并且做出不同的Response。
这里需要注意管道中的中间件是有顺序的,他的顺序就是你在Owin启动类Startup中的注册顺序。每个中间件运行完毕之后,都可以指定是否继续运行后续的中间件。在Invoke方法中可以显示调用Next.Invoke(context)来表明需要继续运行后续的中间件。
下面我们做一个简单的PNG图片水印中间件。
创建项目
首先我们创建一个空的命令行工程PNGWatermark,并依次引入一下Nuget Library
Install-Package Microsoft.Owin.Host //使用Owin Host托管
Install-Package Microsoft.Owin.StaticFiles //静态文件中间件
Install-Package Microsoft.Owin.Host.HttpListener //使用HttpListener作为Owin服务器
创建水印中间件
添加一个新类PngWatermarkMiddleware, 其中的AddTextToImg方法是我从网上随便Copy的,这里的主要代码在Invoke方法中。因为Owin中不能使用ASP.NET的Server.MapPath方法,所以这里需要借助PhysicalFileSystem类,来吧url转换成对应的服务器文件路径。在这个方法最后我没有写Next.Invoke(context), 是因为我认为加上水印之后,后续的中间件已经不需要运行了。
public class PngWatermarkMiddleware : OwinMiddleware { public PngWatermarkMiddleware(OwinMiddleware next) : base(next) { } public override async Task Invoke(IOwinContext context) { //获取网站根目录 PhysicalFileSystem pfs = new PhysicalFileSystem(string.Empty); IFileInfo info = null; //转换url为绝对文件路径, 并检查文件是否存在 var isFile = pfs.TryGetFileInfo(context.Request.Uri.LocalPath, out info); if (isFile && info.Name.EndsWith(".png")) { //如果是文件,就读取图片内容,加水印 Image image = Image.FromFile(info.PhysicalPath); var imageByteAfterAddingWatermark = AddTextToImg(image, "Author: Lamond"); context.Response.ContentType = "application/x-png"; context.Response.StatusCode = (int)HttpStatusCode.OK; await context.Response.WriteAsync(imageByteAfterAddingWatermark); } } public static byte[] AddTextToImg(Image image, string text) { Bitmap bitmap = new Bitmap(image, image.Width, image.Height); Graphics g = Graphics.FromImage(bitmap); float fontSize = 12.0f; //字体大小 float textWidth = text.Length * fontSize; //文本的长度 //下面定义一个矩形区域,以后在这个矩形里画上白底黑字 float rectX = 0; float rectY = 0; float rectWidth = text.Length * (fontSize + 8); float rectHeight = fontSize + 8; //声明矩形域 RectangleF textArea = new RectangleF(rectX, rectY, rectWidth, rectHeight); //定义字体 Font font = new Font("宋体", fontSize); //白笔刷,画文字用 Brush whiteBrush = new SolidBrush(Color.White); //黑笔刷,画背景用 Brush blackBrush = new SolidBrush(Color.Black); g.FillRectangle(blackBrush, rectX, rectY, rectWidth, rectHeight); g.DrawString(text, font, whiteBrush, textArea); MemoryStream ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); return ms.ToArray(); } }
注入水印中间件
Owin中间件需要在Owin启动类的Configuration中注册,所以这里我们需要加一个Owin Startup类,代码如下
public class Startup { public void Configuration(IAppBuilder app) { app.Use<PngWatermarkMiddleware>(); } }
以OwinHost方式启动项目
在Program.cs中加入以下代码,启动Owin服务器
class Program { static void Main(string[] args) { var url = "http://localhost:1234"; using (WebApp.Start<Startup>(url)) { Console.WriteLine("Server Started"); } Console.Read(); } }
最终运行效果
下面我们将一个logo.png放置到当前项目的bin/debug目录中
然后启动项目,运行效果如下
打开浏览器,输入http://localhost:1234/logo.png
浏览器会自动下载一个logo.png, 打开之后,其内容如下,水印已经成功加上了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2020-11-09 Java集合中List,Set以及Map等集合体系详解(史上最全)
2020-11-09 数据库中事务详解!
2020-11-09 mysql中用limit 进行分页有两种方式