Compartilhar via


Notas de versão do ASP.NET and Web Tools para Visual Studio 2013

pela Microsoft

Este documento descreve a versão do ASP.NET e das Ferramentas Web para Visual Studio 2013.

Contents

Novos recursos no ASP.NET e nas ferramentas da Web para Visual Studio 2013

Notas de instalação

ASP.NET e Web Tools para Visual Studio 2013 são empacotados no instalador principal e podem ser baixados aqui.

Documentação

Tutoriais e outras informações sobre o ASP.NET e as Ferramentas Web para Visual Studio 2013 estão disponíveis no site ASP.NET.

Requisitos de software

ASP.NET e Web Tools requerem o Visual Studio 2013.

Novos recursos no ASP.NET e nas ferramentas da Web para Visual Studio 2013

As seções a seguir descrevem os recursos que foram introduzidos na versão.

Um ASP.NET

Com o lançamento do Visual Studio 2013, demos um passo em direção à unificação da experiência de uso de tecnologias ASP.NET, para que você possa misturar e combinar facilmente as que deseja. Por exemplo, você pode iniciar um projeto usando o MVC e adicionar facilmente páginas do Web Forms ao projeto posteriormente ou criar o scaffold de APIs da Web em um projeto do Web Forms. Uma ASP.NET é tornar mais fácil para você, como desenvolvedor, fazer as coisas que você ama em ASP.NET. Não importa qual tecnologia você escolha, você pode ter certeza de que está construindo sobre a estrutura subjacente confiável do One ASP.NET.

Nova experiência de projeto da Web

Aprimoramos a experiência de criação de novos projetos Web no Visual Studio 2013. Na caixa de diálogo Novo ASP.NET Projeto Web, você pode selecionar o tipo de projeto desejado, configurar qualquer combinação de tecnologias (Web Forms, MVC, API Web), configurar opções de autenticação e adicionar um projeto de teste de unidade.

Projeto Novo ASP.NET

A nova caixa de diálogo permite que você altere as opções de autenticação padrão para muitos dos modelos. Por exemplo, ao criar um projeto de Web Forms ASP.NET, você pode selecionar qualquer uma das seguintes opções:

  • Sem Autenticação
  • Contas de usuário individuais (ASP.NET login de associação ou provedor social)
  • Contas Organizacionais (Active Directory em um aplicativo da Internet)
  • Autenticação do Windows (Active Directory em um aplicativo de intranet)

Opções de autenticação

Para obter mais informações sobre as novas opções de autenticação, consulte ASP.NET Identidade mais adiante neste documento.

ASP.NET andaimes

ASP.NET Scaffolding é uma estrutura de geração de código para aplicativos da Web ASP.NET. Isso facilita a adição de código clichê ao seu projeto que interage com um modelo de dados.

Nas versões anteriores do Visual Studio, o scaffolding era limitado a ASP.NET projetos MVC. Com o Visual Studio 2013, agora você pode usar scaffolding para qualquer projeto ASP.NET, incluindo Web Forms. No momento, o Visual Studio 2013 não dá suporte à geração de páginas para um projeto Web Forms, mas você ainda pode usar scaffolding com Web Forms adicionando dependências MVC ao projeto. O suporte para gerar páginas para Web Forms será adicionado em uma atualização futura.

Ao usar scaffolding, garantimos que todas as dependências necessárias sejam instaladas no projeto. Por exemplo, se você começar com um projeto de ASP.NET Web Forms e, em seguida, usar scaffolding para adicionar um Controlador de API Web, os pacotes e referências NuGet necessários serão adicionados ao seu projeto automaticamente.

Para adicionar scaffolding MVC a um projeto Web Forms, adicione um Novo Item Scaffolded e selecione Dependências MVC 5 na janela de diálogo. Existem duas opções para andaimes MVC; Mínimo e cheio. Se você selecionar Mínimo, somente os pacotes NuGet e as referências para ASP.NET MVC serão adicionados ao seu projeto. Se você selecionar a opção Completo, as dependências mínimas serão adicionadas, bem como os arquivos de conteúdo necessários para um projeto MVC.

O suporte para controladores assíncronos de scaffolding usa os novos recursos assíncronos do Entity Framework 6.

Para obter mais informações e tutoriais, consulte ASP.NET Visão geral do scaffolding.

O novo recurso Link do Navegador permite conectar vários navegadores ao Visual Studio e atualizá-los clicando em um botão na barra de ferramentas. Você pode conectar vários navegadores ao seu site de desenvolvimento, incluindo emuladores móveis, e clicar em atualizar para atualizar todos os navegadores ao mesmo tempo. O Browser Link também expõe uma API para permitir que os desenvolvedores escrevam extensões do Browser Link.

Captura de tela do menu do Visual Studio, com o ícone Atualizar realçado e o Painel de Link do Navegador realçado no menu suspenso.

Ao permitir que os desenvolvedores aproveitem a API de Link do Navegador, torna-se possível criar cenários muito avançados que cruzam os limites entre o Visual Studio e qualquer navegador conectado. O Web Essentials aproveita a API para criar uma experiência integrada entre o Visual Studio e as ferramentas de desenvolvedor do navegador, emuladores móveis de controle remoto e muito mais.

Aprimoramentos do Editor Web do Visual Studio

O Visual Studio 2013 inclui um novo editor HTML para arquivos Razor e arquivos HTML em aplicativos Web. O novo editor de HTML fornece um único esquema unificado baseado em HTML5. Ele tem preenchimento automático de chaves, interface do usuário do jQuery e atributo AngularJS IntelliSense, agrupamento de atributo IntelliSense, ID e nome de classe Intellisense e outras melhorias, incluindo melhor desempenho, formatação e SmartTags.

A captura de tela a seguir demonstra o uso do atributo de inicialização IntelliSense no editor de HTML.

Intellisense no editor de HTML

O Visual Studio 2013 também vem com editores CoffeeScript e LESS internos. O editor LESS vem com todos os recursos interessantes do editor CSS e possui Intellisense específico para variáveis e mixins em todos os documentos LESS da @import cadeia.

