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, 打开之后,其内容如下,水印已经成功加上了

Owin学习笔记(二) 中间件开发的更多相关文章

  1. Struts2学习笔记二:开发流程

    一:创建项目,添加依赖包 二:在web.xml配置核心控制器 <filter> <filter-name>struts2</filter-name> <fil ...

  2. Java学习笔记二:Java开发工具Eclipse的安装与使用

    Java开发工具Eclipse的安装与使用 正如office一样我们在开发java语言过程中同样需要依款不错的开发工具,目前市场上的IDE很多,这里只演示Eclipse的安装: 一:下载软件: 1.下 ...

  3. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  4. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  5. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  6. amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules

    amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules 一.总结 1.am:以 am 为命名空间 2.模块状态: {命名空间}-{模块名}-{状态描述} 3.子模块: {命名空间}- ...

  7. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  8. amazeui学习笔记二(进阶开发1)--项目结构structure

    amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...

  9. Qlik Sense学习笔记之Mashup开发(二)

    date: 2019-01-26 11:28:07 updated: 2019-01-26 11:28:07 Qlik Sense学习笔记之Mashup开发(二) 1.Mobile SPA UI Fr ...

  10. MongoDB学习笔记二- Mongoose

    MongoDB学习笔记二 Mongoose Mongoose 简介 之前我们都是通过shell来完成对数据库的各种操作, 在开发中大部分时候我们都需要通过程序来完成对数据库的操作 而Mongoose就 ...

随机推荐

  1. 逆向分析一款国外Blackjack Card Counter软件并附上License生成脚本

    没有学过逆向,一时兴起,搞了一下这个小软件,名为“逆向分析”,其实过程非常简单,难登大雅之堂,就当段子看吧.首先介绍一下背景吧.这是一款国外的Blackjack也就是21点算牌软件,我从来不玩牌的,机 ...

  2. flask权限控制

    大概思路为通过管理员id的查询角色,然后查看相应权限,为列表类型,然后通过id查询对应的路由规则,进而得出结论得出是否具有该权限 具体代码: def admin_auth(f): @wraps(f) ...

  3. 多版本python安装TensorFlow出现的各种事故

    TensorFlow™ 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库.节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数 ...

  4. VS Code做项目的笔记

    需要自己研究的东西:http://www.bootcss.com/ 画页面时的布局插件:http://blog.chinaunix.net/uid-22414998-id-2878529.html v ...

  5. angularjs和ajax的结合使用 (三)

    转眼九月份了,忙忙碌碌 发现今年还没开过张,写一篇吧. 15年在空闲时就倒腾过angularjs那玩意儿 ,觉得还是挺好的,李金龙那厚厚的一本书,只不过没有系统化应用.最主要的是原来有一个东西没有用到 ...

  6. C++ MD5类封装

    c++ md5 算法封装 md5.h #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* T ...

  7. <算法图解>读书笔记:第3章 递归

    第3章 递归 3.1 递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一 ...

  8. web基础要点记录

    最近公司项目做完了,不怎么忙,翻看了一些基础的资料,文章.就做了个简单的记录. 1.Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性  -we ...

  9. json格式的数据及遍历:

    代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  10. XGBoost原理和公式推导

     本篇文章主要介绍下Xgboost算法的原理和公式推导.关于XGB的一些应用场景在此就不赘述了,感兴趣的同学可以自行google.下面开始: 1.模型构建 构建最优模型的方法一般是最小化训练数据的损失 ...