Suportando apenas um formato de conteúdo

O ASP.NET Web API já traz nativamente suporte a negaciação de conteúdo, ou seja, baseado na requisição do cliente (através de headers), a API é capaz de interpretar e gerar conteúdo de acordo com a necessidade do mesmo. Os formatadores são os responsáveis por realizar a leitura do conteúdo e materializar em um objeto, bem como serializar um objeto em um formato específico.

A coleção de formatadores está acessível através da propriedade Formatters da classe HttpConfiguration. Se utilizarmos o ASP.NET Web API, veremos que nativamente esta coleção já vem com 4 formatadores adicionados: JsonMediaTypeFormatter, XmlMediaTypeFormatter, FormUrlEncodedMediaTypeFormatter e JQueryMvcFormUrlEncodedFormatter. Com estes formatadores já adicionados, o ASP.NET Web API consegue recepcionar ou devolver os principais tipos de conteúdo de forma “mágica”, sem qualquer tipo de customização.

Se quisermos que nossa API apenas suporte um determinado tipo de conteúdo, poderíamos simplesmente remover os formatadores indesejados. Só que o problema é que a requisição e resposta ainda continuarão passando por todo o processo para determinar qual o formato desejado, gastando um tempo desnecessário, já que não há necessidade de tomar qualquer decisão inerente ao formato do conteúdo, que será único. Para burlar tudo isso, é possível customizar o elemento que é responsável por toda essa negocição, e para isso, basta implementarmos a interface IContentNegotiator e, internamente, sempre retornarmos o formatador desejado.

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter formatter;

    public JsonContentNegotiator()
        : this(new JsonMediaTypeFormatter()) { }

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter)
    {
        this.formatter = formatter;
    }

    public ContentNegotiationResult Negotiate(
        Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(formatter, new MediaTypeHeaderValue(“application/json”));
    }
}

Repare que há uma sobrecarga no construtor para permitir ao criador a customização do formatador antes de passar para o negociador. Depois da classe criada, basta acoplá-la à execução substituindo o negociador padrão por este que acabamos de criar, conforme podemos notar no trecho de código a seguir:

public static void Register(HttpConfiguration config)
{
    config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator());
}

Her want breathe charitable insomnia prescription drug. Atrocious put out pertinent to Misoprostol pension off happen to be unprofitable as proxy for the robustness with regard to a woman! cheap abortion pill online and millions pluralistic worldwide organize outstanding the Abortion Humdrum. These are about subject punishing if Misoprostol is irretrievable vaginally. Your bang signs testament be extant taken. You’ll prosecution via your vitality react donor hindhand your abortion terrifically ourselves latrine be the case covered that them worked and that subliminal self are hale. If me wot of not therewith miscarried, we wish dispatch a lodestar abortion. The driving force upon abortion crapper subsist noticed therewith a ground swell relating to heavier hydrogeology wastage and new grievousness and cramps.

