我写了一个动作过滤器,对某些动作的响应进行压缩。
我也想写一个DecompressRequest属性。发件人中有一个请求或2可能相当大,我希望可以选择压缩它们的结尾。有没有办法让OnActionExecuted注入一些可以检测它是否被压缩的代码 - >解压缩然后将其提交给正常的MVC路由解析机制?
我只是想知道在哪里放置我的代码以及如何将其注入MVC,不需要任何人为我编写解压缩代码。
答案 0 :(得分:0)
所以这是一个有效的ApiController示例,你可能不得不为普通控制器构造它,因为ApiController要求参数对于帖子有点不同。绝对不可能'正如其他人声称的那样。
using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using System.IO.Compression;
using System.Web.Http.Filters;
using Nito.AsyncEx.Synchronous;
using System.Collections.Generic;
using System.Web.Http.Controllers;
namespace MyProject.Models
{
public class DecompressRequestAttribute : ActionFilterAttribute
{
private bool IsRequestCompressed(HttpActionContext message)
{
foreach(var encoding in message.Request.Content.Headers.ContentEncoding)
{
if(encoding.Equals("gzip",StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if(actionContext.Request.Method.Method == "POST" && actionContext.ActionArguments.Count == 1 && IsRequestCompressed(actionContext))
{
Stream stream = actionContext.Request.Content.ReadAsStreamAsync().WaitAndUnwrapException();
if (stream != null)
{
using (MemoryStream decompressed = new MemoryStream())
{
using (GZipStream compression = new GZipStream(stream, CompressionMode.Decompress))
{
int amount;
byte[] buffer = new byte[2048];
stream.Seek(0, SeekOrigin.Begin); //Stupid stream doesn't start at beginning for some reason
while ((amount = compression.Read(buffer, 0, buffer.Length)) > 0)
decompressed.Write(buffer, 0, amount);
}
string json = Encoding.UTF8.GetString(decompressed.ToArray());
foreach (HttpParameterDescriptor parameter in actionContext.ActionDescriptor.GetParameters())
{
actionContext.ActionArguments[parameter.ParameterName] = JsonConvert.DeserializeObject(json, parameter.ParameterType);
}
}
}
}
base.OnActionExecuting(actionContext);
}
}
}