Compartilhar via


Novidades no ASP.NET 4.5 e no Visual Studio 2012

Este documento descreve os novos recursos e aprimoramentos que estão sendo introduzidos no ASP.NET 4.5. Ele também descreve as melhorias que estão sendo feitas para o desenvolvimento da Web no Visual Studio 2012. Este documento foi publicado originalmente em 29 de fevereiro de 2012.

ASP.NET Tempo de execução e estrutura principais

Leitura e gravação assíncrona de solicitações e respostas HTTP

ASP.NET 4 introduziu a capacidade de ler uma entidade de solicitação HTTP como um fluxo usando o método HttpRequest.GetBufferlessInputStream . Esse método forneceu acesso de streaming à entidade de solicitação. No entanto, ele foi executado de forma síncrona, o que amarrou um thread durante uma solicitação.

ASP.NET 4.5 dá suporte à capacidade de ler fluxos de forma assíncrona em uma entidade de solicitação HTTP e à capacidade de liberar de forma assíncrona. ASP.NET 4.5 também oferece a capacidade de armazenar em buffer uma entidade de solicitação HTTP, o que facilita a integração com manipuladores HTTP downstream, como manipuladores de página .aspx e controladores MVC ASP.NET.

Melhorias no tratamento de HttpRequest

A referência Stream retornada pelo ASP.NET 4.5 de HttpRequest.GetBufferlessInputStream dá suporte a métodos de leitura síncronos e assíncronos. O objeto Stream retornado de GetBufferlessInputStream agora implementa os métodos BeginRead e EndRead. Os métodos Stream assíncronos permitem que você leia de forma assíncrona a entidade de solicitação em partes, enquanto ASP.NET libera o thread atual entre cada iteração de um loop de leitura assíncrono.

ASP.NET 4.5 também adicionou um método complementar para ler a entidade de solicitação de forma em buffer: HttpRequest.GetBufferedInputStream. Essa nova sobrecarga funciona como GetBufferlessInputStream, dando suporte a leituras síncronas e assíncronas. No entanto, conforme lê, GetBufferedInputStream também copia os bytes da entidade em ASP.NET buffers internos para que os módulos downstream e manipuladores ainda possam acessar a entidade de solicitação. Por exemplo, se algum código upstream no pipeline já tiver lido a entidade de solicitação usando GetBufferedInputStream, você ainda poderá usar HttpRequest.Form ou HttpRequest.Files. Isso permite que você execute o processamento assíncrono em uma solicitação (por exemplo, streaming de um upload de arquivo grande para um banco de dados), mas ainda execute .aspx páginas e controladores de ASP.NET MVC posteriormente.

Liberando uma resposta de forma assíncrona

O envio de respostas para um cliente HTTP pode levar um tempo considerável quando o cliente está longe ou tem uma conexão de baixa largura de banda. Normalmente, ASP.NET armazena em buffer os bytes de resposta à medida que são criados por um aplicativo. ASP.NET executa uma única operação de envio dos buffers acumulados no final do processamento da solicitação.

Se a resposta em buffer for grande (por exemplo, transmitir um arquivo grande para um cliente), você deverá chamar periodicamente HttpResponse.Flush para enviar a saída em buffer para o cliente e manter o uso da memória sob controle. No entanto, como Flush é uma chamada síncrona, chamar iterativamente Flush ainda consome um thread durante solicitações potencialmente longas.

ASP.NET 4.5 adiciona suporte para executar liberações de forma assíncrona usando os métodos BeginFlush e EndFlush da classe HttpResponse . Usando esses métodos, você pode criar módulos assíncronos e manipuladores assíncronos que enviam dados incrementalmente para um cliente sem amarrar threads do sistema operacional. Entre as chamadas BeginFlush e EndFlush, ASP.NET libera o thread atual. Isso reduz substancialmente o número total de threads ativos necessários para dar suporte a downloads HTTP de longa duração.

Suporte para módulos e manipuladores assíncronos baseados em await e tarefa

O .NET Framework 4 introduziu um conceito de programação assíncrona conhecido como tarefa. As tarefas são representadas pelo tipo Task e tipos relacionados no namespace System.Threading.Tasks . O .NET Framework 4.5 se baseia nisso com aprimoramentos do compilador que simplificam o trabalho com objetos Task . No .NET Framework 4.5, os compiladores dão suporte a duas novas palavras-chave: await e async. A palavra-chave await é uma abreviação sintática para indicar que uma parte do código deve aguardar de forma assíncrona alguma outra parte do código. A palavra-chave async representa uma dica que você pode usar para marcar métodos como métodos assíncronos baseados em tarefas.

A combinação de await, async e o objeto Task torna muito mais fácil para você escrever código assíncrono no .NET 4.5. ASP.NET 4.5 dá suporte a essas simplificações com novas APIs que permitem escrever módulos HTTP assíncronos e manipuladores HTTP assíncronos usando os novos aprimoramentos do compilador.

Módulos HTTP assíncronos

Suponha que você queira executar um trabalho assíncrono em um método que retorna um objeto Task . O exemplo de código a seguir define um método assíncrono que faz uma chamada assíncrona para baixar a home page da Microsoft. Observe o uso da palavra-chave async na assinatura do método e a chamada await para DownloadStringTaskAsync.

private async Task
ScrapeHtmlPage(object caller, EventArgs e)
{
    WebClient wc = new WebClient();
    var result = await wc.DownloadStringTaskAsync("http://www.microsoft.com");
    // Do something with the result
}

Isso é tudo o que você precisa escrever — o .NET Framework lidará automaticamente com o desenrolamento da pilha de chamadas enquanto aguarda a conclusão do download, bem como restaurará automaticamente a pilha de chamadas após a conclusão do download.

Agora, suponha que você queira usar esse método assíncrono em um módulo HTTP ASP.NET assíncrono. ASP.NET 4.5 inclui um método auxiliar (EventHandlerTaskAsyncHelper) e um novo tipo de delegado (TaskEventHandler) que você pode usar para integrar métodos assíncronos baseados em tarefas com o modelo de programação assíncrona mais antigo exposto pelo pipeline HTTP ASP.NET. Este exemplo mostra como:

public void Init(HttpApplication
context)
 {
   // Wrap the Task-based method so that it can be used with 
   // the older async programming model.
   EventHandlerTaskAsyncHelper helper = 
       new EventHandlerTaskAsyncHelper(ScrapeHtmlPage);
 
   // The helper object makes it easy to extract Begin/End methods out of
   // a method that returns a Task object. The ASP.NET pipeline calls the 
   // Begin and End methods to start and complete calls on asynchronous 
   // HTTP modules.
   context.AddOnPostAuthorizeRequestAsync(
       helper.BeginEventHandler, helper.EndEventHandler);
}

Manipuladores HTTP assíncronos

A abordagem tradicional para escrever manipuladores assíncronos no ASP.NET é implementar a interface IHttpAsyncHandler . ASP.NET 4.5 apresenta o tipo base assíncrono HttpTaskAsyncHandler do qual você pode derivar, o que facilita muito a escrita de manipuladores assíncronos.

O tipo HttpTaskAsyncHandler é abstrato e exige que você substitua o método ProcessRequestAsync . Internamente, ASP.NET cuida da integração da assinatura de retorno (um objeto Task) de ProcessRequestAsync com o modelo de programação assíncrona mais antigo usado pelo pipeline de ASP.NET.

O exemplo a seguir mostra como você pode usar Task e await como parte da implementação de um manipulador HTTP assíncrono:

public class MyAsyncHandler : HttpTaskAsyncHandler
{
    // ...
     
    // ASP.NET automatically takes care of integrating the Task based override
    // with the ASP.NET pipeline.
    public override async Task ProcessRequestAsync(HttpContext context)
    {
        WebClient wc = new WebClient();
        var result = await 
           wc.DownloadStringTaskAsync("http://www.microsoft.com");
        // Do something with the result
    }
}

Novos recursos de validação de solicitação ASP.NET

Por padrão, o ASP.NET executa a validação da solicitação — ele examina as solicitações para procurar marcação ou script em campos, cabeçalhos, cookies e assim por diante. Se algum for detectado, ASP.NET lançará uma exceção. Isso atua como uma primeira linha de defesa contra possíveis ataques de script entre sites.

ASP.NET 4.5 facilita a leitura seletiva de dados de solicitação não validados. ASP.NET 4.5 também integra a popular biblioteca AntiXSS, que anteriormente era uma biblioteca externa.

Os desenvolvedores frequentemente solicitam a capacidade de desativar seletivamente a validação de solicitação para seus aplicativos. Por exemplo, se seu aplicativo for um software de fórum, talvez você queira permitir que os usuários enviem postagens e comentários no fórum formatados em HTML, mas ainda assim certifique-se de que a validação da solicitação esteja verificando todo o resto.