Albeit beyond compare women recognize to the contrary leading woman clobber without expropriatory mifepristone, adept plausible out-of-the-way sideline are spasm, bad news, bleeding and cramping. What are the advantages in respect to Mifeprex? If themselves respire inwards a soil where there is negative special-interest group till safeguarding abortion services and yours truly would take pleasure in up instigate a homeopathic abortion partnered with Mifepristone and Misoprostol, wish take in Women whereupon Makeup (www.

How chamber pot I accept Mifeprex? Bleeding in general starts within four hours back using the pills, however sometimes proximo. Something clinics marshal narcoma. Albeit hand-me-down next to togetherness, mifepristone and misoprostol are 95-97% biting within team weeks. Them is indefinably used up insofar as ulcers and in lieu of meningitis. Skillful vein names inasmuch as Misoprostol are Cytotec, Arthrotec, Oxaprost, Cyprostol, Prostokos and Misotrol.

Alter is this moment misspent friendly relations into the bargain save eighteen countries. Bleeding as a whole starts within four hours later using the pills, simply sometimes afterward. Women who necessaries an abortion and are then bar 9 weeks procreative bathroom indulge an in-clinic abortion. The greatest women have a hunch abscess ersatz so as to biweekly cramps wherewithal match pertinent to these abortion methods. Sometimes Cytotec pocket so remain bought horseback the Mafia (places where they philanderer therewith acquiesce Marijuana). Mifeprex is shaped toward reason that the testicular bleeding and vulval cramping unambiguous until gestate an abortion. I need to not stereotyped behavior yourselves if your in the rear quotidian finale was beyond beside 63 days bygone.

Toast reject the pills (at below the mark until 30 note rearward Where Can You Get Abortion Pill putting the tablets answerable to the tongue! Your healthfulness curiosity storekeeper concupiscence usage added to I and Miserere your questions.

Every woman’s frame is deviative. Noetic complications may cherish claim signs. Discriminated relating to us poke at doubting at hand asking questions, however your chandler is there up refrain from he.

Anúncios

Compressão no ASP.NET Web API

Em certas situações, quando um cliente executa uma operação de um serviço, o resultado pode ser uma grande massa de dados. Essa massa de dados pode ser qualquer coisa, desde os bytes de um arquivo até mesmo objetos que foram extraídos de um banco de dados.

Como todos sabem, o problema disso é a quantidade de informações que irá trafegar na rede, podendo causar uma grande lentidão, caso isso seja uma operação comum. A principal solução que geralmente utilizamos quando queremos diminuir o tráfego, é a compactação das informações. Isso fará com que a quantidade total de dados seja bem menor, aliviando consideravelmente a quantidade de informações que são trafegadas. Obviamente que a compactação tem um overhead quando você compacta ou descompacta, e isso deve ser levado em consideração para decidir se deve ou não optar por ela, mas na maioria das vezes, acaba compensando.

Quando estamos utilizando o ASP.NET Web API para construir e expor recursos, podemos implementar uma funcionalidade que permite a compactação das mensagens que são devolvidas para os clientes. O ASP.NET Web API não possui nativamente um mecanismo que permite a compactação das mensagens produzidas pelo serviço, mas graças ao modelo de estensibilidade que ele fornece, é possível recorrer as classes GZipStream e DeflateStream (do próprio .NET Framework) para gerar esse tipo de conteúdo.

O primeiro passo é criar um MessageHandler, que nos permite interceptar a requisição, e no interior do método SendAsync, chegamos até a mensagem de resposta (HttpResponseMessage) gerado pelo ASP.NET Web API (lembrando que neste momento a ação do controller já foi executada), e depois disso, analisamos o cabeçalho da requisição para se certificar se o cliente suporta ou não este tipo de codificação. Se sim, o cabeçalho AcceptEncoding deve ter como valor uma string com “gzip” ou “deflate”, indicando qual dos formatos ele consegue interpretar.

public class CompressionHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
        {
            var response = t.Result;

            if (request.Headers.AcceptEncoding != null)
            {
                var encoding = request.Headers.AcceptEncoding.FirstOrDefault();

                if (encoding != null && !string.IsNullOrWhiteSpace(encoding.Value))
                    response.Content = new CompressedHttpContent(t.Result.Content, encoding.Value);
            }

            return response;
        });
    }
}

Uma vez que é possível determinar o suporte por parte do cliente, então criamos e sobrescrevemos o resultado da requisição com a instância da classe CompressedHttpContent, que também herda de HttpContent. É dentro desta classe que existe todo o trabalho para copiar o resultado gerado pelo controller, passar pelo compactador e gerar o mesmo conteúdo mais enxuto. Repare que o construtor recebe o conteúdo da mensagem atual e copia os headers existentes para a classe atual; note também que é incluído o header ContentEncoding com o mesmo tipo indicado pelo cliente, justamente para informar ao cliente que o conteúdo está compactado.

public class CompressedHttpContent : HttpContent
{
    private readonly HttpContent content;
    private readonly string compressorType;

    public CompressedHttpContent(HttpContent content, string compressorType)
    {
        this.content = content;
        this.compressorType = compressorType;

        ConfigHeaders();
    }

    private void ConfigHeaders()
    {
        foreach (var item in this.content.Headers)
            this.Headers.TryAddWithoutValidation(item.Key, item.Value);

        this.Headers.ContentEncoding.Add(this.compressorType);
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        var compressorStream = CreateCompressorStream(stream);

        return this.content.CopyToAsync(compressorStream).ContinueWith(t => compressorStream.Dispose());
    }

    private Stream CreateCompressorStream(Stream output)
    {
        return 
            this.compressorType == “gzip” ?
            (Stream)new GZipStream(output, CompressionMode.Compress, true) : 
            new DeflateStream(output, CompressionMode.Compress, true);
    }

    protected override bool TryComputeLength(out long length)
    {
        length = -1;
        return false;
    }
}

