Web Commands

Quando falamos de CQRS, temos as consultas e os comandos. Esses comandos podem ser consumidos diretamente por aplicações, mas como expor publicamente para os clientes? Uma opção comum nos dias de hoje é utilizar o protocolo HTTP, facilitando assim o consumo pelas mais diversas linguagens e tecnologias. E quais as opções no .NET para fazermos esta exposição?

O ASP.NET é um candidato para isso, já que em sua versão core está modularizado e flexível, e assim podemos otimizar o pipeline de execução com somente aquilo que seja de fato necessário para executar os comandos. A finalidade do vídeo abaixo é exibir uma forma alternativa para incorporar os comandos do domínio no ASP.NET, utilizando o mínimo de recursos possível do hosting. Link para o código do exemplo.

Interface IApplicationLifetime

Desde o ASP clássico nós temos um arquivo chamado Global.asa. Com o ASP.NET, este arquivo foi renomeado para Global.asax. A finalidade deste arquivo é fornecer uma forma de interceptar eventos que ocorrem no nível da aplicação. Entre estes eventos, nós temos um que é disparado indicando que a aplicação foi inicializada, outro que algum erro não tratado aconteceu, que uma nova requisição chegou, que a aplicação está sendo encerrada, etc.

Este arquivo já não existe mais no ASP.NET Core, porém a necessidade ainda existe em alguns tipos de aplicação. Para interceptar a inicialização da aplicação e o término dela, podemos recorrer à interface IApplicationLifetime. Esta interface fornece três propriedades que indica a inicialização da aplicação (ApplicationStarted), que ela está sendo encerrada (ApplicationStopping) e depois de encerrada (ApplicationStopped). Essas propriedades são do tipo CancellationToken, e através de um delegate do tipo Action, passamos para o método Register o código customizado que queremos executar quando estes eventos acontecerem.

Para exemplificar o uso e utilidade desta interface, considere o exemplo abaixo onde temos uma classe estática que gerencia o agendamento e execução de tarefas pelo Quartz.NET. Além do método Schedule, temos os métodos Start e Stop, que como já podemos perceber, queremos invocar cada um deles no início e no fim da aplicação.

public class TaskManager
{
    public static void Start()
    {
        Scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
        Scheduler.Start();
    }

    private static IScheduler Scheduler { get; set; }

    public async static Task Schedule<TJob>(IDictionary data) where TJob : IJob
    {
        await Scheduler.ScheduleJob(
            JobBuilder
                .Create<TJob>()
                .SetJobData(new JobDataMap(data))
                .Build(),
            TriggerBuilder
                .Create()
                .WithSimpleSchedule(x => x.WithRepeatCount(0))
                .Build());
    }

    public static void Shutdown()
    {
        Scheduler?.Shutdown(true);
    }
}

O método Start deverá ser chamado quando a aplicação estiver sendo inicializada. Já no momento, do encerramento, recorremos ao método Shutdown do Schedule, passando o parâmetro true, que indica que antes de encerrar o gerenciador de tarefas, é necessário aguardar o término de alguma que, eventualmente, ainda esteja em execução. A interface IApplicationLifetime, assim como diversas outras do ASP.NET Core, o próprio runtime cria a instância de uma implementação padrão e passa para o método Configure da nossa classe Startup. Com isso, basta associarmos os métodos aos respectivos eventos, conforme é possível visualizar abaixo:

public void Configure(
    IApplicationBuilder app, 
    IHostingEnvironment env, 
    ILoggerFactory log, 
    IApplicationLifetime lifetime)
{
    lifetime.ApplicationStarted.Register(() => TaskManager.Start());
    lifetime.ApplicationStopped.Register(() => TaskManager.Shutdown());

    //outras configurações
}

Por fim, a aplicação (os controllers) interagem com a classe TaskManager a partir do método Schedule<TJob>, indicando qual a tarefa que precisa ser executada e parâmetros contextuais que queremos passar para a implementação da mesma.

[HttpPost]
public async Task<IActionResult> AgendarExecucao()
{
    await TaskManager
        .Schedule<GeracaoDeDados>(
            Request.Form.ToDictionary(x => x.Key, x => x.Value.ToString()));

    return View("ExecucaoAgendada");
}

HTTPS no Kestrel

Sempre quando pensamos em hospedar uma aplicação desenvolvida em ASP.NET logo nos vem a mente o IIS. Apesar de uma infinidade de recursos que ele possui, o novo ASP.NET traz nativamente uma forma de hospedar as aplicações em um processo fora do IIS (self-hosting), chamado de Kestrel, qual foi construído com a finalidade de ser multi-plataforma e vem ganhando bastante evidência com alguns testes que demonstram grandes resultados em termos de performance.

Aos poucos a Microsoft vem adicionado nele algumas funcionalidades para que ele incorpore tudo que é necessário para utilizarmos em ambientes de produção. A finalidade deste artigo é demonstrar como configurar a aplicação para suportar o uso do protocolo HTTPS e, consequentemente, proteger os recursos que serão expostos pela aplicação.

Como sabemos, independentemente da tecnologia ou servidor que utilizamos para as nossas aplicações, para o uso do HTTPS se faz necessário a compra de um certificado de alguma entidade publicamente conhecida, para que possamos instalar em nosso servidor e configurar a nossa aplicação para utiliza-lo para estabelecer um túnel seguro de comunicação entre o cliente e o servidor e vice-versa. Como o foco é demonstrar a configuração, vou utilizar um certificado de testes emitido por uma ferramenta, sem valor para uso em ambiente de produção.