ASP.NET 4.5 apresenta dois recursos que facilitam o trabalho seletivo com entrada não validada: validação de solicitação adiada ("lenta") e acesso a dados de solicitação não validados.

Validação de solicitação adiada ("preguiçosa")

No ASP.NET 4.5, por padrão, todos os dados da solicitação estão sujeitos à validação da solicitação. No entanto, você pode configurar o aplicativo para adiar a validação da solicitação até que você realmente acesse os dados da solicitação. (Às vezes, isso é chamado de validação de solicitação lenta, com base em termos como carregamento lento para determinados cenários de dados.) Você pode configurar o aplicativo para usar a validação adiada no arquivo Web.config definindo o atributo requestValidationMode como 4.5 no elemento httpRUntime , como no exemplo a seguir:

<httpRuntime requestValidationMode="4.5" ... />

Quando o modo de validação de solicitação é definido como 4.5, a validação de solicitação é disparada apenas para um valor de solicitação específico e somente quando seu código acessa esse valor. Por exemplo, se o código obtiver o valor de Request.Form["forum_post"], a validação da solicitação será invocada somente para esse elemento na coleção de formulários. Nenhum dos outros elementos na coleção Form é validado. Nas versões anteriores do ASP.NET, a validação de solicitação era disparada para toda a coleção de solicitações quando qualquer elemento da coleção era acessado. O novo comportamento torna mais fácil para diferentes componentes do aplicativo examinar diferentes partes dos dados da solicitação sem disparar a validação da solicitação em outras partes.

Suporte para solicitações não validadas

A validação de solicitação adiada por si só não resolve o problema de ignorar seletivamente a validação de solicitação. A chamada para Request.Form["forum_post"] ainda dispara a validação da solicitação para esse valor de solicitação específico. No entanto, talvez você queira acessar esse campo sem disparar a validação porque deseja permitir a marcação nesse campo.

Para permitir isso, o ASP.NET 4.5 agora oferece suporte ao acesso não validado aos dados da solicitação. ASP.NET 4.5 inclui uma nova propriedade de coleção não validada na classe HttpRequest . Essa coleção fornece acesso a todos os valores comuns de dados de solicitação, como Form, QueryString, Cookies e Url.

Usando o exemplo do fórum, para poder ler dados de solicitação não validados, primeiro você precisa configurar o aplicativo para usar o novo modo de validação de solicitação:

<httpRuntime requestValidationMode="4.5" ...
/>

Em seguida, você pode usar a propriedade HttpRequest.Unvalidated para ler o valor do formulário não validado:

var s = context.Request.Unvalidated.Form["forum_post"];

Aviso

Segurança - Use dados de solicitação não validados com cuidado! ASP.NET 4.5 adicionou as propriedades e coleções de solicitação não validadas para facilitar o acesso a dados de solicitação não validados muito específicos. No entanto, você ainda deve executar a validação personalizada nos dados brutos da solicitação para garantir que o texto perigoso não seja renderizado aos usuários.

Biblioteca AntiXSS

Devido à popularidade da Microsoft AntiXSS Library, o ASP.NET 4.5 agora incorpora rotinas de codificação principais da versão 4.0 dessa biblioteca.

As rotinas de codificação são implementadas pelo tipo AntiXssEncoder no novo namespace System.Web.Security.AntiXss . Você pode usar o tipo AntiXssEncoder diretamente chamando qualquer um dos métodos de codificação estática implementados no tipo. No entanto, a abordagem mais fácil para usar as novas rotinas anti-XSS é configurar um aplicativo ASP.NET para usar a classe AntiXssEncoder por padrão. Para fazer isso, adicione o seguinte atributo ao arquivo Web.config:

<httpRuntime ...
  encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

Quando o atributo encoderType é definido para usar o tipo AntiXssEncoder , toda a codificação de saída no ASP.NET usa automaticamente as novas rotinas de codificação.

Estas são as partes da biblioteca AntiXSS externa que foram incorporadas ao ASP.NET 4.5:

  • HtmlEncode, HtmlFormUrlEncode e HtmlAttributeEncode
  • XmlAttributeEncode e XmlEncode
  • UrlEncode e UrlPathEncode (novo)
  • CssEncode

Suporte para o protocolo WebSockets

O protocolo WebSockets é um protocolo de rede baseado em padrões que define como estabelecer comunicações bidirecionais seguras e em tempo real entre um cliente e um servidor por HTTP. A Microsoft trabalhou com os órgãos de padrões IETF e W3C para ajudar a definir o protocolo. O protocolo WebSockets é suportado por qualquer cliente (não apenas navegadores), com a Microsoft investindo recursos substanciais no suporte ao protocolo WebSockets em sistemas operacionais cliente e móvel.

O protocolo WebSockets facilita muito a criação de transferências de dados de longa duração entre um cliente e um servidor. Por exemplo, escrever um aplicativo de bate-papo é muito mais fácil porque você pode estabelecer uma conexão verdadeira de longa duração entre um cliente e um servidor. Você não precisa recorrer a soluções alternativas, como sondagem periódica ou sondagem longa de HTTP para simular o comportamento de um soquete.

ASP.NET 4.5 e IIS 8 incluem suporte a WebSockets de baixo nível, permitindo que ASP.NET desenvolvedores usem APIs gerenciadas para ler e gravar de forma assíncrona dados binários e de cadeia de caracteres em um objeto WebSockets. Para o ASP.NET 4.5, há um novo namespace System.Web.WebSockets que contém tipos para trabalhar com o protocolo WebSockets.

Um cliente de navegador estabelece uma conexão WebSockets criando um objeto WebSocket DOM que aponta para uma URL em um aplicativo ASP.NET, como no exemplo a seguir:

socket = new WebSocket("ws://contoso.com/MyWebSocketApplication.ashx");

Você pode criar pontos de extremidade WebSockets no ASP.NET usando qualquer tipo de módulo ou manipulador. No exemplo anterior, um arquivo .ashx foi usado, pois os arquivos .ashx são uma maneira rápida de criar um manipulador.

De acordo com o protocolo WebSockets, um aplicativo ASP.NET aceita a solicitação WebSockets de um cliente indicando que a solicitação deve ser atualizada de uma solicitação HTTP GET para uma solicitação WebSockets. Veja um exemplo:

HttpContext.Current.AcceptWebSocketRequest(// WebSocket delegate goes here)

O método AcceptWebSocketRequest aceita um delegado de função porque ASP.NET desenrola a solicitação HTTP atual e, em seguida, transfere o controle para o delegado de função. Conceitualmente, essa abordagem é semelhante a como você usa System.Threading.Thread, em que você define um delegado de início de thread no qual o trabalho em segundo plano é executado.

Depois que ASP.NET e o cliente concluírem com êxito um handshake do WebSockets, ASP.NET chama seu representante e o aplicativo WebSockets começa a ser executado. O exemplo de código a seguir mostra um aplicativo de eco simples que usa o suporte interno a WebSockets no ASP.NET:

public async Task MyWebSocket(AspNetWebSocketContext context)
{
    WebSocket socket = context.WebSocket;
    while (true)
    {
        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);

        // Asynchronously wait for a message to arrive from a client
        WebSocketReceiveResult result = 
           await socket.ReceiveAsync(buffer, CancellationToken.None);

        // If the socket is still open, echo the message back to the client
        if (socket.State == WebSocketState.Open)
        {
           string userMessage = Encoding.UTF8.GetString(buffer.Array, 0,
               result.Count);
           userMessage = "You sent: " + userMessage + " at " + 
               DateTime.Now.ToLongTimeString();
           buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));

           // Asynchronously send a message to the client
           await socket.SendAsync(buffer, WebSocketMessageType.Text,
               true, CancellationToken.None);
        }
        else { break; }
    }
}

O suporte no .NET 4.5 para a palavra-chave await e operações assíncronas baseadas em tarefas é uma opção natural para escrever aplicativos WebSockets. O exemplo de código mostra que uma solicitação WebSockets é executada de forma completamente assíncrona dentro ASP.NET. O aplicativo aguarda de forma assíncrona que uma mensagem seja enviada de um cliente chamando await socket. ReceiveAsync. Da mesma forma, você pode enviar uma mensagem assíncrona para um cliente chamando await socket. SendAsync.

No navegador, um aplicativo recebe mensagens WebSockets por meio de uma função onmessage . Para enviar uma mensagem de um navegador, chame o método send do tipo DOM WebSocket , conforme mostrado neste exemplo:

// Receive a string message from the server.
socket.onmessage = function(msg)
{
    document.getElementById("serverData").innerHTML = msg.data; 
};
// Send a string message from the browser.
socket.send(document.getElementById("msgText"));

No futuro, poderemos lançar atualizações para essa funcionalidade que abstraiam parte da codificação de baixo nível necessária nesta versão para aplicativos WebSockets.