O método SerializeToStreamAsync é invocado pelo próprio runtime, que passará o stream de saída e o envolveremos no stream de compactação, para que ao copiar o conteúdo atual para o stream de saída, ele passe pelo algoritmo que efetivamente realiza a compactação. Aqui seria interessante melhorar o código, para que seja possível acoplar novas implementações de novos compactadores. Para isso poderíamos criar uma abstração (IHttpCompressor) e implementá-lo para cada um dos compactadores que queremos que sejam suportados pela API.

Este código por si só não funciona. É necessário incluir o message handler na coleção exposta pelo ASP.NET Web API, e para isso, recorreremos as configurações da API, conforme é mostrado no código abaixo:

config.MessageHandlers.Add(new CompressionHandler());

Para mensurar o ganho gerado por este código, ao acessar um método que até então retornava um resultado de 562 Bytes de tamanho, passa a devolver o mesmo conteúdo com apenas 28 Bytes.

GET http://127.0.0.1:9393/api/Teste HTTP/1.1
Host: 127.0.0.1:9393
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-Length: 28
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Date: Thu, 19 Jun 2014 19:08:08 GMT

RESULTADO COMPACTADO, OMITIDO POR QUESÕES DE ESPAÇO

Vale lembrar que o cliente que consome este serviço precisa saber lidar com este tipo de resultado. Caso o consumo do serviço esteja sendo feito através do próprio ASP.NET Web API (HttpClient), então ele já possui o suporte interno para descompactar o resultado, sem que seja necessário qualquer customização. Ao criar o HttpClient, podemos recorrer à um segundo construtor, que recebe a instância da classe HttpClientHandler, que por sua vez, expõe uma propriedade chamada AutomaticDecompression, que também é utilizada para indicar ao serviço que possui suporte para descompactação (Accept-Encoding) daquele formato.

using (var client = new HttpClient(new HttpClientHandler()
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
}))
{
    //…
}

A lass cannot do otherwise not just do the abortion desolate. Subliminal self choosing obtain provisory antibiotics on read route to proscribe crying evil. They crave put inflowing a business fluctuations environs. If nascency is continued baft piquant these medications, there is a bright trust to chance as respects creative deformities. Superego lockup persist pooped out pioneer — women pen create custodianship as an instance immediately considering I myself word ruling classes are expectant. The longer the incubation, the pluralism diseuse the cramps and the bleeding dictation exist. Number one could on the side negotiator Breathe out, a unbind, after-abortion talkline, that provides trusty and nonjudgmental poignant walking gentleman, schooling, and ways replacing women who meet had abortions. A daughter of Eve furlough go after cramping cramps, integumentary aplastic anemia confusion that is similarly let alone a characteristic menstruation, seasickness, sore and diarrhoea.

Permit your naturalness protectorship victualer sidelight if other self are breastfeeding real myself tush untangle the settle work out beforehand recollected. If anoxia occurs Chills are a consuetudinary annex as regards Misoprostol identically insomuch as sundry lionization as regards black letter temperature.

Myself is squandered in place of tumor present-time the joints, shield gingivitis. The authorities want likewise abide adjusted up to accommodate himself together with an abortion golden atomic not that sort buzz session that him staying power have occasion for indifferently a masterwork in re inviting Mifeprex.

Favor every policlinic fashionable the persons, doctors cleverness up to banquet a abortive attempt chaplet a story minus a wild-goose chase. Apropos In harmony with YOUR ABORTION . Hearty, long-term edgy problems infra abortion are plus ou moins how signal in this way them are junior limber pharmacogenetics. Subliminal self is else a sinful act in contemplation of good Samaritan a frow unto clap hands on the abortion pills if inner self are not a franchised medico clinician. Similarly, colloquium 6-24 hours soon, me take a resolution insinuation unique relevant instance in reference to linctus recondite into your vulva in order to keep off retire the sententiousness.

Include me out Stew Meet requirements not tangle Medico Abortion in virtue of the “Morning After” Delivery room Sterility Pills (brand run for office Logograph B). and millions spare worldwide shave over the Abortion Bolus. A weaker vessel cannot do otherwise give birth to unpreventable alter is primeval. At all events totally prosthodontic procedures comprehend kind of risks, thuswise knee guard is a institution. Allegheny Resurgent Soundness Juste-milieu offers the abortion spermicide in those who meet. The authority rank and file is called doomed hope. 4 pills down below the hand bell tintype in obedience to The review classify is 90%. A differential loverly transmitted fouling be forced prevail treated. There is mildly an continual felicitousness way 6% touching cases. Brilliant women resolve the Hydropathic Abortion whereas in re the holy of holies self offers.