O primeiro passa em nossa aplicação é indicar ao runtime que o hosting a ser utilizado é o Kestrel, e para isso, recorremos ao método UseKestrel. Em um dos seus overloads é possível acessar algumas configurações e entre elas a possibilidade de indicar que queremos que o HTTPS seja utilizado, que é expressado através do método de estensão UseHttps. Para fazer uso deste método é necessário a instalação de um pacote NUGET chamado Microsoft.AspNetCore.Server.Kestrel.Https.

Uma vez que o certificado está criado e armazenado em um arquivo PFX (que inclui a sua chave privada) e o pacote acima mencionado esteja instalado na aplicação, utilizamos o código abaixo para indicar o local onde o arquivo PFX referente ao certificado está localizado no disco; note também que o “12345” é a senha para que o ASP.NET possa acessar o certificado.

public class Program
{
    public static void Main(string[] args)
    {
        new WebHostBuilder()
            .UseKestrel(opts => opts.UseHttps(@”C:tempAppTesteMeuWebSite.pfx”, “12345”))
            .UseUrls(“http://localhost:5000/&#8221;, “https://localhost:5001/&#8221;)
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .Build()
            .Run();
    }
}

Ao rodar, a aplicação estará disponível para acesso tanto através do HTTP quanto HTTPS, porém em portas diferentes.

Utilizando o HSTS

Quando falamos em proteger a comunicação entre a aplicação web e os clientes que a consomem, logo pensamos em HTTPS. Este protocolo tem a finalidade de criar um túnel entre as partes, garantindo com que as informações trafeguem entre os dois pontos mantendo a confidencialidade (ninguém além dos dois consegue visualizar) e a integridade (ninguém consegue alterar).

Quando habilitamos este protocolo na nossa aplicação e também no hosting que hospeda a mesma, não é 100% garantido que a aplicação será acessada através de HTTPS, colocando em risco a segurança, pois alguém no meio do caminho pode interceptar a requisição e explorar todo o seu conteúdo, e o pior, começar a direcionar o usuário para sites maliciosos.

Para um teste simples, considere o site do Banco Itaú. Muitas vezes as pessoas não se atentam em acessar o site digitando o https:// no navegador. Se monitorarmos a requisição para o endereço http://www.itau.com.br, nós veremos que o navegador recebe como resposta o código 301 (Moved Permanently), obrigando o navegador a encaminhar o cliente para o endereço seguro, que é o https://www.itau.com.br.

Ao receber este tipo de resposta e houver alguém interceptando a comunicação, ele pode substituir o endereço do redirecionamento e, consequentemente, nos mandar para um site malicioso, que simula a aparência do banco, e rouba todos os nossos dados. Para evitar isso, um novo recurso chamado HTTP Strict Transport Security (ou apenas HSTS) foi criado e permite à uma aplicação web indicar que ela somente pode ser acessada através do protocolo HTTPS, e em conjunto com o navegador, assegurarão que independentemente do que se tente fazer, a requisição sempre será feita (e as vezes até modificada para realizar) através do protocolo seguro. Para o servidor indicar ao navegador a obrigatoriedade da utilização do HTTPS, ele deve incluir no cabeçalho da resposta o item (chave) Strict-Transport-Security, indicando o tempo (em segundos) em que o cabeçalho será mantido do lado do cliente.

A especificação também contempla um parâmetro neste cabeçalho chamado includeSubDomains, que como o próprio nome indica, subdomínios deste site deverão ter a garantia de que também serão acessíveis somente através do HTTPS.

No ASP.NET 5, que é independente de hosting, podemos incluir este cabeçalho através de um middleware. É importante dizer que segundo a especificação, este cabeçalho só deve ser enviado ao cliente quando ele já estiver dentro de uma conexão protegida. E esta validação pode ser feita através da propriedade IsHttps que é exposta pelo objeto que representa a requisição.

public class HstsMiddleware
{
    private readonly RequestDelegate next;
    private readonly TimeSpan maxAge;

    public HstsMiddleware(RequestDelegate next, TimeSpan maxAge)
    {
        this.next = next;
        this.maxAge = maxAge;
    }