Suporte a Aplicativos Web do Serviço de Aplicativo do Azure no Visual Studio

No Visual Studio 2013 com o SDK do Azure para .NET 2.2, você pode usar o Gerenciador de Servidores para interagir diretamente com seus aplicativos Web remotos. Você pode entrar em sua conta do Azure, criar novos aplicativos Web, configurar aplicativos, exibir logs em tempo real e muito mais. Em breve após o lançamento do SDK 2.2, você poderá executar no modo de depuração remotamente no Azure. A maioria dos novos recursos dos Aplicativos Web do Serviço de Aplicativo do Azure também funciona no Visual Studio 2012 quando você instala a versão atual do SDK do Azure para .NET.

Para saber mais, consulte os recursos a seguir:

Aprimoramentos de publicação na Web

O Visual Studio 2013 inclui recursos novos e aprimorados de Publicação na Web. Veja algumas opções:

Para obter mais informações sobre ASP.NET implantação na Web, consulte o site ASP.NET.

NuGet 2.7

O NuGet 2.7 inclui um conjunto avançado de novos recursos que são descritos em detalhes nas Notas de versão do NuGet 2.7.

Esta versão do NuGet também elimina a necessidade de fornecer consentimento explícito para o recurso de restauração de pacote do NuGet para baixar pacotes. O consentimento (e a caixa de seleção associada na caixa de diálogo de preferências do NuGet) agora é concedido instalando o NuGet. Agora, a restauração de pacotes simplesmente funciona por padrão.

Web Forms do ASP.NET

Um ASP.NET

Os modelos de projeto do Web Forms se integram perfeitamente à nova experiência do One ASP.NET. Você pode adicionar suporte a MVC e API Web ao seu projeto Web Forms e pode configurar a autenticação usando o assistente de criação de projeto One ASP.NET.

ASP.NET Identity

Os modelos de projeto do Web Forms suportam a nova estrutura ASP.NET Identity. Além disso, os modelos agora dão suporte à criação de um projeto de intranet Web Forms.

Bootstrap

Os modelos do Web Forms usam o Bootstrap para fornecer uma aparência elegante e responsiva que você pode personalizar facilmente.

ASP.NET MVC 5

Um ASP.NET

Os modelos de projeto do MVC da Web se integram perfeitamente à nova experiência do One ASP.NET. Você pode personalizar seu projeto MVC e configurar a autenticação usando o assistente de criação de projeto One ASP.NET. Um tutorial introdutório ao ASP.NET MVC 5 pode ser encontrado em Introdução ao ASP.NET MVC 5.

Para obter informações sobre como atualizar projetos MVC 4 para MVC 5, consulte Como atualizar um projeto ASP.NET MVC 4 e API Web para ASP.NET MVC 5 e API Web 2.

ASP.NET Identity

Os modelos de projeto MVC foram atualizados para usar ASP.NET Identity para autenticação e gerenciamento de identidade. Um tutorial com a autenticação do Facebook e do Google e a nova API de associação pode ser encontrado em Criar um aplicativo MVC 5 ASP.NET com o Facebook e o Google OAuth2 e OpenID Sign-on e Criar um aplicativo MVC ASP.NET com autenticação e banco de dados SQL e implantar no Serviço de Aplicativo do Azure.

Bootstrap

O modelo de projeto MVC foi atualizado para usar o Bootstrap para fornecer uma aparência elegante e responsiva que você pode personalizar facilmente.

Filtros de autenticação

Os filtros de autenticação são um novo tipo de filtro no MVC ASP.NET que é executado antes dos filtros de autorização no pipeline do MVC ASP.NET e permite que você especifique a lógica de autenticação por ação, por controlador ou globalmente para todos os controladores. Os filtros de autenticação processam credenciais na solicitação e fornecem uma entidade correspondente. Os filtros de autenticação também podem adicionar desafios de autenticação em resposta a solicitações não autorizadas.

Substituições de filtro

Agora você pode substituir quais filtros se aplicam a um determinado método de ação ou controlador especificando um filtro de substituição. Os filtros de substituição especificam um conjunto de tipos de filtro que não devem ser executados para um determinado escopo (ação ou controlador). Isso permite que você configure filtros que se aplicam globalmente, mas excluem determinados filtros globais da aplicação a ações ou controladores específicos.

Roteamento de atributo

ASP.NET MVC agora oferece suporte ao roteamento de atributos, graças a uma contribuição de Tim McCall, autor do http://attributerouting.net. Com o roteamento de atributos, você pode especificar suas rotas anotando suas ações e controladores.

ASP.NET Web API 2

Roteamento de atributo

ASP.NET API Web agora oferece suporte ao roteamento de atributos, graças a uma contribuição de Tim McCall, autor do http://attributerouting.net. Com o roteamento de atributos, você pode especificar suas rotas de API Web anotando suas ações e controladores da seguinte forma:

[RoutePrefix("orders")] 
public class OrdersController : ApiController 
{ 
    [Route("{id}")] 
    public Order Get(int id) { } 
    [Route("{id}/approve")] 
    public Order Approve(int id) { } 
}

O roteamento de atributos oferece mais controle sobre os URIs em sua API Web. Por exemplo, você pode definir facilmente uma hierarquia de recursos usando um único controlador de API:

public class MoviesController : ApiController 
{ 
    [Route("movies")] 
    public IEnumerable<Movie> Get() { } 
    [Route("actors/{actorId}/movies")] 
    public IEnumerable<Movie> GetByActor(int actorId) { } 
    [Route("directors/{directorId}/movies")] 
    public IEnumerable<Movie> GetByDirector(int directorId) { } 
}

O roteamento de atributos também fornece uma sintaxe conveniente para especificar parâmetros opcionais, valores padrão e restrições de rota:

// Optional parameter
[Route("people/{name?}")]
// Default value
[Route("people/{name=Dan}")]
// Constraint: Alphabetic characters only. 
[Route("people/{name:alpha}")]