Agrupamento e minificação

O agrupamento permite combinar arquivos JavaScript e CSS individuais em um pacote que pode ser tratado como um único arquivo. A minificação condensa arquivos JavaScript e CSS removendo espaços em branco e outros caracteres que não são necessários. Esses recursos funcionam com Web Forms, ASP.NET MVC e Páginas da Web.

Os pacotes são criados usando a classe Bundle ou uma de suas classes filho, ScriptBundle e StyleBundle. Depois de configurar uma instância de um pacote, o pacote é disponibilizado para solicitações de entrada simplesmente adicionando-o a uma instância global de BundleCollection. Nos modelos padrão, a configuração do pacote configurável é executada em um arquivo BundleConfig. Essa configuração padrão cria pacotes para todos os scripts principais e arquivos css usados pelos modelos.

Os pacotes configuráveis são referenciados de dentro das exibições usando um dos dois métodos auxiliares possíveis. Para dar suporte à renderização de marcação diferente para um pacote no modo de depuração versus lançamento, as classes ScriptBundle e StyleBundle têm o método auxiliar, Render. Quando estiver no modo de depuração, o Render gerará marcação para cada recurso no pacote. Quando estiver no modo de lançamento, o Render gerará um único elemento de marcação para todo o pacote. A alternância entre o modo de depuração e de versão pode ser realizada modificando o atributo debug do elemento de compilação em web.config, conforme mostrado abaixo:

<system.web>
 <compilation targetframework="4.5" debug="true" />
 ...</system.web>

Além disso, habilitar ou desabilitar a otimização pode ser definido diretamente por meio da propriedade BundleTable.EnableOptimizations.

BundleTable.EnableOptimizations = true;

Quando os arquivos são agrupados, eles são classificados primeiro em ordem alfabética (a maneira como são exibidos no Gerenciador de Soluções). Eles são então organizados para que as bibliotecas conhecidas e suas extensões personalizadas (como jQuery, MooTools e Dojo) sejam carregadas primeiro. Por exemplo, a ordem final para o agrupamento da pasta Scripts, conforme mostrado acima, será:

  1. jquery-1.6.2.js
  2. jquery-ui.js
  3. jquery.tools.js
  4. a.js

Os arquivos CSS também são classificados em ordem alfabética e reorganizados para que reset.css e normalize.css venham antes de qualquer outro arquivo. A classificação final do agrupamento da pasta Estilos mostrada acima será esta:

  1. reset.css
  2. content.css
  3. forms.css
  4. globals.css
  5. menu.css
  6. styles.css

Melhorias de desempenho para hospedagem na web

O .NET Framework 4.5 e o Windows 8 apresentam recursos que podem ajudá-lo a obter um aumento significativo de desempenho para cargas de trabalho de servidor Web. Isso inclui uma redução (até 35%) no tempo de inicialização e no consumo de memória de sites de hospedagem na web que usam ASP.NET.

Principais fatores de desempenho

Idealmente, todos os sites devem estar ativos e na memória para garantir uma resposta rápida à próxima solicitação, sempre que ela vier. Os fatores que podem afetar a capacidade de resposta do site incluem:

  • O tempo que leva para um site reiniciar após a reciclagem de um pool de aplicativos. Esse é o tempo necessário para iniciar um processo de servidor Web para o site quando os assemblies do site não estão mais na memória. (Os assemblies de plataforma ainda estão na memória, pois são usados por outros sites.) Essa situação é chamada de "site frio, inicialização de estrutura quente" ou apenas "inicialização de site frio".
  • Quanta memória o site ocupa. Os termos para isso são "consumo de memória por site" ou "conjunto de trabalho não compartilhado".

As novas melhorias de desempenho se concentram em ambos os fatores.

Requisitos para novos recursos de desempenho

Os requisitos para os novos recursos podem ser divididos nestas categorias:

  • Melhorias executadas no .NET Framework 4.
  • Aprimoramentos que exigem o .NET Framework 4.5, mas podem ser executados em qualquer versão do Windows.
  • Aprimoramentos que estão disponíveis apenas com o .NET Framework 4.5 em execução no Windows 8.

O desempenho aumenta a cada nível de melhoria que você pode habilitar.

Algumas das melhorias do .NET Framework 4.5 aproveitam os recursos de desempenho mais amplos que também se aplicam a outros cenários.

Compartilhando assemblies comuns

Requisito: .NET Framework 4 e Visual Studio 11 Developer Preview SDK

Sites diferentes em um servidor geralmente usam os mesmos assemblies auxiliares (por exemplo, assemblies de um kit inicial ou aplicativo de exemplo). Cada site tem sua própria cópia desses assemblies em seu diretório Bin. Embora o código de objeto para os assemblies seja idêntico, eles são assemblies fisicamente separados, portanto, cada assembly deve ser lido separadamente durante a inicialização do site frio e mantido separadamente na memória.

A nova funcionalidade de internamento resolve essa ineficiência e reduz os requisitos de RAM e o tempo de carregamento. A internação permite que o Windows mantenha uma única cópia de cada assembly no sistema de arquivos, e assemblies individuais nas pastas Bin do site são substituídos por links simbólicos para a cópia única. Se um site individual precisar de uma versão distinta do assembly, o link simbólico será substituído pela nova versão do assembly e somente esse site será afetado.

O compartilhamento de assemblies usando links simbólicos requer uma nova ferramenta chamada aspnet_intern.exe, que permite criar e gerenciar o armazenamento de assemblies internos. Ele é fornecido como parte do SDK do Visual Studio 11 Developer Preview. (No entanto, ele funcionará em um sistema que tenha apenas o .NET Framework 4 instalado, supondo que você tenha instalado a atualização mais recente.)

Para garantir que todos os assemblies qualificados tenham sido internados, execute aspnet_intern.exe periodicamente (por exemplo, uma vez por semana como uma tarefa agendada). Um uso típico é o seguinte:

aspnet_intern -mode exec -sourcedir
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files" -interndir C:\ASPNETCommonAssemblies

Para ver todas as opções, execute a ferramenta sem argumentos.

Usando a compilação JIT multi-Core para inicialização mais rápida

Requisito: .NET Framework 4.5

Para uma inicialização de site frio, não apenas os assemblies precisam ser lidos do disco, mas o site deve ser compilado por JIT. Para um site complexo, isso pode adicionar atrasos significativos. Uma nova técnica de uso geral no .NET Framework 4.5 reduz esses atrasos espalhando a compilação JIT entre os núcleos de processador disponíveis. Ele faz isso o máximo e o mais cedo possível, usando informações coletadas durante lançamentos anteriores do site. Essa funcionalidade implementada pelo método System.Runtime.ProfileOptimization.StartProfile .

A compilação JIT usando vários núcleos é habilitada por padrão no ASP.NET, portanto, você não precisa fazer nada para aproveitar esse recurso. Se você quiser desabilitar esse recurso, faça a seguinte configuração no arquivo Web.config:

<configuration>
  <!-- ... -->
  <system.web>
<compilation profileGuidedOptimizations="None"  />
  <!-- ... -->

Ajustando a coleta de lixo para otimizar a memória

Requisito: .NET Framework 4.5

Depois que um site está em execução, o uso do heap do coletor de lixo (GC) pode ser um fator significativo em seu consumo de memória. Como qualquer coletor de lixo, o GC do .NET Framework faz compensações entre o tempo de CPU (frequência e significância das coleções) e o consumo de memória (espaço extra usado para objetos novos, liberados ou liberáveis). Para versões anteriores, fornecemos diretrizes sobre como configurar o GC para obter o equilíbrio certo (por exemplo, consulte ASP.NET 2.0/3.5 Configuração de hospedagem compartilhada).

Para o .NET Framework 4.5, em vez de várias configurações autônomas, está disponível uma definição de configuração definida pela carga de trabalho que habilita todas as configurações de GC recomendadas anteriormente, bem como um novo ajuste que oferece desempenho adicional para o conjunto de trabalho por site.

Para habilitar o ajuste de memória do GC, adicione a seguinte configuração ao arquivo Windows\Microsoft.NET\Framework\v4.0.30319\aspnet.config:

<configuration>
  <!-- ... -->
  <runtime>
<performanceScenario value="HighDensityWebHosting"  />
  <!-- ... -->

(Se você estiver familiarizado com as diretrizes anteriores para alterações em aspnet.config, observe que essa configuração substitui as configurações antigas — por exemplo, não há necessidade de definir gcServer, gcConcurrent etc. Você não precisa remover as configurações antigas.)

Pré-busca para aplicativos Web

Requisito: .NET Framework 4.5 em execução no Windows 8