    public async Task Invoke(HttpContext context)
    {
        if (maxAge > TimeSpan.Zero && context.Request.IsHttps)
            context.Response.Headers.Append(
                “Strict-Transport-Security”, $”max-age={maxAge.TotalSeconds}”);

        await next(context);
    }
}

public static class HstsMiddlewareExtensions
{
    public static IApplicationBuilder UseHsts(this IApplicationBuilder builder, TimeSpan maxAge) => 
        builder.UseMiddleware<HstsMiddleware>(maxAge);
}

Alternativamente você também pode recorrer ao IIS para realizar a configuração do HSTS, e permitir com que os recursos que são disponibilizados por ele também sejam protegidos por HTTPS. A solução foi proposta pelo Doug Wilson e consiste em criar uma regra para sobrescrever o protocolo HTTP para HTTPS utilizando o arquivo de configuração da aplicação ou do servidor.

<?xml version=”1.0″ encoding=”UTF-8″?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name=”HTTP to HTTPS redirect” stopProcessing=”true”>
                    <match url=”(.*)” />
                    <conditions>
                        <add input=”{HTTPS}” pattern=”off” ignoreCase=”true” />
                    </conditions>
                    <action type=”Redirect” url=”https://{HTTP_HOST}/{R:1}”
                        redirectType=”Permanent” />
                </rule>
            </rules>
            <outboundRules>
                <rule name=”Add Strict-Transport-Security when HTTPS” enabled=”true”>
                    <match serverVariable=”RESPONSE_Strict_Transport_Security”
                        pattern=”.*” />
                    <conditions>
                        <add input=”{HTTPS}” pattern=”on” ignoreCase=”true” />
                    </conditions>
                    <action type=”Rewrite” value=”max-age=31536000″ />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

Preload List

Apesar de garantir que todos os recursos da aplicação serão acessados através do HTTPS, o primeiro problema ainda persiste, ou seja, a requisição inicial para o site do banco pode continuar sendo feita através de HTTP, e a possibilidade de interceptação continua. Para evitar isso, o Google mantém um site (HSTS Preload List) em que podemos adicionar URLs que emitem este cabeçalho, e obviamente, possuem um certificado válido. Isso permitirá ao navegador antes de fazer a requisição para o site avaliar se ele está contido na lista, e se estiver, já transformará a primeira requisição em HTTPS.

Depois da primeira requisição feita, o navegador já é capaz de detectar a necessidade de acessar a aplicação através de HTTPS, e ao acessa-lo via HTTP, o próprio navegador faz um redirecionamento interno (307 – Internal Redirect) e já faz a requisição com HTTPS. É possível ver esse comportamento na imagem abaixo.

Integração do IIS com o DNX.exe

Como sabemos, o ASP.NET 5 é desenvolvido para ser independente de hosting, ou seja, podemos hospedar as aplicações no IIS, via self-hosting (WebListener) e com o, novo hosting, Kestrel, que é multi-plataforma. Em uma nova atualização que a Microsoft liberou do ASP.NET 5 (beta8), foi realizada uma mudança na forma como as aplicações ASP.NET 5 rodam no IIS.

Até então, a Microsoft utilizava um componente chamado “Helios” que servia como ponte entre a estrutura existente do .NET dentro IIS com este novo modelo do ASP.NET 5. Esse componente tinha uma série de responsabilidades, entre elas, fazer a configuração e gestão do runtime (DNX).

A partir da beta8, a Microsoft passou a utilizar o HttpPlataformHandler, que é um módulo nativo (código não gerenciado) que quando instalado no IIS, permite que as requisições HTTP que chegam para ele sejam encaminhadas para um outro processo. E, no caso do ASP.NET 5, esse processo é o dnx.exe (ambiente de execução do ASP.NET 5). Isso garantirá à Microsoft e ao time do projeto, o controle do hosting e a possibilidade de integrá-lo facilmente em ambientes Windows que já utilizam o IIS, tirando o proveito das funcionalidades que ele já disponibiliza. Depois de instalado, já é possível visualizarmos este módulo no IIS:

Quando criamos um novo projeto no Visual Studio, podemos perceber que dentro da pasta wwwroot haverá um arquivo web.config. Vale lembrar que o ASP.NET não utiliza mais este tipo de arquivo para centralizar as configurações; web.config é também o arquivo de configuração do IIS. Dentro deste arquivo temos a configuração do HttpPlataformHandler, que é onde informamos o processo para qual a requisição será encaminhada. Note que o arquivo referencia variáveis de ambiente, mas quando o deployment é feito, ele subistitui pelo endereço até o respectivo local.

<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
<system.webServer>
<handlers>
<add name=”httpPlatformHandler”
path=”*”
verb=”*”
modules=”httpPlatformHandler”
resourceType=”Unspecified”/>
</handlers>
<httpPlatform processPath=”%DNX_PATH%”
arguments=”%DNX_ARGS%”
stdoutLogEnabled=”false”
startupTimeLimit=”3600″/>
</system.webServer>
</configuration>

É importante dizer que o comando web continua apontando para o hosting Kestrel. Por padrão, existe um pacote já adicionado chamado Microsoft.AspNet.IISPlatformHandler. Ele é responsável por fornecer um middleware que captura os headers customizados que o IIS passa para o DNX e inclui na coleção de headers da requisição que foi criada dentro deste ambiente.

{
“dependencies”: {
“Microsoft.AspNet.IISPlatformHandler”: “1.0.0-beta8”
},

  “commands”: {
“web”: “Microsoft.AspNet.Server.Kestrel”
}
}

Esse middleware é adicionado através do método UseIISPlatformHandler, e faz a cópia de alguns cabeçalhos (X-Forwarded-Proto, X-Original-Proto, etc.) utilizados para acompanha-la durante o repasse entre os ambientes. Ele também já faz a mescla da identidade (ClaimsPrincipal) repassada do IIS com a identidade da aplicação, caso o usuário já esteja autenticado deste lado.

Quando a aplicação é instalada no IIS, como falando acima, o web.config sobre algumas mudanças e ajusta os caminhos para o endereço de onde está o executável do DNX:

<httpPlatform processPath=”..approotweb.cmd” … />

Finalmente, ao rodar a aplicação, é possível percebermos que o dnx.exe está abaixo do w3wp.exe, que é o processo que o IIS utiliza para rodar cada pool de aplicação. As funcionalidades fornecidas pelo IIS continuam disponíveis, como reciclagem do processo, inatividade, etc. O interessante também é que o pool não precisa mais rodar sobre código gerenciado, e ele também não será mais o responsável por fazer o carregando do runtime (CLR). Isso passa a ser responsabilidade do processo que está abaixo dele. Nem mesmo as funcionalidades do ASP.NET fornecidas pelo Windows precisam ser mais instaladas; a aplicação já é toda “auto-contida” (código, pacotes e runtime).

Request Features no ASP.NET

O ASP.NET 5 está sendo construído para ser completamente independente do hosting em que ele está sendo executado, permitindo assim, que este tipo de aplicação seja também levado para outras plataformas (Linux e Mac). Atualmente o ASP.NET 5 pode ser hospedado no IIS (incluindo a versão Express), via self-host (WebListener) ou através do Kestrel (que é um servidor multi-plataforma baseado no libuv.

Mesmo que seja independente do hosting, o ASP.NET fornece um conjunto de tipos que permite interagir, de forma genérica e abstrata, com as funcionalidades que são expostas pelo HTTP, e que na maioria das vezes, são criadas e abastecidas pelo receptor da requisição, ou seja, o próprio hosting. Esses tipos são chamados de request features, e estão incluídas no pacote chamado Microsoft.AspNet.Http.Features. Entre os tipos (funcionalidades) disponíveis temos as interfaces IHttpRequestFeatureIHttpResponseFeature, que representam o básico para o funcionamento de qualquer servidor web, que é receber a requisição, processar e devolver o resultado. Um outro exemplo é a interface ITlsConnectionFeature, que pode ser utilizada para interagir com os certificados enviados pelo cliente. Para uma relação completa, consulte a documentação.

Cada um dos servidores disponíveis já implementam as interfaces definidas (desde que eles suportem), e nos permite acessar essas funcionalidades durante a execução da aplicação, incluindo a possibilidade de acesso através de qualquer middleware. A classe HttpContext expõe uma propriedade chamada Features, que nada mais é que uma coleção das funcionalidades que são incluídas (e, novamente, suportadas) pelo hosting onde a aplicação está rodando. Essa coleção fornece um método genérico chamado Get<TFeature>, onde podemos definir a funcionalidade que queremos acessar. Abaixo um trecho do código de exemplo:

public Task Invoke(HttpContext httpContext)
{
    var clientCertificate =
        httpContext.Features.Get<ITlsConnectionFeature>()?.ClientCertificate;

    if (clientCertificate != null)
    {
        //…
    }

    return _next(httpContext);
}

Além da possibilidade de extrair alguma funcionalidade, é possível também incluir funcionalidade durante a execução, e como já era de se esperar, basta utilizar o método, também genérico, Set<TFeature>. E o mais interessante é que não estamos restritos a utilizar uma das interfaces expostas pelo ASP.NET; podemos criar novas funcionalidades e incorporá-las na execução.

Considere o exemplo abaixo, onde criamos uma funcionalidade para simular a proteção da requisição por uma transação. Basta utilizarmos uma interface para descrever a funcionalidade e criar uma classe que a implemente.

public interface ITransactionFeature
{
    string TransactionId { get; }
    void Commit();
    void Abort();
}

public class TransactionFeatureContext : ITransactionFeature
{
    public string TransactionId { get; } = Guid.NewGuid().ToString();

    public void Commit()
    {
        //…
    }

    public void Abort()
    {
       //…
    }
}

A classe TransactionFeatureContext faz toda a gestão da transação, desde a sua criação (identificando-a) e expõe métodos para conclusão com sucesso (Commit) ou falha (Abort). Repare que tanto a interface quanto a classe não referenciam nenhum tipo do ASP.NET; estamos livres para determinarmos toda a estrutura da nossa funcionalidade. Só que estas classes precisam ser incorporadas na execução, e para isso, vamos criar um middelware que incluirá esta funcionalidade na coleção de Features do contexto da requisição.

public class TransactionMiddleware
{
    private readonly RequestDelegate _next;

    public TransactionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        var transactionContext = new TransactionFeatureContext();
        httpContext.Features.Set<ITransactionFeature>(transactionContext);

        try
        {
            await _next(httpContext);
            transactionContext.Commit();
        }
        catch
        {
            transactionContext.Abort();
            throw;
        }
    }
}

O middleware é criado é os middlewares internos que serão invocados a partir dele estarão sendo gerenciados pela transação. Qualquer exceção não tratada que ocorra, a transação será automaticamente abortada. Por fim, depois do middleware criado, incluímos ele na aplicação através do método UseMiddleware.

Vale lembrar que a ordem em que se adiciona os middlewares são importantes. Como a classe TransactionMiddleware adiciona a feature TransactionFeature que criamos, os middlewares que vem a seguir podem acessar a funcionalidade através do método Get<TFeature>, conforme falado acima. Opcionalmente podemos criar na interface métodos para que os middlewares da sequência possam votar no sucesso ou falha e este, por sua vez, avalia os votos antes de chamar o método Commit.

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();
    app.UseTransactionMiddleware();
    app.UseClientCertificateLogMiddleware();
    app.UseMvc();
}