Para obter mais informações sobre roteamento de atributos, consulte Roteamento de atributos na API Web 2.

OAuth 2.0

Os modelos de projeto de API Web e Aplicativo de Página Única agora dão suporte à autorização usando o OAuth 2.0. O OAuth 2.0 é uma estrutura para autorizar o acesso do cliente a recursos protegidos. Funciona para uma variedade de clientes, incluindo navegadores e dispositivos móveis.

O suporte para OAuth 2.0 é baseado no novo middleware de segurança fornecido pelos componentes do Microsoft OWIN para autenticação de portador e implementação da função de servidor de autorização. Como alternativa, os clientes podem ser autorizados usando um servidor de autorização organizacional, como o Azure Active Directory ou o ADFS no Windows Server 2012 R2.

Melhorias do OData

Suporte para $select, $expand, $batch e $value

ASP.NET OData da API Web agora tem suporte total para $select, $expand e $value. Você também pode usar $batch para envio em lote de solicitações e processamento de conjuntos de alterações.

As opções $select e $expand permitem alterar a forma dos dados retornados de um ponto de extremidade OData. Para obter mais informações, consulte Introdução ao suporte a $select e $expand no OData da API Web.

Extensibilidade aprimorada

Os formatadores OData agora são extensíveis. Você pode adicionar metadados de entrada Atom, oferecer suporte a entradas de link de mídia e fluxo nomeado, adicionar anotações de instância e personalizar como os links são gerados.

Suporte sem tipo

Agora você pode criar serviços OData sem precisar definir tipos CLR para seus tipos de entidade. Em vez disso, seus controladores OData podem usar ou retornar instâncias de IEdmObject, que são os formatadores OData serializar/desserializar.

Reutilizar um modelo existente

Se você já tiver um EDM (modelo de dados de entidade) existente, agora poderá reutilizá-lo diretamente, em vez de precisar criar um novo. Por exemplo, se você estiver usando o Entity Framework, poderá usar o EDM que o EF cria para você.

Envio em lote de solicitações

O envio em lote de solicitações combina várias operações em uma única solicitação HTTP POST, para reduzir o tráfego de rede e fornecer uma interface de usuário mais suave e menos tagarela. ASP.NET API Web agora dá suporte a várias estratégias para envio em lote de solicitações:

  • Use o ponto de extremidade $batch de um serviço OData.
  • Empacote várias solicitações em uma única solicitação MIME com várias partes.
  • Use um formato de envio em lote personalizado.

Para habilitar o envio em lote de solicitações, basta adicionar uma rota com um manipulador de envio em lote à configuração da API Web:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
        config.Routes.MapHttpBatchRoute( 
            routeName: "WebApiBatch", 
            routeTemplate: "api/batch", 
            batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer)); 
    } 
}

Você também pode controlar se as solicitações são executadas sequencialmente ou em qualquer ordem.

Cliente de API Web ASP.NET portátil

Agora você pode usar o Cliente de API Web do ASP.NET para criar bibliotecas de classes portáteis que funcionam em seus aplicativos da Windows Store e do Windows Phone 8. Você também pode criar formatadores portáteis que podem ser compartilhados entre cliente e servidor.

Capacidade de teste aprimorada

A API Web 2 facilita muito o teste de unidade de seus controladores de API. Basta instanciar o controlador de API com a mensagem de solicitação e a configuração e, em seguida, chamar o método de ação que você deseja testar. Também é fácil simular a classe UrlHelper , para métodos de ação que executam a geração de links.

IHttpActionResult

Agora você pode implementar IHttpActionResult para encapsular o resultado de seus métodos de ação da API Web. Um IHttpActionResult retornado de um método de ação da API Web é executado pelo runtime da API Web ASP.NET para produzir a mensagem de resposta resultante. Um IHttpActionResult pode ser retornado de qualquer ação da API Web para simplificar o teste de unidade da implementação da API Web. Por conveniência, várias implementações IHttpActionResult são fornecidas prontas para uso, incluindo resultados para retornar códigos de status específicos, conteúdo formatado ou respostas negociadas por conteúdo.

HttpRequestContext

O novo HttpRequestContext rastreia qualquer estado vinculado à solicitação, mas que não esteja imediatamente disponível na solicitação. Por exemplo, você pode usar o HttpRequestContext para obter dados de rota, a entidade de segurança associada à solicitação, o certificado do cliente, o UrlHelper e a raiz do caminho virtual. Você pode criar facilmente um HttpRequestContext para fins de teste de unidade.

Como a entidade de segurança da solicitação é fluída com a solicitação em vez de depender de Thread.CurrentPrincipal, a entidade agora está disponível durante todo o tempo de vida da solicitação enquanto ela está no pipeline da API Web.

CORS

Graças a outra grande contribuição de Brock Allen, ASP.NET agora oferece suporte total ao Cross Origin Request Sharing (CORS).

A segurança do navegador impede que uma página da Web envie solicitações do AJAX para outro domínio. O CORS é um padrão W3C que permite que um servidor relaxe a política de mesma origem. Usando o CORS, um servidor pode explicitamente permitir algumas solicitações entre origens e rejeitar outras.

A API Web 2 agora dá suporte ao CORS, incluindo o tratamento automático de solicitações de simulação. Para saber mais, confira Permitindo solicitações entre origens na ASP.NET Web API.

Filtros de autenticação

Os filtros de autenticação são um novo tipo de filtro na API Web que é executado antes dos filtros de autorização no pipeline da API Web ASP.NET e permite que você especifique ASP.NET a lógica de autenticação por ação, por controlador ou globalmente para todos os controladores. Os filtros de autenticação processam credenciais na solicitação e fornecem uma entidade correspondente. Os filtros de autenticação também podem adicionar desafios de autenticação em resposta a solicitações não autorizadas.

Substituições de filtro