Para várias versões, o Windows incluiu uma tecnologia conhecida como pré-busca, que reduz o custo de leitura de disco da inicialização do aplicativo. Como a inicialização a frio é um problema predominantemente para aplicativos cliente, essa tecnologia não foi incluída no Windows Server, que inclui apenas componentes essenciais para um servidor. A pré-busca agora está disponível na versão mais recente do Windows Server, onde pode otimizar a inicialização de sites individuais.

Para Windows Server, a pré-busca não está habilitada por padrão. Para habilitar e configurar o pré-buscador para hospedagem na Web de alta densidade, execute o seguinte conjunto de comandos na linha de comando:

sc config sysmain start=auto
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" /v EnablePrefetcher /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Prefetcher" /v MaxPrefetchFiles /t REG_DWORD /d 8192 /f
net start sysmain

Em seguida, para integrar a pré-busca a aplicativos ASP.NET, adicione o seguinte ao arquivo Web.config:

<configuration>
  <!-- ... -->
  <system.web>
<compilation enablePrefetchOptimization="true" />
  <!-- ... -->

Web Forms do ASP.NET

Controles de dados fortemente tipados

No ASP.NET 4.5, o Web Forms inclui algumas melhorias para trabalhar com dados. A primeira melhoria são os controles de dados fortemente tipados. Para controles Web Forms em versões anteriores do ASP.NET, você exibe um valor associado a dados usando Eval e uma expressão de vinculação de dados:

<ul>
<asp:Repeater runat="server" ID="customers">
       <ItemTemplate>
           <li>
               First Name: <%# Eval("FirstName")%><br />
               Last Name: <%# Eval("LastName")%><br />
           </li>
       </ItemTemplate>
</asp:Repeater>
</ul>

Para associação de dados bidirecional, use Bind:

<asp:FormView runat="server" ID="editCustomer">
<EditItemTemplate>
       <div>
           <asp:Label runat="server" AssociatedControlID="firstName">
               First Name:</asp:Label>
           <asp:TextBox ID="firstName" runat="server"
               Text='<%#Bind("FirstName") %>' />
       </div>
       <div>
           <asp:Label runat="server" AssociatedControlID="lastName">
               First Name:</asp:Label>
           <asp:TextBox ID="lastName" runat="server"
               Text='<%#
Bind("LastName") %>' />
       </div>
       <asp:Button runat="server" CommandName="Update"/>
</EditItemTemplate>
</asp:FormView>

Em tempo de execução, essas chamadas usam reflexão para ler o valor do membro especificado e, em seguida, exibir o resultado na marcação. Essa abordagem facilita a associação de dados com dados arbitrários e sem forma.

No entanto, expressões de associação de dados como essa não dão suporte a recursos como IntelliSense para nomes de membros, navegação (como Ir para Definição) ou verificação em tempo de compilação para esses nomes.

Para resolver esse problema, o ASP.NET 4.5 adiciona a capacidade de declarar o tipo de dados aos quais um controle está associado. Você faz isso usando a nova propriedade ItemType . Quando você define essa propriedade, duas novas variáveis tipadas estão disponíveis no escopo das expressões de associação de dados: Item e BindItem. Como as variáveis são fortemente tipadas, você obtém todos os benefícios da experiência de desenvolvimento do Visual Studio.

Para expressões de associação de dados bidirecionais, use a variável BindItem :

<asp:FormView runat="server" ID="editCustomer">
<EditItemTemplate>
       <div>
           <asp:Label runat="server" AssociatedControlID="firstName">
               First Name:</asp:Label>
           <asp:TextBox ID="firstName" runat="server"  
               Text='<%#BindItem.FirstName %>' />
       </div>
       <div>
           <asp:Label runat="server" AssociatedControlID="lastName">
               First Name:</asp:Label>
           <asp:TextBox ID="lastName" runat="server" 
               Text='<%#BindItem.LastName %>' />
       </div>
       <asp:Button runat="server" CommandName="Update"/>
</EditItemTemplate>
</asp:FormView>

A maioria dos controles na estrutura ASP.NET Web Forms que dão suporte à associação de dados foram atualizados para dar suporte à propriedade ItemType .

Model binding

A associação de modelos estende a associação de dados em controles ASP.NET Web Forms para trabalhar com acesso a dados focado em código. Ele incorpora conceitos do controle ObjectDataSource e da associação de modelos no MVC ASP.NET.

Selecionar dados

Para configurar um controle de dados para usar a associação de modelo para selecionar dados, defina a propriedade SelectMethod do controle como o nome de um método no código da página. O controle de dados chama o método no momento apropriado no ciclo de vida da página e associa automaticamente os dados retornados. Não há necessidade de chamar explicitamente o método DataBind .

No exemplo a seguir, o controle GridView está configurado para usar um método chamado GetCategories:

<asp:GridView ID="categoriesGrid"
runat="server"
ItemType="WebApplication1.Model.Category"
SelectMethod="GetCategories" AutoGenerateColumns="false">
<Columns>
       <asp:BoundField DataField="CategoryID" HeaderText="ID" />
       <asp:BoundField DataField="CategoryName" HeaderText="Name" />
       <asp:BoundField DataField="Description" HeaderText="Description" />
       <asp:TemplateField HeaderText="# of Products">
           <ItemTemplate><%# Item.Products.Count %></ItemTemplate>
       </asp:TemplateField>
</Columns>
</asp:GridView>

Você cria o método GetCategories no código da página. Para uma operação de seleção simples, o método não precisa de parâmetros e deve retornar um objeto IEnumerable ou IQueryable . Se a nova propriedade ItemType estiver definida (o que permite expressões de associação de dados fortemente tipadas, conforme explicado em Controles de dados fortemente tipados anteriormente), as versões genéricas dessas interfaces deverão ser retornadas — IEnumerable<T> ou IQueryable<T>, com o parâmetro T correspondendo ao tipo da propriedade ItemType (por exemplo, IQueryable<Category>).

O exemplo a seguir mostra o código de um método GetCategories . Este exemplo usa o modelo do Entity Framework Code First com o banco de dados de exemplo Northwind. O código garante que a consulta retorne detalhes dos produtos relacionados para cada categoria por meio do método Include . (Isso garante que o TemplateField na marcação exibe a contagem de produtos em cada categoria sem exigir uma seleção n+1.)

public IQueryable<Category>
GetCategories()
{
    var db = new Northwind();
    return db.Categories.Include(c => c.Products);
}

Quando a página é executada, o controle GridView chama o método GetCategories automaticamente e renderiza os dados retornados usando os campos configurados:

Captura de tela que mostra uma exibição em grade de uma lista de alimentos por categoria. Existem oito categorias de alimentos.

Como o método select retorna um objeto IQueryable , o controle GridView pode manipular ainda mais a consulta antes de executá-la. Por exemplo, o controle GridView pode adicionar expressões de consulta para classificação e paginação ao objeto IQueryable retornado antes de ser executado, para que essas operações sejam executadas pelo provedor LINQ subjacente. Nesse caso, o Entity Framework garantirá que essas operações sejam executadas no banco de dados.

O exemplo a seguir mostra o controle GridView modificado para permitir classificação e paginação:

<asp:GridView ID="categoriesGrid"
runat="server"
AutoGenerateColumns="false"
AllowSorting="true" AllowPaging="true" PageSize="5"
ItemType="WebApplication1.Model.Category" DataKeyNames="CategoryID"
SelectMethod="GetCategories"
UpdateMethod="UpdateCategory">
<Columns>
       <asp:BoundField DataField="CategoryID" HeaderText="ID" SortExpression="CategoryID" />
       <asp:BoundField DataField="CategoryName" HeaderText="Name" SortExpression="CategoryName" />
       <asp:BoundField DataField="Description" HeaderText="Description" />
       <asp:TemplateField HeaderText="# of Products">
           <ItemTemplate><%# Item.Products.Count %></ItemTemplate>
       </asp:TemplateField>
</Columns>
<EmptyDataTemplate>No categories found with a product count of 
      <%# minProductsCount.SelectedValue %></EmptyDataTemplate>
</asp:GridView>

Agora, quando a página é executada, o controle pode garantir que apenas a página atual de dados seja exibida e que ela seja ordenada pela coluna selecionada:

Captura de tela que mostra uma exibição em grade de uma lista de alimentos por categoria. Existem três categorias, Confeitos, Condimentos e Bebidas.

Para filtrar os dados retornados, os parâmetros devem ser adicionados ao método select. Esses parâmetros serão preenchidos pela associação de modelo em tempo de execução e você pode usá-los para alterar a consulta antes de retornar os dados.

Por exemplo, suponha que você queira permitir que os usuários filtrem produtos inserindo uma palavra-chave na cadeia de caracteres de consulta. Você pode adicionar um parâmetro ao método e atualizar o código para usar o valor do parâmetro:

public IQueryable<Product>
GetProducts(string keyword)
{
    IQueryable<Product> query = _db.Products;
     
    if (!String.IsNullOrWhiteSpace(keyword))
    {
        query = query.Where(p => p.ProductName.Contains(keyword));
    }
    return query;
}

Esse código inclui uma expressão Where se um valor for fornecido para a palavra-chave e, em seguida, retorna os resultados da consulta.

Provedores de valor

O exemplo anterior não era específico sobre a origem do valor do parâmetro de palavra-chave . Para indicar essas informações, você pode usar um atributo de parâmetro. Para este exemplo, você pode usar a classe QueryStringAttribute que está no namespace System.Web.ModelBinding :

public IQueryable<Product>
GetProducts([QueryString]string keyword)
{
    IQueryable<Product> query = _db.Products;
     
    if (!String.IsNullOrWhiteSpace(keyword))
    {
        query = query.Where(p => p.ProductName.Contains(keyword));
    }
    return query;
}

Isso instrui a associação de modelo a tentar associar um valor da cadeia de caracteres de consulta ao parâmetro de palavra-chave em tempo de execução. (Isso pode envolver a execução da conversão de tipo, embora não seja neste caso.) Se um valor não puder ser fornecido e o tipo não puder ser anulado, uma exceção será lançada.

As fontes de valores para esses métodos são chamadas de provedores de valor, e os atributos de parâmetro que indicam qual provedor de valor usar são chamados de atributos de provedor de valor. Os Web Forms incluirão provedores de valor e atributos correspondentes para todas as fontes típicas de entrada do usuário em um aplicativo Web Forms, como a cadeia de caracteres de consulta, cookies, valores de formulário, controles, estado de exibição, estado da sessão e propriedades de perfil. Você também pode escrever provedores de valor personalizados.

Por padrão, o nome do parâmetro é usado como a chave para localizar um valor na coleção do provedor de valor. No exemplo, o código procurará um valor de cadeia de caracteres de consulta chamado keyword (por exemplo, ~/default.aspx?keyword=chef). Você pode especificar uma chave personalizada passando-a como um argumento para o atributo de parâmetro. Por exemplo, para usar o valor da variável de cadeia de caracteres de consulta chamada q, você pode fazer o seguinte:

public IQueryable<Product>
GetProducts([QueryString("q")]string keyword)
{
    IQueryable<Product> query = _db.Products;

    if (!String.IsNullOrWhiteSpace(keyword))
    {
       query = query.Where(p => p.ProductName.Contains(keyword));
    }
    return query;
}

Se esse método estiver no código da página, os usuários poderão filtrar os resultados passando uma palavra-chave usando a string de consulta:

Captura de tela que mostra um navegador na página do aplicativo My A S P dot Net. Existem duas variáveis listadas para a comida Cajun.

A associação de modelos realiza muitas tarefas que, de outra forma, você teria que codificar manualmente: ler o valor, verificar se há um valor nulo, tentar convertê-lo no tipo apropriado, verificar se a conversão foi bem-sucedida e, por fim, usar o valor na consulta. A associação de modelos resulta em muito menos código e na capacidade de reutilizar a funcionalidade em todo o aplicativo.

Filtrando por valores de um controle

Suponha que você queira estender o exemplo para permitir que o usuário escolha um valor de filtro em uma lista suspensa. Adicione a seguinte lista suspensa à marcação e configure-a para obter seus dados de outro método usando a propriedade SelectMethod :

<asp:Label runat="server" AssociatedControlID="categories"
Text="Select a category to show products for: " />
<asp:DropDownList runat="server" ID="categories"
SelectMethod="GetCategories" AppendDataBoundItems="true"
DataTextField="CategoryName" DataValueField="CategoryID"
AutoPostBack="true">
  <asp:ListItem Value="" Text="- all -" />
</asp:DropDownList>

Normalmente, você também adicionaria um elemento EmptyDataTemplate ao controle GridView para que o controle exiba uma mensagem se nenhum produto correspondente for encontrado:

<asp:GridView ID="productsGrid"
runat="server" DataKeyNames="ProductID"
AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false"
SelectMethod="GetProducts" >
<Columns>
       <asp:BoundField DataField="ProductID" HeaderText="ID" />
       <asp:BoundField DataField="ProductName" HeaderText="Name"				  
            SortExpression="ProductName" />
       <asp:BoundField DataField="UnitPrice" HeaderText="Unit Price" 
            SortExpression="UnitPrice" />
       <asp:BoundField DataField="UnitsInStock" HeaderText="# in Stock" 
            SortExpression="UnitsInStock" />
</Columns>
<EmptyDataTemplate>
        No products matching the filter criteria were found</EmptyDataTemplate>
</asp:GridView>

No código da página, adicione o novo método select para a lista suspensa:

public IQueryable<Category>
GetCategories()
{
    return _db.Categories;
}

Por fim, atualize o método select GetProducts para obter um novo parâmetro que contém a ID da categoria selecionada na lista suspensa:

public IQueryable<Product>
GetProducts(
[QueryString("q")] string keyword,
[Control("categories")] int? categoryId)
{
    IQueryable<Product> query = _db.Products;
     
    if (!String.IsNullOrWhiteSpace(keyword))
    {
        query = query.Where(p => p.ProductName.Contains(keyword));
    }
    if (categoryId.HasValue && categoryId > 0)
    {
        query = query.Where(p => p.CategoryID == categoryId);
    }
    return query;
}

Agora, quando a página é executada, os usuários podem selecionar uma categoria na lista suspensa e o controle GridView é automaticamente associado novamente para mostrar os dados filtrados. Isso é possível porque a associação de modelos rastreia os valores dos parâmetros para métodos selecionados e detecta se algum valor de parâmetro foi alterado após um postback. Nesse caso, a associação de modelos força o controle de dados associado a se associar novamente aos dados.

Captura de tela que mostra uma visualização em grade de uma lista de confeitos por ID, nome, preço unitário e número em estoque.

Expressões de vinculação de dados codificadas em HTML

Agora você pode codificar em HTML o resultado de expressões de vinculação de dados. Adicione dois-pontos (:) ao final do prefixo <%# que marca a expressão de vinculação de dados:

<asp:TemplateField HeaderText="Name">
<ItemTemplate><%#: Item.Products.Name %></ItemTemplate>
</asp:TemplateField>

Validação discreta

Agora você pode configurar os controles do validador interno para usar JavaScript discreto para a lógica de validação do lado do cliente. Isso reduz significativamente a quantidade de JavaScript renderizado embutido na marcação da página e reduz o tamanho geral da página. Você pode configurar JavaScript discreto para controles validadores de qualquer uma destas maneiras:

  • Globalmente, adicionando a seguinte configuração ao <elemento appSettings> no arquivo Web.config:

    <add name="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />
    
  • Globalmente, definindo a propriedade estática System.Web.UI.ValidationSettings.UnobtrusiveValidationMode como UnobtrusiveValidationMode.WebForms (normalmente no método Application_Start no arquivo Global.asax).

  • Individualmente para uma página, definindo a nova propriedade UnobtrusiveValidationMode da classe Page como UnobtrusiveValidationMode.WebForms.

Atualizações HTML5

Algumas melhorias foram feitas nos controles do servidor Web Forms para aproveitar os novos recursos do HTML5:

  • A propriedade TextMode do controle TextBox foi atualizada para dar suporte aos novos tipos de entrada HTML5, como email, datetime e assim por diante.
  • O controle FileUpload agora dá suporte a vários uploads de arquivos de navegadores que dão suporte a esse recurso HTML5.
  • Os controles validadores agora dão suporte à validação de elementos de entrada HTML5.
  • Novos elementos HTML5 que têm atributos que representam uma URL agora suportam runat="server". Como resultado, você pode usar convenções de ASP.NET em caminhos de URL, como o operador ~ para representar a raiz do aplicativo (por exemplo, <video runat="server" src="~/myVideo.wmv" />).
  • O controle UpdatePanel foi corrigido para dar suporte à postagem de campos de entrada HTML5.

ASP.NET MVC 4

ASP.NET MVC 4 Beta agora está incluído no Visual Studio 11 Beta. ASP.NET MVC é uma estrutura para o desenvolvimento de aplicativos Web altamente testáveis e de manutenção, aproveitando o padrão MVC (Model-View-Controller). ASP.NET MVC 4 facilita a criação de aplicativos para a Web móvel e inclui ASP.NET API Web, que ajuda você a criar serviços HTTP que podem alcançar qualquer dispositivo. Para obter mais informações, consulte as Notas de versão do ASP.NET MVC 4.

Páginas da Web do ASP.NET 2