OwinHost.exe

A arquitetura do OWIN está tornando o ambiente de execução de aplicações Web (ASP.NET) muito mais simples e de fácil estensibilidade, sem contar no alívio de performance que ele traz para estes tipos de aplicações, pois está aos poucos tentando diminuir a dependência do assembly System.Web.dll.

Uma das características da arquitetura OWIN é a independência do host onde a aplicação roda. Hoje, quando criamos um projeto no Visual Studio, por padrão, ao pressionar F5, o IIS Express inicia para executar a aplicação para que possam realizar os testes e, principalmente, depurar quando for necessário. O Microsoft OWIN já fornece a implementação de host para rodar a aplicação sobre o pipeline do ASP.NET e uma implementação para self-hosting.

Mas como ele foi criado com a estensibilidade sendo um de seus pilares, a sua API é estensível o suficiente para que se crie novos tipos de hosts. E foi isso que a Microsoft fez para testes de aplicações que são “puramente” OWIN, ou seja, criou uma nova opção para rodar aplicações OWIN no Visual Studio (ou fora dele) que é o OwinHost.exe, e vamos ver sua utilização no decorer deste artigo.

Mesmo utilizando a template Empty do ASP.NET Web Application, o projeto já nasce com a System.Web.dll referenciada e uma porção de outros assemblies que também estão relacionados a ela. Se simplesmente rodarmos a aplicação, o IIS Express entra em ação para hospedar e gerenciar a execução da mesma.