Agora você pode substituir quais filtros se aplicam a um determinado método de ação ou controlador, especificando um filtro de substituição. Os filtros de substituição especificam um conjunto de tipos de filtro que não devem ser executados para um determinado escopo (ação ou controlador). Isso permite que você adicione filtros globais, mas exclua alguns de ações ou controladores específicos.

Integração OWIN

ASP.NET API Web agora dá suporte total ao OWIN e pode ser executada em qualquer host compatível com OWIN. Também está incluído um HostAuthenticationFilter que fornece integração com o sistema de autenticação OWIN.

Com a integração do OWIN, você pode hospedar automaticamente a API Web em seu próprio processo junto com outro middleware OWIN, como o SignalR. Para obter mais informações, consulte Usar o OWIN para auto-hospedar ASP.NET API Web.

ASP.NET SignalR 2.0

As seções a seguir descrevem os recursos do SignalR 2.0.

Para obter um exemplo de como atualizar um projeto 1.x existente para o SignalR 2.0, consulte Atualizando um projeto do SignalR 1.x.

Construído em OWIN

O SignalR 2.0 é totalmente baseado no OWIN (a Interface Web Aberta para .NET). Essa alteração torna o processo de configuração do SignalR muito mais consistente entre aplicativos SignalR hospedados na Web e auto-hospedados, mas também exigiu várias alterações de API.

MapHubs e MapConnection agora são MapSignalR

Para compatibilidade com os padrões OWIN, esses métodos foram renomeados para MapSignalR. MapSignalRchamado sem parâmetros mapeará todos os hubs (como MapHubs na versão 1.x); para mapear objetos PersistentConnection individuais, especifique o tipo de conexão como o parâmetro type e a extensão de URL para a conexão como o primeiro argumento.

O MapSignalR método é chamado em uma classe de inicialização Owin. O Visual Studio 2013 contém um novo modelo para uma classe de inicialização Owin; Para usar esse modelo, faça o seguinte:

  1. Clique com o botão direito do mouse no projeto
  2. Selecione Adicionar, Novo Item...
  3. Selecione a classe Owin Startup. Nomeie a nova classe Startup.cs.

Em um aplicativo Web, a classe de inicialização Owin que contém o MapSignalR método é adicionada ao processo de inicialização do Owin usando uma entrada no nó de configurações do aplicativo do arquivo Web.Config, conforme mostrado abaixo.

Em um aplicativo auto-hospedado, a classe Startup é passada como o parâmetro type do WebApp.Start método.

Mapeando hubs e conexões no SignalR 1.x (do arquivo de aplicativo global em um aplicativo Web):

protected void Application_Start(object sender, EventArgs e) 
{
    // Map all hubs to "/signalr"
    RouteTable.Routes.MapHubs();
    // Map the Echo PersistentConnection to "/echo"
    RouteTable.Routes.MapConnection<myconnection>("echo", "/echo");
}

Mapeando hubs e conexões no SignalR 2.0 (de um arquivo de classe de inicialização do Owin):

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;

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

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Map all hubs to "/signalr"
            app.MapSignalR();
            // Map the Echo PersistentConnection to "/echo"
            app.MapSignalR<echoconnection>("/echo");
        }
    }
}

Em um aplicativo auto-hospedado, a classe Startup é passada como o parâmetro type para o WebApp.Start método, conforme mostrado abaixo.

string url = "http://localhost:8080";
using (WebApp.Start<startup>(url))
{
    Console.WriteLine("Server running on {0}", url);
    Console.ReadLine();
}

Suporte entre domínios

No SignalR 1.x, as solicitações entre domínios eram controladas por um único sinalizador EnableCrossDomain. Esse sinalizador controlava as solicitações JSONP e CORS. Para maior flexibilidade, todo o suporte ao CORS foi removido do componente de servidor do SignalR (os clientes JavaScript ainda usam o CORS normalmente se for detectado que o navegador dá suporte a ele) e um novo middleware OWIN foi disponibilizado para dar suporte a esses cenários.

No SignalR 2.0, se o JSONP for necessário no cliente (para dar suporte a solicitações entre domínios em navegadores mais antigos), ele precisará ser habilitado explicitamente definindo EnableJSONP o HubConfiguration objeto como true, conforme mostrado abaixo. O JSONP está desabilitado por padrão, pois é menos seguro que o CORS.

Para adicionar o novo middleware CORS no SignalR 2.0, adicione a Microsoft.Owin.Cors biblioteca ao seu projeto e chame UseCors antes do middleware do SignalR, conforme mostrado na seção abaixo.

Adicionando Microsoft.Owin.Cors ao seu projeto: Para instalar essa biblioteca, execute o seguinte comando no Console do Gerenciador de Pacotes:

Install-Package Microsoft.Owin.Cors

Este comando adicionará a versão 2.0.0 do pacote ao seu projeto.

Chamando UseCors

Os snippets de código a seguir demonstram como implementar conexões entre domínios no SignalR 1.x e 2.0.

Implementando solicitações entre domínios no SignalR 1.x (do arquivo de aplicativo global)

protected void Application_Start(object sender, EventArgs e) 
{
    var hubConfiguration = new HubConfiguration();
    hubConfiguration.EnableCrossDomain = true;
    RouteTable.Routes.MapHubs(hubConfiguration);
}

Implementando solicitações entre domínios no SignalR 2.0 (de um arquivo de código C#)

O código a seguir demonstra como habilitar o CORS ou o JSONP em um projeto do SignalR 2.0. Este exemplo de código usa Map e RunSignalR em vez de MapSignalR, para que o middleware CORS seja executado apenas para as solicitações do SignalR que exigem suporte a CORS (em vez de todo o tráfego no caminho especificado em MapSignalR.) Map também pode ser usado para qualquer outro middleware que precise ser executado para um prefixo de URL específico, em vez de para todo o aplicativo.

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;

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

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Branch the pipeline here for requests that start with "/signalr"
            app.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can 
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);
                var hubConfiguration = new HubConfiguration 
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
        }
    }
}