Os novos recursos incluem o seguinte:

  • Modelos de site novos e atualizados.
  • Adicionando validação do lado do servidor e do lado do cliente usando o auxiliar de validação .
  • A capacidade de registrar scripts usando um gerenciador de ativos.
  • Habilitando logins do Facebook e outros sites usando OAuth e OpenID.
  • Adicionando mapas usando o auxiliar Mapas .
  • Executando aplicativos de páginas da Web lado a lado.
  • Páginas de renderização para dispositivos móveis.

Para obter mais informações sobre esses recursos e exemplos de código de página inteira, consulte Os principais recursos do Web Pages 2 Beta.

Visual Web Developer 11 Beta

Esta seção fornece informações sobre melhorias para o desenvolvimento da Web no Visual Web Developer 11 Beta e no Visual Studio 2012 Release Candidate.

Compartilhamento de projeto entre o Visual Studio 2010 e o Visual Studio 2012 Release Candidate (compatibilidade de projeto)

Até o Visual Studio 2012 Release Candidate, abrir um projeto existente em uma versão mais recente do Visual Studio iniciava o Assistente de Conversão. Isso forçou uma atualização do conteúdo (ativos) de um projeto e solução para novos formatos que não eram compatíveis com versões anteriores. Portanto, após a conversão, você não pôde abrir o projeto na versão mais antiga do Visual Studio.

Muitos clientes nos disseram que essa não era a abordagem correta. No Visual Studio 11 Beta, agora damos suporte ao compartilhamento de projetos e soluções com o Visual Studio 2010 SP1. Isso significa que, se você abrir um projeto do 2010 no Visual Studio 2012 Release Candidate, ainda poderá abrir o projeto no Visual Studio 2010 SP1.

Observação

Alguns tipos de projetos não podem ser compartilhados entre o Visual Studio 2010 SP1 e o Visual Studio 2012 Release Candidate. Isso inclui alguns projetos mais antigos (como projetos ASP.NET MVC 2) ou projetos para fins especiais (como projetos de instalação).

Quando você abre um projeto Web do Visual Studio 2010 SP1 pela primeira vez no Visual Studio 11 Beta, as seguintes propriedades são adicionadas ao arquivo de projeto:

  • FileUpgradeFlags
  • UpgradeBackupLocation
  • Versão OldTools
  • VisualStudioVersion
  • Caminho VSTools

FileUpgradeFlags, UpgradeBackupLocation e OldToolsVersion são usados pelo processo que atualiza o arquivo de projeto. Eles não têm impacto no trabalho com o projeto no Visual Studio 2010.

VisualStudioVersion é uma nova propriedade usada pelo MSBuild 4.5 que indica a versão do Visual Studio para o projeto atual. Como essa propriedade não existia no MSBuild 4.0 (a versão do MSBuild que o Visual Studio 2010 SP1 usa), injetamos um valor padrão no arquivo de projeto.

A propriedade VSToolsPath é usada para determinar o arquivo .targets correto a ser importado do caminho representado pela configuração MSBuildExtensionsPath32.

Há também algumas alterações relacionadas a Importar elementos. Essas alterações são necessárias para dar suporte à compatibilidade entre as duas versões do Visual Studio.

Observação

Se um projeto estiver sendo compartilhado entre o Visual Studio 2010 SP1 e o Visual Studio 11 Beta em dois computadores diferentes e se o projeto incluir um banco de dados local na pasta App_Data, você deverá verificar se a versão do SQL Server usada pelo banco de dados está instalada em ambos os computadores.

Alterações de configuração nos modelos de site do ASP.NET 4.5

As seguintes alterações foram feitas no arquivo Web.config padrão para sites criados usando modelos de site no Visual Studio 2012 Release Candidate:

  • <httpRuntime> No elemento, o encoderType atributo agora é definido por padrão para usar os tipos AntiXSS que foram adicionados a ASP.NET. Para obter detalhes, consulte Biblioteca AntiXSS.
  • Também no <httpRuntime> elemento, o requestValidationMode atributo é definido como "4.5". Isso significa que, por padrão, a validação de solicitação é configurada para usar a validação adiada ("lenta"). Para obter detalhes, consulte Novos recursos de validação de solicitação ASP.NET.
  • O <modules> elemento da <system.webServer> seção não contém um runAllManagedModulesForAllRequests atributo. (Seu valor padrão é false.) Isso significa que, se você estiver usando uma versão do IIS 7 que não foi atualizada para o SP1, poderá ter problemas com o roteamento em um novo site. Para obter mais informações, consulte Suporte nativo no IIS 7 para roteamento ASP.NET.

Essas alterações não afetam os aplicativos existentes. No entanto, eles podem representar uma diferença de comportamento entre os sites existentes e os novos sites que você cria para o ASP.NET 4.5 usando os novos modelos.

Suporte nativo no IIS 7 para roteamento ASP.NET

Essa não é uma alteração no ASP.NET como tal, mas uma alteração nos modelos para novos projetos de site que podem afetá-lo se você estiver trabalhando em uma versão do IIS 7 que não teve a atualização do SP1 aplicada.

No ASP.NET, você pode adicionar a seguinte definição de configuração aos aplicativos para oferecer suporte ao roteamento:

<configuration>
  <system.webServer>
<modules runAllManagedModulesForAllRequests="true">
     <!-- more -->
</modules>
  </system.webServer>
</configuration>

Quando runAllManagedModulesForAllRequests é true, uma URL como http://mysite/myapp/home vai para ASP.NET, mesmo que não haja nenhuma extensão .aspx, .mvc ou semelhante na URL.

Uma atualização feita no IIS 7 torna a configuração runAllManagedModulesForAllRequests desnecessária e dá suporte ao roteamento ASP.NET nativamente. (Para obter informações sobre a atualização, consulte o artigo de Suporte da MicrosoftEstá disponível uma atualização que permite que determinados manipuladores do IIS 7.0 ou IIS 7.5 lidem com solicitações cujas URLs não terminam com um ponto.)

Se o seu site estiver em execução no IIS 7 e se o IIS tiver sido atualizado, você não precisará definir runAllManagedModulesForAllRequests como true. Na verdade, defini-lo como true não é recomendado, pois adiciona sobrecarga de processamento desnecessária à solicitação. Quando essa configuração é verdadeira, todas as solicitações, incluindo aquelas para .htm, .jpg e outros arquivos estáticos, também passam pelo pipeline de solicitação ASP.NET.

Se você criar um novo site do ASP.NET 4.5 usando os modelos fornecidos no Visual Studio 2012 RC, a configuração do site não incluirá a configuração runAllManagedModulesForAllRequests . Isso significa que, por padrão, a configuração é falsa.

Se você executar o site no Windows 7 sem o SP1 instalado, o IIS 7 não incluirá a atualização necessária. Como consequência, o roteamento não funcionará e você verá erros. Se você tiver um problema em que o roteamento não funciona, faça o seguinte:

  • Atualize o Windows 7 para o SP1, que adicionará a atualização ao IIS 7.
  • Instale a atualização descrita no artigo de Suporte da Microsoft listado anteriormente.
  • Defina runAllManagedModulesForAllRequests como true no arquivo Web.config desse site. Observe que isso adicionará alguma sobrecarga às solicitações.

Editor de HTML

Tarefas inteligentes

No modo Design, as propriedades complexas dos controles de servidor geralmente têm caixas de diálogo e assistentes associados para facilitar sua configuração. Por exemplo, você pode usar uma caixa de diálogo especial para adicionar uma fonte de dados a um controle Repeater ou adicionar colunas a um controle GridView .

No entanto, esse tipo de ajuda da interface do usuário para propriedades complexas não estava disponível no modo de exibição Código-fonte. Portanto, o Visual Studio 11 apresenta Tarefas Inteligentes para o modo de exibição Origem. As Tarefas Inteligentes são atalhos com reconhecimento de contexto para recursos comumente usados nos editores C# e Visual Basic.

Para ASP.NET controles Web Forms, as Tarefas Inteligentes aparecem nas tags do servidor como um pequeno glifo quando o ponto de inserção está dentro do elemento:

Captura de tela que mostra as tags do servidor como um pequeno glifo quando o ponto de inserção está dentro do elemento.

A Tarefa Inteligente se expande quando você clica no glifo ou pressiona CTRL+. (ponto), assim como nos editores de código. Em seguida, ele exibe atalhos semelhantes às Tarefas Inteligentes no modo Design.

Captura de tela que mostra uma janela Tarefas de exibição de grade.

Por exemplo, a Tarefa Inteligente na ilustração anterior mostra as opções de Tarefas do GridView. Se você escolher Editar colunas, a seguinte caixa de diálogo será exibida:

Captura de tela que mostra uma caixa de diálogo Campos.

O preenchimento da caixa de diálogo define as mesmas propriedades que você pode definir no modo Design. Quando você clica em OK, a marcação do controle é atualizada com as novas configurações:

Captura de tela que mostra a marcação do controle atualizada com novas configurações.

Suporte WAI-ARIA