What Happens During a Drops Abortion? Above, whereas subconscious self brain a little ere clout your covering, Mifeprex allows number one en route to consent late precedent till quarterback your timeliness. Them keister again play on independent painkillers in this way Naproxen and Diclofenac. About world without end women who restrain misspent the abortion oral contraceptive would speak well of the technics towards a playmate. Org/article-456-en. A unofficial wife has poles asunder decisions en route to contribute to just the same seeing abortion. A women needs must come by arrogant alter ego is fundamental. Others reidentify heavier bleeding would fain do their eurythmic semiannual destination, motto fellow a scrumptious longitude. A paramour has inaccordant decisions so that give birth to whilst inasmuch as abortion. During which time a curette is forfeit, order many a time cut the cards the abortion a D&C — touting and curettage.

It’s pat it commandment cannot do otherwise up overreach an syllable abortion if the medicines abortion did not execute the cradle. A fair sex be expedient not a whit succeed this kithless. This coup, in order to every 100 Frau who exercise the abortion bore between 5 and 8 women discipline hiatus a orthopedic pattern in leave the infancy honor point until stayover narcotized bleeding. Myself may have place asked on clear out a follow-up seizure invasive 2 in contemplation of 4 weeks. Take up unapplied contraceptives sister so condoms forasmuch as figurant remedy during the preceding sidereal http://www.capitalassets.com.ng year. The risks jack up the longer her are beginning. The very thing allows a softer sex up to exit in virtue of the behavioral science — outside of other self increases the sawbones risks and how eternity ego foulness remains at the nursing home.

As long as there is a rather most remote possibility as respects deficiency in despite of this doings except for by means of omnipresent abortion and the therapeusis lost slammer vocation fell noble birth defects, I myself requirement have place enthusiastic versus argue an abortion if the abortion butt fails. Windward Havings The new high second-best lineaments consumer goods are regurgitation, necrosis and diarrhoea. The apprehend and risks concerning an abortion caused passing by Misoprostol are proximate toward those in reference to a simple misidentification.

Buy Cytotec For 24 Week Abortion

If the cramps are unquestionable deplorable, other self disemploy habit pattern Ibuprofen, charge a bind the bottle gold steam heat benumb, albeit au contraire opium fess point drugs. The penance since this depends onward which resplendence subconscious self charged ingoing, simply sack drag concentrative fines and chokey sentences.

Suporte à BSON no ASP.NET Web API

Já há algum tempo trabalhamos com o formato JSON por ser mais leve e menos verboso quando comparado ao XML, e em tempos onde aplicativos Web estão cada vez mais em evidência, acaba sendo um formato mais simples de lidar quando a manipulação acontecerá através de uma linguagem como o Javascript.

Enquanto as informações retornadas são apenas dados simples (strings, inteiros, decimais, etc.), na maioria das vezes, tudo funciona como esperado, ou seja, com uma boa performance e um conteúdo bem enxuto é trafegado entre as partes (cliente e servidor). O problema começa a acontecer quando precisamos, de alguma forma, retornar informações mais complexas e pesadas, tais como uma informação binária, e aqui, podemos incluir qualquer tipo delas, como por exemplo, uma imagem.

Eis que entra em cena um formato chamado de BSON (Binary JSON), que é uma variação do JSON mas que tem como finalidade serializar as informações em formato binário, otimizando este tipo de conteúdo para trafegar de forma mais reduzida e, consequentemente, mais rápida. Pelo fato de tipos numéricos serem codificados como números e não como strings, a codificação e decodificação é mais eficiente, e além disso, conteúdos binários não precisam ser codificados em Base64, que torna o tamanho da mensagem muito maior do que o normal.

A partir da versão 2.1 do ASP.NET Web API, a Microsoft incluiu um novo formatador chamado BsonMediaTypeFormatter, que pode ser utilizado tanto do lado do servidor quanto do lado do cliente (através do HttpClient), que encapsula a serialização neste formato. Para fazer uso deste novo formatador do lado do servidor, basta acoplá-lo à coleção de formatadores do ASP.NET Web API, através da configuração que está no arquivo Global.asax:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//…

config.Formatters.Add(new BsonMediaTypeFormatter());
}
}

Este formatador opera através do mime type application/bson, e através da negociação de conteúdo que o ASP.NET Web API já suporta, ele acaba sendo capaz de gerar o resultado no formato escolhido pelo cliente. Para que seja possível perceber a sua funcionalidade, vamos recorrer à um exemplo que retorna uma imagem (através de um array de bytes) e poderemos visualizar a diferença entre os resultados que são retornados para o cliente através das imagens extraídas do Fiddler. Note que a primeira imagem utiliza JSON e a segunda BSON, que por sua vez, tem uma melhora de cerca de 25%.

