Asp.net WebAPi gzip压缩和json格式化
现在webapi越来越流行了,很多时候它都用来做接口返回json格式的数据,webapi原本是根据客户端的类型动态序列化为json和xml的,但实际很多时候我们都是序列化为json的,所以webapi的序列化比我们用ServiceStack.Text序列化要多花费一些时间,还有如果返回的数据量比较大那么我们应该启动gzip和deflate压缩。而这些实现都不得影响现有的code, 我个人喜欢同时也是习惯用特性来完成压缩和json格式化。
1.压缩的code:
namespace MvcApp
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Http.Filters;
using System.IO.Compression;
using System.Net.Http;
public class CompressAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var content = actionExecutedContext.Response.Content;
var acceptEncoding = actionExecutedContext.Request.Headers.AcceptEncoding.Where(x => x.Value == "gzip" || x.Value == "deflate").ToList();
if (acceptEncoding != null && acceptEncoding.Count > && content != null && actionExecutedContext.Request.Method != HttpMethod.Options)
{
var bytes = content.ReadAsByteArrayAsync().Result;
if (acceptEncoding.FirstOrDefault().Value == "gzip")
{
actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.GzipCompress(bytes));
actionExecutedContext.Response.Content.Headers.Add("Content-Encoding", "gzip");
}
else if (acceptEncoding.FirstOrDefault().Value == "deflate")
{
actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.DeflateCompress(bytes));
actionExecutedContext.Response.Content.Headers.Add("Content-encoding", "deflate");
}
}
base.OnActionExecuted(actionExecutedContext);
} }
class CompressionHelper
{ public static byte[] DeflateCompress(byte[] data)
{
if (data == null || data.Length < )
return data;
try
{
using (MemoryStream stream = new MemoryStream())
{
using (DeflateStream gZipStream = new DeflateStream(stream, CompressionMode.Compress))
{
gZipStream.Write(data, , data.Length);
gZipStream.Close();
}
return stream.ToArray();
}
}
catch (Exception)
{
return data;
}
} public static byte[] GzipCompress(byte[] data)
{
if (data == null || data.Length < )
return data;
try
{
using (MemoryStream stream = new MemoryStream())
{
using (GZipStream gZipStream = new GZipStream(stream, CompressionMode.Compress))
{
gZipStream.Write(data, , data.Length);
gZipStream.Close();
}
return stream.ToArray();
}
}
catch (Exception)
{
return data;
} }
}
}
首先判断客户端是否启动gzip,deflate压缩,如果启用并且请求类型不是Options同时又返回数据,那么我们就压缩返回数据。至于用gzip还是deflate那就看客户端接受的一个压缩是gzip,deflate?
2.json
如下:
public IEnumerable<Users> Get()
{
return _userList;
}
很多时候我们会把这个api的返回类型改为HttpResponseMessage同时序列化为json格式的数据,写成一个通用的方法大家来调用。我推荐的实现方式采用Attribute来做。
相关code:
namespace MvcApp
{
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class JsonResultConverterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//actionContext.ActionDescriptor.ResultConverter ;
var actionDescriptor = actionContext.ActionDescriptor;
var field = typeof(HttpActionDescriptor).GetField("_converter", BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
{
field.SetValue(actionDescriptor, new JsonResultConverter());
//actionDescriptor.ReturnType = typeof(HttpResponseMessage);
}
var test = actionDescriptor.ResultConverter;
base.OnActionExecuting(actionContext);
}
}
public class JsonResultConverter : IActionResultConverter
{
public HttpResponseMessage Convert(HttpControllerContext controllerContext, object actionResult)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
} HttpResponseMessage resultAsResponse = actionResult as HttpResponseMessage;
if (resultAsResponse != null)
{
// resultAsResponse.EnsureResponseHasRequest(controllerContext.Request);
return resultAsResponse;
} string jsonResult = TypeSerializer.SerializeToString(actionResult);
var content = new StringContent(jsonResult, Encoding.UTF8, "application/json"); return controllerContext.Request.CreateResponse(HttpStatusCode.OK, jsonResult);
}
}
}
注意HttpActionDescriptor的私有字段_converter在ResultConverter属性中暴露出来,遗憾的是是个只读属性,所以我们需要用反射来设置它的value(实现IActionResultConverter接口)。
运行结果我也就不贴图了,代码下载地址:http://download.csdn.net/detail/dz45693/9486586
Asp.net WebAPi gzip压缩和json格式化的更多相关文章
- asp.net实现GZip压缩和GZip解压
最近在开发一个网站doc.115sou.com,使用到了GZip压缩技术,经过多次搜索找到asp.net中用GZip对数据压缩和解压缩非常方便,当我第一次拿到这个类的时候却感觉很迷茫,无从下手.主要是 ...
- Springboot 之 Filter 实现 Gzip 压缩超大 json 对象
简介 在项目中,存在传递超大 json 数据的场景.直接传输超大 json 数据的话,有以下两个弊端 占用网络带宽,而有些云产品就是按照带宽来计费的,间接浪费了钱 传输数据大导致网络传输耗时较长 为了 ...
- 使用Newtonsoft.json 解决 Asp.Net MVC DateTime类型数据Json格式化问题
解决思路 众所周知,MVC中调用的微软的组件JavaScriptSerialer...,格式DateTime类型数据需要在客户端专门解. 还知道,NewtonSoft.json可以“正确”的格式化Da ...
- ASP.NET WebAPI构建API接口服务实战演练
一.课程介绍 一.王小二和他领导的第一次故事 有一天王小二和往常一下去上早班,刚吃完早餐刚一打开电脑没一会儿.王小二的领导宋大宝走到他的面前,我们现在的系统需要提供服务给其他内部业务系统,我看你平时喜 ...
- 使用Gzip压缩数据,加快页面访问速度
在返回的json数据量大时,启用Gzip压缩,可以提高传输效率.下面为Gzip压缩对json字符串压缩并输出到页面的代码. 一.代码 /** 向浏览器输出字符串响应数据,启用 ...
- asp.net core系列 77 webapi响应压缩
一.介绍 背景:目前在开发一个爬虫框架,使用了.net core webapi接口作为爬虫调用入口,在调用 webapi时发现爬虫耗时很短(1秒左右),但客户端获取响应时间却在3~4秒.对于这个问题考 ...
- ASP.NET MVC 3 网站优化总结(一) 使用 Gzip 压缩
网站开启 Gzip 压缩的好处相信很多人都已经清楚,这样做可以提高网站的性能.那么为什么很多网站没有开启 Gzip 压缩功能呢?原因有4点:防病毒软件.浏览器 bug.网站代理和服务器未配置. 使用 ...
- ASP.NET WEBAPI 简单CURD综合测试(asp.net MVC,json.net,sql基础存储过程和视图,sqlhelper,json解析)
草图 真正的后端是不管前端是什么平台,用什么语言的,JSON格式的数据应该可以应对.用ASP.NET WEBAPI尝试做一个后端,实现最基本的CURD,业务逻辑和数据库操作都放在后端,前端只需要正 ...
- 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
在介绍之前,先简单说一说ASP.NET服务端GZIP压缩模块的作用及工作原理,很多人编写网页的时候页面因为使用了大量的JS特效又或者放置很多大型动态广告导致了页面或脚本体积庞大,通常都会使用一些压缩工 ...
随机推荐
- C# Socket异步实现消息发送--附带源码
前言 看了一百遍,不如动手写一遍. Socket这块使用不是特别熟悉,之前实现是公司有对应源码改改能用. 但是不理解实现的过程和步骤,然后最近有时间自己写个demo实现看看,熟悉熟悉Socket. 网 ...
- HDU 5628 Clarke and math dp+数学
Clarke and math 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5628 Description Clarke is a patient ...
- canvas知识点积累
fillRect(x,y,width,height) 填充一个矩形区域,绘制已填色的矩形,默认填充颜色为黑色.x:矩形左上横坐标,y:矩形左上纵坐标,width:矩形宽度,height:矩形高度. s ...
- Xcode 模拟器复制解决方案
网址:http://blog.csdn.net/zhangao0086/article/details/38491271
- API测试利器postMan 使用教程
自从开始做API开发之后,我就在寻找合适的API测试工具.一开始不是很想用Chrome扩展,用的 WizTools 的工具,后来试过一次 Postman 之后就停不下来了,还买了付费的Jetpacks ...
- FireDAC 下的 Sqlite [10] - 使用 R-Tree 搜索
R-Tree 主要用于三维空间的搜索, 据说这种搜索算法非常之快, 哪怕百万条记录也是眨眼间的事! SQLite 支持 1-5 维, FireDAC 也提供了 TFDSQLiteRTree 控件以方便 ...
- enode
WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例 WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例 https://mp.weixin.qq ...
- nginx php-fpm安装配置(转)
nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端. nginx一般是把请求发fastcgi管理进程处理,fascgi管 ...
- [Deepin 15] sudo source /etc/profile 提示找不到 source 命令(切换到 root 用户:sudo su)
在 Deepin/Ubuntu 系统 中,因为修改了下 配置文件,然后执行 source 命令重新加载配置文件,结果: sudo source /etc/profile 提示找不到 source 命令 ...
- Revit API画垂直于风管的风管
start /// <summary> /// 选择风管与风管外一点,画与风管垂直的风管. /// </summary> [Transaction(TransactionMod ...