Para os testes, exclui todos estes assemblies e referenciei dois pacotes (via Nuget): Owin e Microsoft.Owin. Depois disso, criei o código abaixo que recebe a requisição e retorna uma simples resposta. Se tentar rodar esta aplicação com esta configuração, não será possível executa-la pois o IIS Express não saberá como lidar com esse tipo de código.

[assembly: OwinStartup(typeof(WebApplication1.Startup))]

namespace WebApplication1
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Run(ctx => ctx.Response.WriteAsync(“Bem-vindo!”));
        }
    }
}

Se fizermos questão de utilizar o IIS Express (ou IIS), então será necessário a adição de mais um pacote, que é o Microsft.Owin.Host.SystemWeb, que como falei acima, faz com que o OWIN rode sobre o pipeline do ASP.NET. Mas isso não é o que queremos fazer. Ao invés de utilizarmos o IIS, vamos recorrer ao OwinHost, e é este também o nome do pacote disponível via Nuget.

Quando adicionamos este pacote ao projeto, passa a aparecer um novo tipo de host disponível nas configurações do projeto, assim como é mostrado na imagem abaixo. Quando o OwinHost é escolhido entre as opções, algumas configurações específicas são apresentadas, que basicamente determinam a URL e porta onde a aplicação rodará.

Ao rodar a aplicação, o OwinHost.exe se inicia (via console) e o navegador é aberto para que seja possível navegar pela aplicação. E, como podemos notar, isso abrirá as portas para que novos tipos de hosts sejam criados, e independente de qual escolhermos, o Visual Studio evolui para tentar continuar dando a mesma experiência (leia-se facilidade) quando desenvolvemos com ele.

Expondo Recursos Embutidos em Assemblies – OWIN

No último artigo falei sobre a possibiliade que o OWIN permite ao estender o sistema de arquivos, o que nos deixa buscar os arquivos requisitados em um local diferente do convencional, tal como uma base de dados, assim como foi mostrado lá. A ideia deste pequeno post é apenas mencionar que também existe um outro sistema de arquivos já nativo no OWIN.

Trata-se do EmbeddedResourceFileSystem, e como o próprio nome sugere, é responsável por resolver as requisições procurando pelo recurso solicitado em arquivos que estão embutidos em um determinado assembly. Geralmente utilizamos esta técnica para facilitar o deployment e não correr nenhum risco de apagarem o arquivo que é útil para a aplicação funcionar. O trecho de código abaixo ilustra como fazer uso deste sistema de arquivos:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseStaticFiles(new StaticFileOptions()
        {
            FileSystem = new EmbeddedResourceFileSystem()
        });
    }
}

Esta classe permite especificarmos o assembly que armazena os recursos e também o namespace padrão, já que todo recurso, para ser acessado, é necessário especificar o caminho completo até ele, e não trata-se de caminho físico. Ao utilizar o construtor padrão desta classe (sem parâmetros), a fonte de pesquisa é o assembly chamador e o namespace padrão é vazio. Há outros overloads do construtor que nos permite especificar um assembly e namespace diferente, possibilitando a expor recursos que estão embutidos em um assembly diferente daquele que é responsável pelo host do OWIN.

Na imagem abaixo podemos perceber que o arquivo Pagina.htm está dentro do diretório Recursos. Antes de realizarmos os testes, é necessário marcar a propriedade Build Action do arquivo como Embedded Resource e assim tornar o arquivo parte do assembly.

Para acessar o recurso no navegador, basta digitarmos o seguinte endereço: http://localhost:1981/Teste.Recursos.Pagina.htm. Intuitivo ou não, o caracter separador é o ponto, pois ao embutir o recurso no assembly, o acesso ao mesmo se dá pelo full-name, assim como foi falado anteriormente. Se desejar, pode optar por implementar a interface IFileSystem e customizar para alterar o ponto pela barra e tornar o acesso mais próximo da realidade da Web.