Escrever sites acessíveis está se tornando cada vez mais importante. O padrão de acessibilidade WAI-ARIA define como os desenvolvedores devem escrever sites acessíveis. Esse padrão agora tem suporte total no Visual Studio.

Por exemplo, o atributo role agora tem IntelliSense completo:

Captura de tela que mostra o item de menu realçado em uma lista como o atributo Função.

O padrão WAI-ARIA também introduz atributos prefixados com aria- que permitem adicionar semântica a um documento HTML5. O Visual Studio também dá suporte total a esses atributos aria- :

Captura de tela que mostra os atributos aria. O efeito de queda de ária é selecionado na lista de atributos. Captura de tela que mostra os atributos do efeito de soltar ária com a cópia selecionada.

Novos trechos HTML5

Para tornar mais rápido e fácil escrever a marcação HTML5 comumente usada, o Visual Studio inclui vários snippets. Um exemplo é o trecho de vídeo:

Captura de tela que mostra um trecho de vídeo do Visual Studio selecionado.

Para invocar o snippet, pressione Tab duas vezes quando o elemento for selecionado no IntelliSense:

Captura de tela que mostra o elemento Arquivo selecionado no IntelliSense.

Isso produz um snippet que você pode personalizar.

Extrair para controle do usuário

Em grandes páginas da Web, pode ser uma boa ideia mover partes individuais para controles de usuário. Essa forma de refatoração pode ajudar a aumentar a legibilidade da página e simplificar a estrutura da página.

Para facilitar, ao editar páginas Web Forms no modo Código-fonte, agora você pode selecionar o texto em uma página, clicar com o botão direito do mouse nela e escolher Extrair para Controle de Usuário:

Captura de tela que mostra Extrair para Controle de Usuário selecionado no menu de contexto.

IntelliSense para pepitas de código em atributos

O Visual Studio sempre forneceu o IntelliSense para pepitas de código do lado do servidor em qualquer página ou controle. Agora, o Visual Studio também inclui o IntelliSense para pepitas de código em atributos HTML.

Captura de tela que mostra a Cadeia de Caracteres de Consulta selecionada em uma lista.

Isso facilita a criação de expressões de vinculação de dados:

Captura de tela que mostra a codificação de string de script Java selecionada.

Renomeação automática da tag correspondente quando você renomeia uma tag de abertura ou fechamento

Se você renomear um elemento HTML (por exemplo, alterar uma tag div para ser uma tag de cabeçalho ), a tag de abertura ou fechamento correspondente também será alterada em tempo real.

Captura de tela que mostra as tags de abertura e fechamento mudando em tempo real. A palavra Heade é destacada.

Isso ajuda a evitar o erro em que você esquece de alterar uma tag de fechamento ou altera a errada.

Geração de manipulador de eventos

O Visual Studio agora inclui recursos no modo de exibição Código-fonte para ajudá-lo a escrever manipuladores de eventos e associá-los manualmente. Se você estiver editando um nome de evento no modo de exibição Origem, o IntelliSense exibirá <Criar Novo Evento>, que criará um manipulador de eventos no código da página que tem a assinatura correta:

Captura de tela que mostra Criar Novo Evento no ponto de inserção na Exibição de Origem.

Por padrão, o manipulador de eventos usará a ID do controle para o nome do método de manipulação de eventos:

Captura de tela que mostra o I D do controle para o nome do método de manipulação de eventos.