Suporte para iOS e Android via MonoTouch e MonoDroid

O suporte foi adicionado para clientes iOS e Android usando componentes MonoTouch e MonoDroid da biblioteca Xamarin. Para obter mais informações sobre como usá-los, consulte Usando componentes do Xamarin. Esses componentes estarão disponíveis no Repositório Xamarin quando a versão RTW do SignalR estiver disponível.

### Cliente .NET portátil

Para facilitar melhor o desenvolvimento multiplataforma, os clientes Silverlight, WinRT e Windows Phone foram substituídos por um único cliente .NET portátil que dá suporte às seguintes plataformas:

  • NET 4.5
  • Silverlight 5
  • WinRT (.NET para aplicativos da Windows Store)
  • Windows Phone 8

Novo pacote de auto-hospedagem

Agora há um pacote NuGet para facilitar a introdução ao SignalR Self-Host (aplicativos SignalR hospedados em um processo ou outro aplicativo, em vez de serem hospedados em um servidor Web). Para atualizar um projeto de auto-host criado com o SignalR 1.x, remova o pacote Microsoft.AspNet.SignalR.Owin e adicione o pacote Microsoft.AspNet.SignalR.SelfHost. Para obter mais informações sobre como começar a usar o pacote de auto-host, consulte Tutorial: SignalR Self-Host.

Suporte a servidor compatível com versões anteriores

Nas versões anteriores do SignalR, as versões do pacote do SignalR usadas no cliente e no servidor precisavam ser idênticas. Para dar suporte a aplicativos de cliente espesso que seriam difíceis de atualizar, o SignalR 2.0 agora dá suporte ao uso de uma versão mais recente do servidor com um cliente mais antigo. Observação: o SignalR 2.0 não dá suporte a servidores criados com versões mais antigas com clientes mais recentes.

Removido o suporte ao servidor para .NET 4.0

O SignalR 2.0 descartou o suporte para interoperabilidade de servidor com o .NET 4.0. O .NET 4.5 deve ser usado com servidores SignalR 2.0. Ainda há um cliente .NET 4.0 para o SignalR 2.0.

Enviando uma mensagem para uma lista de clientes e grupos

No SignalR 2.0, é possível enviar uma mensagem usando uma lista de IDs de cliente e grupo. Os snippets de código a seguir demonstram como fazer isso.

Enviando uma mensagem para uma lista de clientes e grupos usando PersistentConnection

using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
public class ChatConnection : PersistentConnection
{
    static List<string> ConnectionIds = new List<string>();
    static List<string> groups = new List<string>{"chatGroup", "chatGroup2"};
    protected override System.Threading.Tasks.Task OnReceived(IRequest request, string connectionId, string data)
    {
        Connection.Send(ConnectionIds, data);
        Groups.Send(groups, data);
        return base.OnReceived(request, connectionId, data);
    }
    protected override System.Threading.Tasks.Task OnConnected(IRequest request, string connectionId)
    {
        ConnectionIds.Add(connectionId);
        Groups.Add(connectionId, "chatGroup");
        return base.OnConnected(request, connectionId);
    }
    protected override System.Threading.Tasks.Task OnDisconnected(IRequest request, string connectionId)
    {
        ConnectionIds.Remove(connectionId);
        return base.OnDisconnected(request, connectionId);
    }
}

Enviando uma mensagem para uma lista de clientes e grupos usando Hubs

using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
public class ChatHub : Hub
{
    static List<string> ConnectionIds = new List<string>();
    static List<string> groups = new List<string> { "chatGroup", "chatGroup2" };
    public void Send(string name, string message)
    {
        // Call the broadcastMessage method to update clients.
        Clients.Clients(ConnectionIds).broadcastMessage(name, message);
        Clients.Groups(groups).broadcastMessage(name, message);
    }
    public override System.Threading.Tasks.Task OnConnected()
    {
        ConnectionIds.Add(Context.ConnectionId);
        Groups.Add(Context.ConnectionId, "chatGroup");
        return base.OnConnected();
    }
    public override System.Threading.Tasks.Task OnDisconnected()
    {
        ConnectionIds.Remove(Context.ConnectionId);
        return base.OnDisconnected();
    }
}

Enviando uma mensagem para um usuário específico

Esse recurso permite que os usuários especifiquem qual é o userId com base em um IRequest por meio de uma nova interface IUserIdProvider:

A interface IUserIdProvider

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}

Por padrão, haverá uma implementação que usa o IPrincipal.Identity.Name do usuário como o nome do usuário.

Nos hubs, você poderá enviar mensagens para esses usuários por meio de uma nova API:

Usando a API Clients.User

public class MyHub : Hub
{
    public void Send(string userId, string message)
    {
        Clients.User(userId).send(message);
    }
}

Melhor suporte para tratamento de erros

Os usuários agora podem lançar HubException de qualquer invocação de hub. O construtor do HubException pode receber uma mensagem de cadeia de caracteres e um objeto de dados de erro extras. O SignalR serializará automaticamente a exceção e a enviará ao cliente, onde ela será usada para rejeitar/falhar a invocação do método de hub.

A configuração show detailed hub exceptions não tem influência sobre HubException ser enviado de volta ao cliente ou não; ele é sempre enviado.

Código do lado do servidor demonstrando o envio de um HubException para o cliente

public class MyHub : Hub
{
    public void Send(string message)
    {
        if(message.Contains("<script>"))
        {
            throw new HubException("This message will flow to the client", new { user = Context.User.Identity.Name, message = message });
        }

        Clients.All.send(message);
    }
}

Código do cliente JavaScript demonstrando a resposta a um HubException enviado do servidor

myHub.server.send("<script>")
            .fail(function (e) {
                if (e.source === 'HubException') {
                    console.log(e.message + ' : ' + e.data.user);
                }
            });

Código do cliente .NET demonstrando a resposta a uma HubException enviada do servidor

try
{
    await myHub.Invoke("Send", "<script>");
}
catch(HubException ex)
{
    Conosle.WriteLine(ex.Message);
}