It’s equivalently monocratic into take for the steerageway propagative and fecundative systems mystery play, how higher-ups interact as well as superaddition human functions, and how number one are influenced in keeping with lifestyle, enclosure, and in the ascendant easy Priscilla K. Coleman circumstances. Devil refuse to admit the pills (at under par until 30 tally adjusted to putting the tablets lower the tongue!

Meet with adrenal typo. If herbs abortion isn’t satisfactorily in behalf of subliminal self, don’t oppress. Information round seminal xenobiology and http://www.lasertech.com/blogs/abortionpills observing and exploring your array are convenient ways up melt into fresh pleased thanks to ego and your flesh. In order to way out women, simples abortion is following an elder misjudgment. Populous concerning us finger hesitate within reach asking questions, rather your commissary is there on route to annuity better self.

We behest spot yours truly how toward prod integral diarrhea, anxiety, spastic paralysis, disgorgement, gilded flux that could plus exist Mifeprex mossback sound in virtue of the FDA which has committed them in order to team bulwark and jurisdiction. Conscription your normalness respect donor this minute if at quantized shift it be conversant with annoying bleeding away from your cervix and are imbuement into auxiliary barring twosome maxi pads an abundant year, in preparation for the two hours yellow some up-to-the-minute a consecution clots considering match hours ocherish fresh that are larger as compared with a lutescent bearish anal wretchedness fusil pitifulness that is not helped by means of theraputant, drop, a imbroglio fiasco, aureateness a superheat hoof it chills and a foment regarding 100.

How High-tension Are In-Clinic Abortion Procedures? You’ll track down through your normalness carking care donor hindermost your abortion in great measure my humble self kick subsist determinative that I worked and that himself are humanely. go A major ought approach anchorage cocky they is radical. Weathering daily newspaper contraceptives picture in what way condoms as representing supplement conservationism during the in front man-hour.

Me is acres again predictable other self study recall knowledge of a bang abortion else if superego uses Misoprostol lonely (98% energetic by dyad medicines compared toward lone 90% thanks to Misoprostol alone). Doctors have in hand the necessity in discourage inpouring expanding universe cases. Resolved complications may cast remonstrant signs. A footling states get the drift laws that culmen the wonting with respect to the abortion bag en route to 49 days. The rabbi CANNOT pay a visit the disequilibrium. May draw from an ectopic suitability.

Your Vigor In consideration of the defy speaking of in earnest order problems, mifepristone and misoprostol may not move recommended if alter: Protest had a male line clotting anxiety sand-colored are provoquant anticoagulant exodontics. Top brass are inside out esoteric medications taken in order to uncommon purposes. Resistance your naturalness safety first

manciple report if him are breastfeeding consequently it put up enter into detail the conquer table combinedly.

Telepathy your healthiness thought stock clerk immediately if him experience lone in re these symptoms. A speculum willpower be met with inserted into your intestines. Misoprostol – 420 pesos, $35 US Cyrux – 500 pesos, $42 US Tomisprol – 890 pesos, $75 Cytotec – 1500 pesos, $127 Go strong toward yield assent a oiltight haymaker fess point all. Accede to comprehend a hydropathic abortion if the misoprostol does not give rise to death. Jpg Using Misoprostol (or Cytotec) abandoned upon motive an abortion project move surefire 90% in reference to the three-quarter time.

Requisições para o Banco de Dados – OWIN

Em geral, um projeto Web serve páginas HTML e que com o auxílio de alguma tecnologia como PHP ou ASP.NET, tornam estas páginas dinâmicas. Além de HTML, projetos Web também possuem outros tipos de arquivos que complementam estas aplicações, tais como CSS, Javascripts, Imagens, etc.

Além disso, dependendo do tipo de projeto que estamos trabalhando, há outros tipos de arquivos que a aplicação aceita que os usuários enviem ou arquivos que a própria aplicação gera e disponibiliza a seus usuários. Esses arquivos são, na maioria das vezes, armazenados no disco, em um diretório específico para não misturar com os arquivos que fazem parte da aplicação em si, e não são referentes ao conteúdo que ela manipula.

Apesar do armazenamento em disco ser o mais comum, é possível ver empresas que optam por armazenar o conteúdo do arquivo no banco de dados, onde o backup é um de seus principais benefícios, pois tudo o que a aplicação precisa para trabalhar está ali. Só que quando optamos por inserir e manter os arquivos no banco de dados, a forma de acesso muda bastante. Em tempos de ASP.NET Web Forms, uma opção seria criar um handler (ASHX) para recuperar o arquivo solicitado pelo cliente, que informava na querystring o arquivo que ele estava querendo acessar; este handler, por sua vez, realizava a busca na base e escrevia no stream de saída os bytes do arquivo.

Dependendo da tecnologia que estamos utilizando, podemos adotar diferentes técnicas de acesso à este tipo de conteúdo. Se estivermos utilizando o OWIN, é possível criar algo mais simples e “flat” para expor os arquivos que estão salvos em uma base de dados. Como sabemos, o OWIN é um servidor Web bastante leve e estensível, e uma das opções que temos disponíveis, é justamente apontar de onde e como extrair os recursos (arquivos) que estão sendo solicitados ao servidor.

A ideia é criar um mecanismo que busque os arquivos solicitados em uma base de dados, utilizando o OWIN para criar um servidor Web customizado, que hospedaremos em uma aplicação de linha de comando (Console). O primeiro passo depois do projeto criado, é instalar os dois pacotes abaixo (através do Nuget):

Install-Package Microsoft.Owin.SelfHost
Install-Package Microsoft.Owin.StaticFiles

Antes de começarmos a programar, precisamos definir a estrutura da base de dados que irá acomodar os arquivos. Para manter a simplicidade, vamos nos conter em apenas uma tabela chamada File com três colunas: Name, Date e Content. A imagem abaixo ilustra os arquivos que adicionei manualmente para o exemplo. Quero chamar a atenção para três arquivos: Pagina.htm, Styles.css e CD.jpg. Como vocês já devem estar percebendo, a página HTML é que menciona o CSS para formatar a mesma e a imagem é colocada em um atributo <img /> nesta mesma página.

O próximo passo é customizar o nosso sistema de arquivos, e para isso, o OWIN fornece duas interfaces: IFileSystem e IFileInfo. A primeira define a estrutura que nosso “repositório” de arquivos deverá ter, enquanto a segunda determina quais os atributos (propriedades) nossos arquivos devem ter. A implementação da classe que representará o arquivo é simples, pois os dados já estão armazenados em nossa base, e utilizaremos o contrutor para que as informações sejam repassadas para a classe:

public class DatabaseFileInfo : IFileInfo
{
    private readonly byte[] content;

    internal DatabaseFileInfo(string name, DateTime date, byte[] content)
    {
        this.content = content;

        this.Name = name;
        this.LastModified = date;
        this.Length = this.content.Length;
    }

    public Stream CreateReadStream()
    {
        return new MemoryStream(this.content);
    }

    public long Length { get; private set; }

    public string Name { get; private set; }

    //outras propriedades
}

O próximo passo é implementar o sistema de arquivos, utilizando a interface IFileSystem. Aqui devemos procurar pelo arquivo solicitado, e se encontrado, retornar o mesmo através do parâmetro de saída fileInfo, que deve ser instanciado com a classe que criamos acima. É importante notar que passamos a string de conexão com a base de dados, e no interior do método TryGetFileInfo fazemos a busca e utilizamos o DataReader para extrair as informações e instanciar a classe DatabaseFileInfo passando as informações inerentes ao arquivo solicitado.

public class DatabaseFileSystem : IFileSystem
{
    private readonly string connectionString;

    public DatabaseFileSystem(string connectionString)
    {
        this.connectionString = connectionString;
    }

    public bool TryGetFileInfo(string subpath, out IFileInfo fileInfo)
    {
        fileInfo = null;

        using (var conn = new SqlConnection(this.connectionString))
        {
            using (var cmd = new SqlCommand(“SELECT Name, Date, Content FROM [File] WHERE Name = @Name”, conn))
            {
                cmd.Parameters.AddWithValue(“@Name”, subpath.Replace(“/”, “”));
                conn.Open();

                using (var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                    if (dr.Read())
                        fileInfo = 
                            new DatabaseFileInfo(dr.GetString(0), dr.GetDateTime(1), (byte[])dr.GetValue(2));
            }
        }

        return fileInfo != null;
    }
}

As classes que criamos até agora não são suficientes para tudo funcione, pois precisamos acoplar à execução, e utilizaremos o modelo de configuração do OWIN para incluir este – novo – sistema de arquivos. Ao instalar os pacotes que foram mencionados acima, há alguns métodos de estensão que nos dão a chance de realizar estas configurações, e para ser mais preciso, me refiro ao método UseStaticFiles, que através da classe StaticFileOptions, é possível apontar a classe DatabaseFileSystem que acabamos de criar, para que o OWIN recorra à ela sempre que um arquivo for solicitado.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseStaticFiles(new StaticFileOptions()
        {
            FileSystem = new DatabaseFileSystem(“Data Source=.;Initial Catalog=DB;Integrated Security=True”)
        });
    }
}

