Şu anda MVC3 Denetleyicilerimden birkaçını MVC4 Api Denetleyicilerine taşımaya çalışıyorum. MVC3 denetleyicisi için Sıkıştırma mekanizmasını uyguladım ActionFilterAttribute
'u ve OnActionExecutiong
yöntemini geçersiz kılarak Yöntem Yanıtlarını Alın. Bazı araştırmalardan sonra System.Web.HttpFilters
'dan ActionFilterMethod
kullanmam gerektiğini buldum. Birisi, GZipSıkıştır HTTP GET Yanıtı
cevap
En kolayı, enable compression doğrudan IIS düzeyinde. Uygulama düzeyinde yapmak istiyorsanız following post gösterildiği gibi
ileti işleyicisi devrederek özel bir yazabilirsiniz:
public class CompressHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>((responseToCompleteTask) =>
{
HttpResponseMessage response = responseToCompleteTask.Result;
if (response.RequestMessage.Headers.AcceptEncoding != null)
{
string encodingType = response.RequestMessage.Headers.AcceptEncoding.First().Value;
response.Content = new CompressedContent(response.Content, encodingType);
}
return response;
},
TaskContinuationOptions.OnlyOnRanToCompletion);
}
}
public class CompressedContent : HttpContent
{
private HttpContent originalContent;
private string encodingType;
public CompressedContent(HttpContent content, string encodingType)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
if (encodingType == null)
{
throw new ArgumentNullException("encodingType");
}
originalContent = content;
this.encodingType = encodingType.ToLowerInvariant();
if (this.encodingType != "gzip" && this.encodingType != "deflate")
{
throw new InvalidOperationException(string.Format("Encoding '{0}' is not supported. Only supports gzip or deflate encoding.", this.encodingType));
}
// copy the headers from the original content
foreach (KeyValuePair<string, IEnumerable<string>> header in originalContent.Headers)
{
this.Headers.AddWithoutValidation(header.Key, header.Value);
}
this.Headers.ContentEncoding.Add(encodingType);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Stream compressedStream = null;
if (encodingType == "gzip")
{
compressedStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true);
}
else if (encodingType == "deflate")
{
compressedStream = new DeflateStream(stream, CompressionMode.Compress, leaveOpen: true);
}
return originalContent.CopyToAsync(compressedStream).ContinueWith(tsk =>
{
if (compressedStream != null)
{
compressedStream.Dispose();
}
});
}
}
Tüm bu Application_Start
yılında işleyicisi kaydetmek için şimdi Geriye kalan tek:
GlobalConfiguration.Configuration.MessageHandlers.Add(new CompressHandler());
Sanırım bu kodda bir hata var (web'de bulunan benzer örneklerin yanı sıra): Content-Length Header, Content-Length Üstbilgisi gziplenmiş içerikten kopyalandığından hatalı ayarlandı. Bu, Sıkıştırma İşleyicisi aracılığıyla bir StringContent geçirilerek kolayca çoğaltılabilir. Bunu düzeltmek için, 'originalContent.Headers' ile satırın şöyle düzeltilmesi gerekir:' originalContent.Headers.Where (x => x.Key! = "Content-Length") ' –
Accept-Encoding yoksa kod başarısız olur. sağlanır. 'if (response.RequestMessage.Headers.AcceptEncoding! = null)' '(response.RequestMessage.Headers.AcceptEncoding.Any())' –
ise olmalıdır. Aşağıdakileri kodlamaType ve atamaların ataması arasında SendAsync'e eklemenizi öneririm response.Concept ("response.StatusCode! = HttpStatusCode.OK || response.ContentCode! = HttpStatusCode.OK || response.Content == null || string.IsNullOrWhiteSpace (encodingType)) yanıtı olmadan dönmek için hata yanıtları sağlama özelliği." – Paul
kullanarak sıkıştırılan HTTP yanıtı için beni başlatmak için örnek kod parçasını paylaşabiliyorsa harika olur. IIS 7+ kullanıyorsanız, sıkıştırma işlemini GZIP sıkıştırmasını desteklediği için IIS'ye bırakın. Sadece turn it on. Diğer taraftan, sıkıştırma, kontrol cihazı için metale çok yakındır. İdeal olarak kontrolör, baytlardan ve akışlardan daha yüksek seviyede çalışmalıdır.
Genel olarak kabul ediyorum, ancak IIS düzeyindeki sıkıştırma, onu kullanan herhangi bir sunucunun yapılandırılmasını gerektirir. – samosaris
bir sınıfını kullanın ve aşağıdaki kodu
yazma 210Şimdi başka bir sınıf oluşturun ve aşağıdaki kodu yazın.
public class CompressedContent : HttpContent
{
private readonly string _encodingType;
private readonly HttpContent _originalContent;
public CompressedContent(HttpContent content, string encodingType = "gzip")
{
if (content == null)
{
throw new ArgumentNullException("content");
}
_originalContent = content;
_encodingType = encodingType.ToLowerInvariant();
foreach (var header in _originalContent.Headers)
{
Headers.TryAddWithoutValidation(header.Key, header.Value);
}
Headers.ContentEncoding.Add(encodingType);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
Stream compressedStream = null;
switch (_encodingType)
{
case "gzip":
compressedStream = new GZipStream(stream, CompressionMode.Compress, true);
break;
case "deflate":
compressedStream = new DeflateStream(stream, CompressionMode.Compress, true);
break;
default:
compressedStream = stream;
break;
}
return _originalContent.CopyToAsync(compressedStream).ContinueWith(tsk =>
{
if (compressedStream != null)
{
compressedStream.Dispose();
}
});
}
}
Şimdi benim durumumda zaten IIS sıkıştırma özellikli rağmen, aynı sorunu yaşıyorum bu
[Route("GetData")]
[CompressFilter]
public HttpResponseMessage GetData()
{
}
ile biter. Web API'mda yapılandırılmış OWIN Middleware var ve bu benim için çalışan tek çözüm. Ayrıca, sıkıştırmak istediğiniz şeyi gerçekten hedefleyebilirsiniz. Güzel çözüm! – Elferone
gibi Kontrolör veya herhangi API eylem yönteminde aşağıdaki özniteliğini kullanın. Durumunuzda, IIS sıkıştırması mıydı yoksa özel işleyici mi oluşturdunuz? – Carvellis
Evet, bunun için Darin'in bahsettiği gibi, bunun için özel işleyici kullandım. –