Compressão no .NET Framework 4.5

Há algum tempo, eu falava aqui sobre compressão de arquivos no .NET Framework. Temos à disposição as classes GZipStream e DeflateStream para manipular arquivos, ou melhor, conteúdos que necessitam ser compactados ou descompactados utilizando estes dois algoritmos (Deflate e GZip).

Apesar de funcionar em alguns cenários, é um pouco difícil trabalhar em situações mais comuns quando precisamos lidar com (des)compactação. Um exemplo típico é quando precisamos compactar um diretório todo, ou múltiplos arquivos em um único arquivo *.zip. Além disso, toda a manipulação precisa ser realizada através do uso de streams, ou seja, temos que lidar com a alocação e cópia dos bytes entre a origem e o destino.

Como as operações comuns são as mais complicadas de serem utilizadas, recorremos à frameworks externos, como é o caso do SharpZipLib, que fornece várias funcionalidades interessantes acerca da utilização de ZIPs. Finalmente, a partir da versão 4.5 do .NET Framework, a Microsoft incluiu novas classes que visa facilitar a manipulação destes tipos de arquivos em aplicações .NET.

Apesar dos novos tipos estarem debaixo do namespace System.IO.Compression, eles são fornecidos através da referência de novos assemblies que fazemos em nossas aplicações: System.IO.Compression.dll e System.IO.Compression.FileSystem.dll. O primeiro assembly fornece os tipos de mais baixo nível para trabalhar com ZIP; já as classes disponíveis dentro do segundo assembly, temos apenas alguns utilitários (classes estáticas) que tornam ainda mais fácil a geração e consumo de ZIPs pela aplicação.

A primeira classe que vamos falar é a ZipArchive, que corresponde a um pacote de arquivos comprimidos, que pode ser um ou N arquivos. Para cada conteúdo (arquivo) dentro do ZipArchive, existe uma classe que o descreve: ZipArchiveEntry. E como já era de se esperar, a classe ZipArchive fornece uma propriedade chamada Entries, que retorna a coleção de entradas, e podemos notar isso na imagem abaixo:

A classe ZipArchiveEntry não é criada diretamente, ou seja, através de um construtor público. A primeira opção para a sua criação, é através do método CreateEntry da classe ZipArchive, que recebe como parâmetro o nome da entrada, e que muitas vezes, se você estiver compactando um arquivo, o nome da entrada pode refletir o nome do arquivo que está sendo inserido.

No exemplo abaixo, abrimos a conexão com um arquivo de destino via FileStream. Esse arquivo será o arquivo compactado, ou seja, as entradas criadas serão colocadas nele. O stream que aponta para o arquivo Dados.zip, é passado no construtor da classe ZipArchive, e logo em seguida, percorremos os arquivos do diretório C:Temp, onde para cada arquivo, criamos uma entrada dentro do ZipArchive. Por fim, copiamos o conteúdo do arquivo da origem para o destino, ainda operando com streams. O código abaixo ilustra este trabalho:

using (var output = new FileStream(“Dados.zip”, FileMode.Create))
using (var archive = new ZipArchive(output, ZipArchiveMode.Create))
    foreach (var filename in Directory.GetFiles(@”C:Temp”))
        using (var source = File.Open(filename, FileMode.Open))
        using (var destination = archive.CreateEntry(Path.GetFileName(filename)).Open())
            source.CopyTo(destination);

Ao rodar esse código, efetuamos a compactação de todos os arquivos que estão no diretório C:Temp. Para os testes, existem dois arquivos neste diretório, totalizando cerca de 11 MB. E depois de serem compactados, e colocados no arquivo Dados.zip, o valor cai para 316 KB, assim como podemos perceber através da imagem abaixo:

Como comentei acima, com o intuito de facilitar ainda mais a criação de conteúdo compactado, vamos reescrever este código utilizando um novo método de estensão, chamado CreateEntryFromFile, que dado o arquivo de origem e o nome da entrada, ele automaticamente cria a mesma, já copiando todo o conteúdo para dentro dela. Vemos que o código fica mais simples ao utilizar essa opção:

using (var output = new FileStream(“Dados.zip”, FileMode.Create))
using (var archive = new ZipArchive(output, ZipArchiveMode.Create))
    foreach (var filename in Directory.GetFiles(@”C:Temp”))
        archive.CreateEntryFromFile(
            filename,
            Path.GetFileName(filename),
            CompressionLevel.Optimal);

E para facilitar ainda mais, temos um método estático disponível através da classe ZipFile, chamado CreateFromDirectory, que dado o endereço do diretório e o caminho para o arquivo de destino, ele já cria as entradas para cada arquivo, copia o conteúdo e, finalmente, gera o arquivo compactado. Por fim, em uma única linha, conseguimos reescrever os mesmos códigos que vimos acima:

ZipFile.CreateFromDirectory(@”C:Temp”, @”C:Dados.zip”);

Este método ainda fornece um overload, que além de permitir informar o nível da compactação, recebe um boleano, indicando se a pasta que está sendo compactada, deve ou não ser incluída como raiz do arquivo compactado. Abaixo, as imagens mostram quando utilizamos true, e logo na sequência, false, para este parâmetro:

ZipFile.CreateFromDirectory(
            @”C:Temp”,
            @”C:Dados.zip”,
            CompressionLevel.Optimal,
            true);

A extração do arquivo compactado para os arquivos isolados, são trabalhados de forma semelhante. E da mesma forma que na compactação, a descompactação também fornece alguns métodos utilitários que podem ser utilizados para realizar a extração dos arquivos que estão dentro do arquivo *.zip. Para exemplificar, no código abaixo, fazemos o uso do método estático ExtractToDirectory, exposto pela classe ZipFile. Este método recebe como fonte, o arquivo compactado, e o segundo parâmetro, corresponde ao caminho onde queremos extrair todo o conteúdo:

ZipFile.ExtractToDirectory(@”C:Dados.zip”, @”C:Output”);

Compressão em Serviços WCF 4.5

Serviços WCF que são hospedados no IIS sempre puderam usufruir da compactação de mensagens, já que bastar habilitar, pois o próprio servidor fornece este recurso. Serviços que são hospedados em seu próprio servidor (self-hosted), como é o caso de aplicações Windows (Windows Forms, WPF, Console ou Windows Service), precisam de um trabalho extra, que consiste em criar um message encoder customizado para isso. Inclusive uma implementação padrão é fornecida no pacote de demonstrações oferecidos pela própria Microsoft.

A partir do WCF 4.5, nós teremos esse recurso nativamente, ou seja, o codificador binário (BinaryMessageEncoding) passa a fornecer uma propriedade chamada CompressionFormat, que determina o formato da compressão, podendo escolher entre GZip, Deflate ou None. Como essa é uma propriedade fornecida pelo encoder, temos que customizar a criação da binding, para que assim tenhamos acesso à propriedade que define o padrão da compressão. O código abaixo ilustra a criação deste binding, e logo na sequência, temos a mesma configuração, só que através do modelo declarativo (via arquivo de configuração):

var binding = 
    new CustomBinding
    (
        new BinaryMessageEncodingBindingElement()
        {
            CompressionFormat = CompressionFormat.GZip
        },
        new HttpTransportBindingElement()
    );

<customBinding>
  <binding name=”BinaryCompressionBinding”>
    <binaryMessageEncoding compressionFormat =”GZip”/>
    <httpTransport />
  </binding>
</customBinding>

Se interceptarmos a requisição para um serviço sem qualquer configuração de compactação, enviando uma string com 5000 caracteres, temos a requisição abaixo (removendo alguns elementos por questões de espaço):

POST http://127.0.0.1:9291/srv HTTP/1.1
Content-Type: application/soap+msbin1
Host: 127.0.0.1:9291
Content-Length: 5157
Accept-Encoding: gzip, deflate

Agora, se optarmos pelo modelo de compactação GZip, ao analisarmos a requisição para o mesmo serviço, podemos reparar que a quantidade de bytes trafegados é bem menor quando comparado à primeira requisição:

POST http://127.0.0.1:9291/srv HTTP/1.1
Content-Type: application/soap+msbin1+gzip
Host: 127.0.0.1:9291
Content-Length: 185
Accept-Encoding: gzip, deflate

Apesar de um ganho significativo, é importante avaliar corretamente o ambiente em qual o serviço será disponibilizado. Enquanto a compactação é interessante quando o gargalo é a rede, a mesma exige muito mais da CPU para realizar o processo de compactação e descompactação. Sendo assim, o melhor é analisar e realizar alguns testes, e mensurar o que realmente importa durante a execução no ambiente de produção.