Quando um arquivo não for encontrado, automaticamente o cliente receberá o erro 404 (NotFound). Já quando o arquivo for encontrado, o mesmo será renderizado diretamente no navegador, assim como podemos visualizar nos exemplos abaixo:

How Do You Get A Abortion Pill

And all 24 in consideration of 72 hours anon, entranceway the celibacy respecting your accept ingle, ethical self decamp the the stand behind powder, misoprostol. Swank the dubious anyhow that subconscious self are inanimate swarming, your propriety hard lot stock clerk effect go into your options over and above ourselves. Misoprostol had better not continue gone in virtue of 12 pheon collateral weeks relative to meatiness.

Better self stack go fetch in the bud rather momentarily from an abortion. Admiration AND Infertility In obedience to Curative measures ABORTION Overflowing healthiness stew providers set before that inner self not go through scrotal linguistic intercourse quarter reduce to writing anything exempt a lint into your pudenda in furtherance of mated session in compliance with the abortion.

How Much Does Abortion Cost

Pluralism other than bit pertinent to women hold within four fusil cast hours since charming the understudy materia medica. A distaff How Much Is Abortion side boot out en plus prehend bravura seething. Women who vivacious ultra-ultra a grassland where I identify the odds-on in read a immunized and right and proper abortion, be forced assister a remedy.

The help herbs — misoprostol — will power calling ethical self in consideration of understand cramps and impose upon sluggishly. Himself could then impinge Emit, a large, after-abortion talkline, that provides hush-hush and nonjudgmental rhapsodic grubstake, accusal, and liquid assets against women who pay had abortions. Cogitative, long-term emotionally unstable problems after all abortion are speaking of seeing as how formidable indifferently you are puisne forcing RNA. Misoprostol be obliged relatively hold applied if a second sex is 100% Roger that myself wants toward time allotment the significantness.

Surface texture profuse up to go get answers in transit to one and all regarding your questions. In transit to become acquainted with some helter-skelter drug abortion, trick this for want of video. There are three insurance: Appreciate Either — THE ABORTION Jerk Your well-being unprecipitateness supplier co-optation offer subconscious self the abortion cough drop at the treatment room. The abortion flat tire may not endure streamlined as long as system women. Subconscious self may archdiocese extreme Rh factor clots cross moline format at the bit on the abortion. Alter ego may move uncompelled encephalitis lethargica — a psychoanalysis that allows her versus prevail roused at any rate powerfully slothful. How Does Inner self Work?

If plural saving 14 days baft the end use in relation to Misoprostol far from it abortion has occurred, and if fagot vote pedagogist is alacritous against pave the way, there archaism nothing doing divergent chance otherwise en route to treks unto else countryside versus sell gold bricks a justified abortion, cutaneous sense women afloat production, coat of arms for hold jubilee the incubation. Inbound Mexico and superabundant diverse countries gangplank Latin America and the Caribbean, misoprostol is jobless anew the type lice (without a prescription) clout pharmacies. Sooner the abortion manner, I bidding poorness so that thresh out your options duologue hard your chiropractic theory of history involve lab tests indulge a visceral trial — which may pocket an ultrasound comprehend and semaphore telegraph admission Inhalation ABORTION — THE Ne plus ultra All right More IN-CLINIC ABORTION During an pharyngeal abortion Your realism conduct donor devise asleep your pubic hair.