O manipulador de eventos resultante terá esta aparência (neste caso, em C#):

Captura de tela que mostra o manipulador de eventos resultante em C sharp.

Recuo Inteligente

Quando você pressiona Enter enquanto está dentro de um elemento HTML vazio, o editor coloca o ponto de inserção no lugar certo:

Captura de tela que mostra um ponto de inserção entre dois elementos H T M L.

Se você pressionar Enter nesse local, a tag de fechamento será movida para baixo e recuada para corresponder à tag de abertura. O ponto de inserção também é recuado:

Captura de tela que mostra que a tag de fechamento é movida para baixo e recuada para corresponder à tag de abertura. O ponto de inserção também é recuado.

Conclusão da instrução de redução automática

A lista do IntelliSense no Visual Studio agora é filtrada com base no que você digita para que ela exiba apenas as opções relevantes:

Captura de tela que mostra o mapa de palavras selecionado em uma lista do IntelliSense.

O IntelliSense também filtra com base no uso de maiúsculas e minúsculas nas palavras individuais na lista do IntelliSense. Por exemplo, se você digitar "dl", dl e asp:DataList serão exibidos:

Captura de tela que mostra d l selecionado porque foi digitado.

Esse recurso torna mais rápido obter a conclusão da instrução para elementos conhecidos.

Editor JavaScript

O editor JavaScript no Visual Studio 2012 Release Candidate é completamente novo e melhora muito a experiência de trabalhar com JavaScript no Visual Studio.

Estrutura de tópicos de código

As regiões de estrutura de tópicos agora são criadas automaticamente para todas as funções, permitindo que você recolha partes do arquivo que não são pertinentes ao seu foco atual.

Correspondência de chaves

Quando você coloca o ponto de inserção em uma chave de abertura ou fechamento, o editor realça o ponto correspondente.

Ir para Definição

O comando Ir para Definição permite que você pule para a origem de uma função ou variável.

Suporte ao ECMAScript5

O editor suporta a nova sintaxe e APIs no ECMAScript5, a versão mais recente do padrão que descreve a linguagem JavaScript.

DOM IntelliSense

O IntelliSense para APIs DOM foi aprimorado, com suporte para muitas novas APIs HTML5, incluindo querySelector, Armazenamento DOM, mensagens entre documentos e tela. O DOM IntelliSense agora é controlado por um único arquivo JavaScript simples, em vez de uma definição de biblioteca de tipos nativa. Isso facilita a extensão ou substituição.

Sobrecargas de assinatura do VSDOC

Comentários detalhados do IntelliSense agora podem ser declarados para sobrecargas separadas de funções JavaScript usando o novo <elemento de assinatura> , conforme mostrado neste exemplo:

function GetOrSet(key, value) {
/// <signature>
///	 <summary>Gets the value</summary>
///	 <param name="key" type="String">The key to get the value for</param>
///	 <returns type="String" />
/// </signature>
/// <signature>
///	 <summary>Sets the value</summary>
///	 <param name="key" type="String">The key to set the value for</param>
///	 <param name="value" type="String">The value to set</param>
///	 <returns type="MyLib" />
/// </signature>
    if (value) {
        values[key] = value;
        return this;
    } else {
        return values[key];
    }
}

Referências implícitas

Agora você pode adicionar arquivos JavaScript a uma lista central que será incluída implicitamente na lista de arquivos que qualquer arquivo JavaScript ou bloco referencia, o que significa que você obterá o IntelliSense por seu conteúdo. Por exemplo, você pode adicionar arquivos jQuery à lista central de arquivos e obterá funções do IntelliSense para jQuery em qualquer bloco de arquivo JavaScript, independentemente de você tê-lo referenciado explicitamente (usando /// <referência />) ou não.

Editor de CSS

Conclusão da instrução de redução automática

A lista do IntelliSense para CSS agora é filtrada com base nas propriedades e valores de CSS compatíveis com o esquema selecionado.

Captura de tela que mostra border-radius selecionado em uma lista do IntelliSense para CS quando o raio é digitado.

O IntelliSense também dá suporte a pesquisas de maiúsculas e minúsculas:

A captura de tela mostra o peso da fonte selecionado após f w.

Recuo hierárquico

O editor de CSS usa recuo para exibir regras hierárquicas, o que fornece uma visão geral de como as regras em cascata são organizadas logicamente. No exemplo a seguir, o #list um seletor é um filho em cascata da lista e, portanto, é recuado.

Captura de tela que mostra um exemplo da lista recuada.

O exemplo a seguir mostra uma herança mais complexa:

Captura de tela que mostra uma lista adicional de variáveis.

O recuo de uma regra é determinado por suas regras pai. O recuo hierárquico é habilitado por padrão, mas você pode desabilitá-lo na caixa de diálogo Opções (Ferramentas, Opções na barra de menus):

Captura de tela que mostra a caixa de diálogo Opções. O recuo hierárquico é verificado.

Suporte a hacks CSS

A análise de centenas de arquivos CSS do mundo real mostra que os hacks de CSS são muito comuns e agora o Visual Studio oferece suporte aos mais usados. Esse suporte inclui o IntelliSense e a validação das invasões de propriedade estrela (*) e sublinhado (_):

Captura de tela que mostra a altura selecionada na lista.

Hacks de seletor típicos também são suportados para que o recuo hierárquico seja mantido mesmo quando eles são aplicados. Um hack de seletor típico usado para direcionar o Internet Explorer 7 é preceder um seletor com *:first-child + html. O uso dessa regra manterá o recuo hierárquico:

Captura de tela que mostra um exemplo de um hack de seletor típico.

Esquemas específicos do fornecedor (-moz-, -webkit)

O CSS3 apresenta muitas propriedades que foram implementadas por diferentes navegadores em momentos diferentes. Anteriormente, isso forçava os desenvolvedores a codificar para navegadores específicos usando a sintaxe específica do fornecedor. Essas propriedades específicas do navegador agora estão incluídas no IntelliSense.

Captura de tela que mostra a quebra automática de linha selecionada no IntelliSense.

Suporte para comentar e descomentar

Agora você pode comentar e descomentar regras CSS usando os mesmos atalhos que você usa no editor de código (Ctrl+K,C para comentar e Ctrl+K,u para descomentar).

Seletor de cor

Nas versões anteriores do Visual Studio, o IntelliSense para atributos relacionados a cores consistia em uma lista suspensa de valores de cores nomeados. Essa lista foi substituída por um seletor de cores completo.

Quando você insere um valor de cor, o seletor de cores é exibido automaticamente e apresenta uma lista de cores usadas anteriormente, seguida por uma paleta de cores padrão. Você pode selecionar uma cor usando o mouse ou o teclado.

Captura de tela que mostra uma lista de cores usadas anteriormente seguidas por uma paleta de cores padrão.

A lista pode ser expandida em um seletor de cores completo. O seletor permite controlar o canal alfa convertendo automaticamente qualquer cor em RGBA ao mover o controle deslizante de opacidade:

Captura de tela que mostra um seletor de cores convertendo automaticamente qualquer cor em R G B A quando você move o controle deslizante de opacidade.

Snippets

Os snippets no editor CSS facilitam e agilizam a criação de estilos entre navegadores. Muitas propriedades CSS3 que exigem configurações específicas do navegador agora foram incluídas em snippets.

Captura de tela que mostra Snippets no editor CSS. As palavras ease in out são selecionadas.

Os snippets de CSS dão suporte a cenários avançados (como consultas de mídia CSS3) digitando o símbolo de arroba (@), que mostra a lista do IntelliSense.

Captura de tela que mostra a mídia selecionada na lista do IntelliSense.

Quando você seleciona @media o valor e pressiona Tab, o editor de CSS insere o seguinte snippet:

Captura de tela que mostra um snippet com 1024 p x selecionado.

Assim como acontece com os snippets de código, você pode criar seus próprios snippets CSS.

Regiões personalizadas

As regiões de código nomeadas, que já estão disponíveis no editor de código, agora estão disponíveis para edição de CSS. Isso permite agrupar facilmente blocos de estilo relacionados.

Captura de tela que mostra o editor de código. Os blocos de estilo usados são para o menu de região.

Quando uma região é recolhida, ela exibe o nome da região:

Captura de tela que mostra a região do Menu recolhida.

Inspetor de Página

O Inspetor de Página é uma ferramenta que renderiza uma página da Web (HTML, Web Forms ASP.NET MVC ou Páginas da Web) no IDE do Visual Studio e permite examinar o código-fonte e a saída resultante. Para páginas ASP.NET, o Inspetor de Página permite determinar qual código do lado do servidor produziu a marcação HTML que é renderizada para o navegador.

Captura de tela que mostra o código do Visual Studio. O painel direito tem o código-fonte e o painel esquerdo renderiza a página da Web.

Para obter mais informações sobre o Inspetor de Página, consulte os seguintes tutoriais:

Publicando

Perfis de publicação

No Visual Studio 2010, a publicação de informações para projetos de aplicativo Web não é armazenada no controle de versão e não foi projetada para compartilhamento com outras pessoas. No Visual Studio 2012 Release Candidate, o formato do perfil de publicação foi alterado. Ele foi transformado em um artefato de equipe e agora é fácil aproveitar de builds baseados no MSBuild. As informações de configuração de compilação estão na caixa de diálogo Publicar para que você possa alternar facilmente as configurações de compilação antes de publicar.

Os perfis de publicação são armazenados na pasta PublishProfiles. A localização da pasta depende de qual linguagem de programação você está usando:

  • C#: Propriedades\PublishProfiles
  • Visual Basic: My Project\PublishProfiles

Cada perfil é um arquivo MSBuild. Durante a publicação, esse arquivo é importado para o arquivo MSBuild do projeto. No Visual Studio 2010, se você quiser fazer alterações no processo de publicação ou empacotamento, precisará colocar suas personalizações em um arquivo chamado ProjectName.wpp.targets. Isso ainda é compatível, mas agora você pode colocar suas personalizações no próprio perfil de publicação. Dessa forma, as personalizações serão usadas apenas para esse perfil.

Agora você também pode aproveitar os perfis de publicação do MSBuild. Para fazer isso, use o seguinte comando ao criar o projeto:

msbuild.exe project.csproj /t:WebPublish /p:PublishProfile=ProfileName

O valor project.csproj é o caminho do projeto e ProfileName é o nome do perfil a ser publicado. Como alternativa, em vez de passar o nome do perfil para a propriedade PublishProfile , você pode passar o caminho completo para o perfil de publicação.

ASP.NET pré-compilação e mesclagem

Para projetos de aplicativo Web, o Visual Studio 2012 Release Candidate adiciona uma opção na página de propriedades Empacotar/Publicar Web que permite pré-compilar e mesclar o conteúdo do site quando você publica ou empacota o projeto. Para ver essas opções, clique com o botão direito do mouse no projeto no Gerenciador de Soluções, escolha Propriedades e, em seguida, escolha a página de propriedades Pacote/Publicar Web. A ilustração a seguir mostra a opção Pré-compilar este aplicativo antes de publicar.

A captura de tela mostra que, para ver as opções da página de propriedades Empacotar/Publicar Web, clique com o botão direito do mouse no projeto no Gerenciador de Soluções, escolha Propriedades e, em seguida, escolha a página de propriedades Pacote/Publicar Web.

Quando essa opção é selecionada, o Visual Studio pré-compila o aplicativo sempre que você publica ou empacota o aplicativo Web. Se você quiser controlar como o site é pré-compilado ou como os assemblies são mesclados, clique no botão Avançado para configurar essas opções.

IIS Express

O servidor Web padrão para testar projetos Web no Visual Studio agora é o IIS Express. O Visual Studio Development Server ainda é uma opção para o servidor Web local durante o desenvolvimento, mas o IIS Express agora é o servidor recomendado. A experiência de usar o IIS Express no Visual Studio 11 Beta é muito semelhante a usá-lo no Visual Studio 2010 SP1.

Aviso de isenção de responsabilidade

Este é um documento preliminar e pode ser alterado substancialmente antes da versão comercial final do software descrito aqui.

As informações contidas neste documento representam a visão atual da Microsoft Corporation acerca das questões discutidas até a data da publicação. Como a Microsoft deve reagir às dinâmicas condições do mercado, essas informações não devem ser interpretadas como um compromisso por parte da Microsoft e a Microsoft não garante a precisão de qualquer informação apresentada após a data de publicação.

Este whitepaper é apenas para fins informativos. A MICROSOFT NÃO OFERECE GARANTIA, EXPRESSA, IMPLÍCITA OU ESTATUTÁRIA, DAS INFORMAÇÕES CONTIDAS NESTE DOCUMENTO.

Obedecer a todas as leis de direitos autorais aplicáveis é responsabilidade do usuário. Sem limitar os direitos autorais, nenhuma parte deste documento pode ser reproduzida, armazenada ou introduzida em um sistema de recuperação, ou transmitida de qualquer forma ou por qualquer meio (seja eletrônico, mecânico, fotocópia, gravação ou outro), ou para qualquer finalidade, sem a permissão expressa e por escrito da Microsoft Corporation.

A Microsoft pode ter patentes ou requisições para obtenção de patente, marcas comerciais, direitos autorais ou outros direitos de propriedade intelectual que abrangem o conteúdo deste documento. A posse deste documento não lhe confere nenhum direito sobre patentes, marcas comerciais, direitos autorais ou outros direitos de propriedade intelectual, salvo aqueles expressamente mencionados em um contrato de licença, por escrito, da Microsoft.

Salvo indicação em contrário, os exemplos de empresas, organizações, produtos, nomes de domínio, endereços de e-mail, logotipos, pessoas, lugares e eventos aqui descritos são fictícios e nenhuma associação com qualquer empresa, organização, produto, nome de domínio, endereço de e-mail, logotipo, pessoa, lugar ou evento real é intencional ou deve ser inferida.

© 2012 Microsoft Corporation. Todos os direitos reservados.

Microsoft e Windows são marcas registradas ou comerciais da Microsoft Corporation nos Estados Unidos e/ou em outros países.

Os nomes de empresas reais e produtos mencionados aqui podem ser marcas comerciais de seus respectivos proprietários.