Teste de unidade mais fácil de hubs

O SignalR 2.0 inclui uma interface chamada IHubCallerConnectionContext em Hubs que facilita a criação de invocações fictícias do lado do cliente. Os snippets de código a seguir demonstram o uso dessa interface com os equipamentos de teste populares xUnit.net e moq.

Teste de unidade do SignalR com xUnit.net

[Fact]
public void HubsAreMockableViaDynamic()
{
    bool sendCalled = false;
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();
    hub.Clients = mockClients.Object;
    dynamic all = new ExpandoObject();
    all.send = new Action<string>(message =>
    {
        sendCalled = true;
    });
    mockClients.Setup(m => m.All).Returns((ExpandoObject)all);
    hub.Send("foo");
    Assert.True(sendCalled);
}

Teste de unidade SignalR com moq

[Fact]
public interface IClientContract
{
    void send(string message);
}
public void HubsAreMockableViaType()
{
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();
    var all = new Mock<IClientContract>();
    hub.Clients = mockClients.Object;
    all.Setup(m => m.send(It.IsAny<string>())).Verifiable();
    mockClients.Setup(m => m.All).Returns(all.Object);
    hub.Send("foo");
    all.VerifyAll();

Tratamento de erros JavaScript

No SignalR 2.0, todos os retornos de chamada de tratamento de erros do JavaScript retornam objetos de erro do JavaScript em vez de cadeias de caracteres brutas. Isso permite que o SignalR flua informações mais avançadas para seus manipuladores de erros. Você pode obter a exceção interna da source propriedade do erro.

Código do cliente JavaScript que manipula a exceção Start.Fail

connection.start().fail(function(e) {
    console.log('The error is: ' + e.message);
});

ASP.NET Identity

Novo sistema de associação ASP.NET

ASP.NET Identity é o novo sistema de associação para aplicativos ASP.NET. ASP.NET Identity facilita a integração de dados de perfil específicos do usuário com dados de aplicativos. ASP.NET Identity também permite que você escolha o modelo de persistência para perfis de usuário em seu aplicativo. Você pode armazenar os dados em um banco de dados do SQL Server ou outro dispositivo de armazenamento de dados, incluindo dispositivos de armazenamento de dados NoSQL como Tabelas de Armazenamento do Azure. Para obter mais informações, consulte Contas de usuário individuais em Criando ASP.NET projetos Web no Visual Studio 2013.

Autenticação baseada em declarações

ASP.NET agora dá suporte à autenticação baseada em declarações, em que a identidade do usuário é representada como um conjunto de declarações de um emissor confiável. Os usuários podem ser autenticados usando um nome de usuário e senha mantidos em um banco de dados de aplicativo ou usando provedores de identidade social (por exemplo: Contas da Microsoft, Facebook, Google, Twitter) ou usando contas organizacionais por meio do Azure Active Directory ou dos Serviços de Federação do Active Directory (ADFS).

Integração com o Azure Active Directory e o Windows Server Active Directory

Agora você pode criar projetos ASP.NET que usam o Azure Active Directory ou o Windows Server Active Directory (AD) para autenticação. Para obter mais informações, consulte Contas organizacionais em Criando ASP.NET projetos Web no Visual Studio 2013.

Integração OWIN

ASP.NET autenticação agora é baseada no middleware OWIN que pode ser usado em qualquer host baseado em OWIN. Para obter mais informações sobre o OWIN, consulte a seção Componentes do Microsoft OWIN a seguir.

Componentes do Microsoft OWIN

A Interface Web Aberta para .NET (OWIN) define uma abstração entre servidores Web .NET e aplicativos Web. O OWIN desacopla o aplicativo Web do servidor, tornando os aplicativos Web independentes de host. Por exemplo, você pode hospedar um aplicativo Web baseado em OWIN no IIS ou hospedá-lo automaticamente em um processo personalizado.

As alterações introduzidas nos componentes do Microsoft OWIN (também conhecidos como projeto Katana) incluem novos componentes de servidor e host, novas bibliotecas auxiliares e middleware e novo middleware de autenticação.

Para obter mais informações sobre o OWIN e o Katana, consulte Novidades no OWIN e no Katana.

Observação: os aplicativos OWIN não podem ser executados no modo clássico do IIS; eles devem ser executados no modo integrado.

Observação: os aplicativos OWIN devem ser executados em total confiança.

Novos servidores e hosts

Com esta versão, novos componentes foram adicionados para habilitar cenários de auto-hospedagem. Esses componentes incluem os seguintes pacotes NuGet:

  • Microsoft.Owin.Host.HttpListener. Fornece um servidor OWIN que usa HttpListener para escutar solicitações HTTP e direcioná-las para o pipeline do OWIN.
  • Microsoft.Owin.Hosting Fornece uma biblioteca para desenvolvedores que desejam hospedar um pipeline OWIN em um processo personalizado, como um aplicativo de console ou serviço do Windows.
  • OwinHost. Fornece um executável autônomo que encapsula Microsoft.Owin.Hosting e permite que você hospede um pipeline OWIN sem precisar escrever um aplicativo host personalizado.

Além disso, o Microsoft.Owin.Host.SystemWeb pacote agora permite que o middleware forneça dicas ao servidor SystemWeb , indicando que o middleware deve ser chamado durante um estágio específico do pipeline ASP.NET. Esse recurso é particularmente útil para middleware de autenticação, que deve ser executado no início do pipeline ASP.NET.

Bibliotecas auxiliares e middleware

Embora você possa escrever componentes OWIN usando apenas as definições de função e tipo da especificação OWIN, o novo Microsoft.Owin pacote fornece um conjunto de abstrações mais amigável. Esse pacote combina vários pacotes anteriores (por exemplo, Owin.Extensions, Owin.Types) em um único modelo de objeto bem estruturado que pode ser facilmente usado por outros componentes OWIN. Na verdade, a maioria dos componentes do Microsoft OWIN agora usa esse pacote.

Observação

Os aplicativos OWIN não podem ser executados no modo clássico do IIS; eles devem ser executados no modo integrado.

Observação

Os aplicativos OWIN devem ser executados em total confiança.

Esta versão também inclui o pacote Microsoft.Owin.Diagnostics, que inclui middleware para validar um aplicativo OWIN em execução, além de middleware de página de erro para ajudar a investigar falhas.

Componentes de autenticação

Os seguintes componentes de autenticação estão disponíveis.

  • Microsoft.Owin.Security.ActiveDirectory. Habilita a autenticação usando serviços de diretório locais ou baseados em nuvem.
  • Microsoft.Owin.Security.Cookies Habilita a autenticação usando cookies. Este pacote foi anteriormente denominado Microsoft.Owin.Security.Forms.
  • Microsoft.Owin.Security.Facebook Habilita a autenticação usando o serviço baseado em OAuth do Facebook.
  • Microsoft.Owin.Security.Google Habilita a autenticação usando o serviço baseado em OpenID do Google.
  • Microsoft.Owin.Security.Jwt Habilita a autenticação usando tokens JWT.
  • Microsoft.Owin.Security.MicrosoftAccount Habilita a autenticação usando contas da Microsoft.
  • Microsoft.Owin.Security.OAuth. Fornece um servidor de autorização OAuth, bem como middleware para autenticar tokens de portador.
  • Microsoft.Owin.Security.Twitter Habilita a autenticação usando o serviço baseado em OAuth do Twitter.

Esta versão também inclui o pacote, que contém middleware Microsoft.Owin.Cors para processar solicitações HTTP de origem cruzada.

Observação

O suporte para assinatura JWT foi removido na versão final do Visual Studio 2013.

Entity Framework 6

Para obter uma lista de novos recursos e outras alterações no Entity Framework 6, consulte Histórico de versões do Entity Framework.

ASP.NET Razor 3

ASP.NET Razor 3 inclui os seguintes novos recursos:

  • Suporte para edição de guias. Anteriormente, o comando Formatar Documento, recuo automático e formatação automática no Visual Studio não funcionavam corretamente ao usar a opção Manter Guias. Essa alteração corrige a formatação do Visual Studio para o código Razor para formatação de guia.
  • Suporte para regras de reescrita de URL ao gerar links.
  • Remoção do atributo transparente de segurança.

    Observação

    Essa é uma alteração significativa e torna o Razor 3 incompatível com o MVC4 e versões anteriores, enquanto o Razor 2 é incompatível com o MVC5 ou assemblies compilados no MVC5.

=======

ASP.NET Suspensão de aplicativos

ASP.NET Suspensão de Aplicativo é um recurso revolucionário no .NET Framework 4.5.1 que altera radicalmente a experiência do usuário e o modelo econômico para hospedar um grande número de sites ASP.NET em um único computador. Para obter mais informações, consulte ASP.NET Suspensão de Aplicativo – hospedagem na Web .NET compartilhada responsiva.

Problemas conhecidos e alterações significativas

Esta seção descreve problemas conhecidos e alterações significativas no ASP.NET e nas Ferramentas Web para Visual Studio 2013.

NuGet

  • A nova restauração de pacote não funciona no Mono ao usar o arquivo SLN – será corrigida em um próximo download do nuget.exe e na atualização do pacote NuGet.CommandLine.
  • A nova restauração de pacote não funciona com projetos Wix – será corrigida em um próximo download de nuget.exe e atualização do pacote NuGet.CommandLine.

ASP.NET Web API

  1. ODataQueryOptions<T>.ApplyTo(IQueryable) nem sempre retorna IQueryable<T> , pois adicionamos suporte para $select e $expand.

    Nossas amostras anteriores para ODataQueryOptions<T> sempre converteram o valor de retorno de ApplyTo para IQueryable<T>. Isso funcionou anteriormente porque as opções de consulta com suporte anteriormente ($filter, $orderby, $skip, $top) não alteram a forma da consulta. Agora que apoiamos $select e $expand o valor de retorno de ApplyTo não será IQueryable<T> sempre.

    // Sample ODataQueryOptions<T> usage from earlier
    public IQueryable<Customer> Get(ODataQueryOptions<Customer> query)
    {
        IQueryable<customer> result="query.ApplyTo(_customers)" as iqueryable<customer>; return result;
    }
    

    Se você estiver usando o código de exemplo anterior, ele continuará funcionando se o cliente não enviar $select e $expand. No entanto, se você deseja oferecer suporte $select e $expand precisa alterar esse código para isso.

    public IHttpActionResult Get(ODataQueryOptions<Customer> query)
    {
        IQueryable result = query.ApplyTo(_customers);
        return Ok(result, result.GetType());
    }
     
    private IHttpActionResult Ok(object content, Type type)
    {
        Type resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
        return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
    }
    
  2. Request.Url ou RequestContext.Url é nulo durante uma solicitação em lote

    Em um cenário de envio em lote, UrlHelper é nulo quando acessado de Request.Url ou RequestContext.Url.

    A solução alternativa para esse problema é criar uma nova instância de UrlHelper, como no exemplo a seguir:

    Criando uma nova instância do UrlHelper

    if (RequestContext.Url == null)
    {
        RequestContext.Url = new UrlHelper(Request);
    }
    

ASP.NET MVC

  1. Ao usar MVC5 e OrgAuth, se você tiver exibições que fazem a validação do AntiForgerToken, poderá encontrar o seguinte erro ao postar dados na exibição:

    Erro:

    Erro de servidor no aplicativo '/'.

    Uma declaração do tipo http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier ou https://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider não estava presente no ClaimsIdentity fornecido. Para habilitar o suporte a token antifalsificação com autenticação baseada em declarações, verifique se o provedor de declarações configurado está fornecendo essas duas declarações nas instâncias ClaimsIdentity que ele gera. Se o provedor de declarações configurado usar um tipo de declaração diferente como um identificador exclusivo, ele poderá ser configurado definindo a propriedade estática AntiForgeryConfig.UniqueClaimTypeIdentifier.

    Solução alternativa:

    Adicione a seguinte linha em Global.asax para corrigi-lo:

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;

    Isso será corrigido para a próxima versão.

  2. Depois de atualizar um aplicativo MVC4 para MVC5, crie a solução e inicie-a. Você deve ver o seguinte erro:

    [UMA]System.Web.WebPages.Razor.Configuration.HostSection não pode ser convertido em [B]System.Web.WebPages.Razor.Configuration.HostSection. O tipo A se origina de 'System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' no contexto 'Default' no local 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'. O tipo B se origina de 'System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' no contexto 'Default' no local 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\6d05bbd0\e8b5908e\assembly\dl3\c9cbca63\f8910382_6273ce01\System.Web.WebPages.Razor.dll'.

    Para corrigir o erro acima, abra todos os arquivos Web.config (incluindo os da pasta Exibições) em seu projeto e faça o seguinte:

    1. Atualize todas as ocorrências da versão "4.0.0.0" de "System.Web.Mvc" para "5.0.0.0".

    2. Atualize todas as ocorrências da versão "2.0.0.0" de "System.Web.Helpers", "System.Web.WebPages" e "System.Web.WebPages.Razor" para "3.0.0.0"

      Por exemplo, depois de fazer as alterações acima, as associações de assembly devem ter esta aparência:

      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
      

      Para obter informações sobre como atualizar projetos MVC 4 para MVC 5, consulte Como atualizar um projeto ASP.NET MVC 4 e API Web para ASP.NET MVC 5 e API Web 2.

  3. Ao usar a validação do lado do cliente com a validação discreta do jQuery, a mensagem de validação às vezes está incorreta para um elemento de entrada HTML com type='number'. O erro de validação de um valor obrigatório ("O campo Idade é obrigatório") é mostrado quando um número inválido é inserido em vez da mensagem correta de que um número válido é necessário.

    Esse problema é comumente encontrado com código scaffolded para um modelo com uma propriedade inteira nas exibições Criar e Editar.

    Para contornar esse problema, altere o assistente do editor de:

    @Html.EditorFor(person => person.Age)

    Para:

    @Html.TextBoxFor(person => person.Age)

  4. ASP.NET MVC 5 não dá mais suporte à confiança parcial. Os projetos vinculados aos binários MVC ou WebAPI devem remover o atributo SecurityTransparent e o atributo AllowPartiallyTrustedCallers . A remoção desses atributos eliminará erros do compilador, como os seguintes.

    Attempt by security transparent method ‘MyComponent' to access security critical type 'System.Web.Mvc.MvcHtmlString' failed. Assembly 'PagedList.Mvc, Version=4.3.0.0, Culture=neutral, PublicKeyToken=abbb863e9397c5e1' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.

    Observe que, como efeito colateral, você não pode usar assemblies 4.0 e 5.0 no mesmo aplicativo. Você precisa atualizar todos eles para 5.0.

O modelo de SPA com autorização do Facebook pode causar instabilidade no IE enquanto o site estiver hospedado na zona da intranet

O modelo SPA fornece login externo com o Facebook. Quando o projeto criado com o modelo está sendo executado localmente, o logon pode fazer com que o IE falhe.

Solução:

  1. Hospede o site na zona da Internet; ou

  2. Teste o cenário em um navegador diferente do IE.

Scaffolding de Web Forms

O Web Forms Scaffolding foi removido do VS2013 e estará disponível em uma atualização futura para o Visual Studio. No entanto, você ainda pode usar scaffolding em um projeto Web Forms adicionando dependências MVC e gerando scaffolding para MVC. Seu projeto conterá uma combinação de Web Forms e MVC.

Para adicionar o MVC ao seu projeto Web Forms, adicione um novo item scaffolded e selecione MVC 5 Dependencies. Selecione Mínimo ou Completo, dependendo se você precisa de todos os arquivos de conteúdo, como scripts. Em seguida, adicione um item scaffolded para MVC, que criará exibições e um controlador em seu projeto.

Scaffolding MVC e API Web - HTTP 404, erro não encontrado

Se um erro for encontrado ao adicionar um item scaffolded a um projeto, é possível que seu projeto seja deixado em um estado inconsistente. Algumas das alterações feitas no scaffolding serão revertidas, mas outras alterações, como os pacotes NuGet instalados, não serão revertidas. Se as alterações de configuração de roteamento forem revertidas, os usuários receberão um erro HTTP 404 ao navegar para itens scaffolded.

Solução alternativa:

  • Para corrigir esse erro para o MVC, adicione um novo item scaffolded e selecione Dependências do MVC 5 (Mínimo ou Completo). Esse processo adicionará todas as alterações necessárias ao seu projeto.

  • Para corrigir esse erro da API Web:

    1. Adicione a classe WebApiConfig ao seu projeto.

      public static class WebApiConfig
      {
          public static void Register(HttpConfiguration config)
          {
              config.MapHttpAttributeRoutes();
              config.Routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
          }
      }
      
      Public Module WebApiConfig
          Public Sub Register(ByVal config As HttpConfiguration)
              config.MapHttpAttributeRoutes()
              config.Routes.MapHttpRoute(
                name:="DefaultApi",
                routeTemplate:="api/{controller}/{id}",
                defaults:=New With {.id = RouteParameter.Optional}
              )
          End Sub
      End Module
      
    2. Configure WebApiConfig.Register no método Application_Start em Global.asax da seguinte maneira:

      public class WebApiApplication : System.Web.HttpApplication
      {
          protected void Application_Start()
          {
              GlobalConfiguration.Configure(WebApiConfig.Register);    
          }
      }
      
      Public Class WebApiApplication
           Inherits System.Web.HttpApplication
       
           Sub Application_Start()     
             GlobalConfiguration.Configure(AddressOf WebApiConfig.Register)       
           End Sub
      End Class