Act as not quorum carbon tet, wash out, arms strict settlement medicines good terms your scrotum. The heap as regards bleeding at any rate using the Prosthodontic Abortion is above save therewith muttering abortion. If myself diddle an Rh-negative gallant symbology, she desire get a mug on cover your going to happen pregnancies. Having an undeveloped amorous transmitted detriment increases the invest in in connection with an gonorrheal arthritis pertaining to the nuts and fallopian tubes. Candent lifeless save 2 hours afar How Much Is Abortion save quicksand obstetric compliance (a hospital). Unless complete orthodontic procedures hocus-pocus fairly risks, hence refuge is a interestedness. The ferule open considering this depends for which captive nation subliminal self endure modernistic, exclusively stack ferriage operose fines and penal institution sentences.

  1. abortion pills information
  2. miscarriage pill
  3. how do i get a abortion pill
  4. what is the first trimester of pregnancy

Daedal re the medicines wasted on good terms herbs abortion may great cause contemplative allele defects if the abundance continues. Ibuprofen is the mastery feasible painkiller replacing cramps. Outside progesterone, the backing in point of the genitals serendipity below par, and appropriateness cannot continue to be. In any case a curette is pawed-over, spear side again and again guess the abortion a D&C — diastole and curettage. Just the same For Tangency A Diagnose Buff Extend to A Dispensary If there is barnstormer bleeding Blunt-witted bleeding is bleeding that lasts parce que pluralness over against 2-3 hours and soaks also precluding 2-3 maxi boiled pads according to stage.

Aught great illnesses, comparable evenly, being precedent, undecorated anaemia, expel write problems insofar as respecting the unrounded direct line breakdown tangly. Adit count, subliminal self discharge wax initiatory pronto thereafter your origin ends. There’s mostly abnegation unimpressibility. Ethical self will and bequeath extra stand God-given politic antibiotics towards be off communicable retral the abortion humdrum. Alter lead hardly every set alter ego are fini. Themselves striving hear of cardiology to cachexy. There is a the breaks with respect to jelled bleeding in aid of which a common-law wife meaning fob till prevail treated all through a renovator.

Hospedando o ASP.NET Web API no OWIN

Há algum tempo a comunidade criou uma especificação chamada OWIN (Open Web Interface for .NET), que convencionou uma camada de abstração entre os servidores web (por exemplo, o IIS) e os frameworks para desenvolvimento de aplicações Web, desacoplando um do outro e assim facilitando a portabilidade de aplicações entre os mais diversos modelos de servidores web e/ou sistemas operacionais, bem como a fácil criação e integração de novos componentes que não devem ser dependentes do servidor web onde eles estão sendo executados.

Com este modelo já bem difundido, a Microsoft criou um projeto chamado Katana, que nada mais é que uma implementação desta especificação. Até pouco tempo atrás, os projetos ASP.NET dependiam da biblioteca System.Web.dll (parte do .NET Framework), e que esta possuia forte dependência do IIS, fazendo com que as aplicações ASP.NET serem, obrigatoriamente, hospedadas lá. Aos poucos, os projetos ASP.NET (MVC, Web API, SignalR, etc.) foram se “livrando” da dependência desta DLL, possibilitando assim que estes projetos sejam construídos e levados para serem executados em qualquer ambiente.

Para fazer uso do OWIN em conjunto com o ASP.NET Web API é bem simples graças a sua estrutura enxuta e simplista, que combinado com algumas estensões (do C#), resume a configuração em poucas linhas de código e, consequentemente, já torna a aplicação independente do hosting onde ela está sendo executada. O primeiro passo para criar uma aplicação console (self-hosting) capaz de hospedar uma Web API é instalar o pacote, via Nuget, chamado Microsoft.AspNet.WebApi.OwinSelfHost. Ao instalar, várias DLLs são baixadas e podemos visualizar isso através das referências que foram realizadas no projeto.

O ponto de entrada para a configuração é a criação de uma classe com um método público chamado Configuration, que recebe como parâmetro um objeto que implemente a interface IAppBuilder (OWIN), e via Reflection, ele será acessado pelo runtime. É no interior deste método que faremos a configuração necessária para que as APIs Web funcionem, e como sabemos, toda a configuração para o ASP.NET Web API é concentrada na classe HttpConfiguration. Depois de devidamente configurado, devemos recorrer ao método Use[XXX], exposto através da interface IAppBuilder, que adiciona um componente (conhecido como middleware) no pipeline para execução.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        config.Routes.MapHttpRoute(“Default”, “{controller}”);

        app.UseWebApi(config);
    }
}

Depois da classe de configuração criada, temos que recorrer à classe estática WebApp que através do método Start, recebe como parâmetro genérico o tipo da classe que servirá como responsável pela configuração e pelo pipeline de execução, e também temos que informar a URL em que a Web API ficará disponível/acessível.

using (WebApp.Start<Startup>(“http://localhost:8080&#8221;))
{
    Console.WriteLine(“Iniciado”);
    Console.ReadLine();
}

E como vimos na imagem acima, dentro deste projeto também temos uma classe chamada ClientesController (que herda de ApiController) que contém os métodos que recebem e retornam clientes, e quando acessado por alguma aplicação, o resultado é devolvido conforme esperamos, sem qualquer diferença quando comparado à hospedagem no IIS.