适用于 Visual Studio 2013 的 ASP.NET 和 Web 工具发行说明

Microsoft

本文档介绍Visual Studio 2013的 ASP.NET 和 Web 工具版本。

目录

适用于 Visual Studio 2013 的 ASP.NET 和 Web 工具 中的新增功能

安装说明

Visual Studio 2013 ASP.NET 和 Web 工具捆绑在 main 安装程序中,可在此处下载。

文档

有关Visual Studio 2013 ASP.NET 和 Web 工具的教程和其他信息,请参阅 ASP.NET 网站

软件要求

ASP.NET 和 Web 工具需要Visual Studio 2013。

适用于 Visual Studio 2013 的 ASP.NET 和 Web 工具 中的新增功能

以下部分介绍版本中引入的功能。

一个 ASP.NET

随着Visual Studio 2013的发布,我们迈出了一步,统一使用 ASP.NET 技术的体验,以便你可以轻松地混合和匹配所需的技术。 例如,可以使用 MVC 启动项目,并在以后轻松地将Web Forms页添加到项目,或在Web Forms项目中搭建 Web API。 其中一 ASP.NET 就是让开发人员更轻松地在 ASP.NET 中完成自己喜欢的事情。 无论你选择哪种技术,你都可以确信自己是在 One ASP.NET 的受信任基础框架上构建的。

新建 Web 项目体验

我们增强了在 Visual Studio 2013 中创建新 Web 项目的体验。 在“新建 ASP.NET Web 项目”对话框中,可以选择所需的项目类型、配置 (Web Forms、MVC、Web API) 的任意技术组合、配置身份验证选项,以及添加单元测试项目。

新建 ASP.NET 项目

通过新对话框,可以更改许多模板的默认身份验证选项。 例如,创建 ASP.NET Web Forms项目时,可以选择以下任一选项:

  • 无身份验证
  • 个人用户帐户 (ASP.NET 成员身份或社交提供程序登录)
  • Internet 应用程序中 (Active Directory 的组织帐户)
  • Intranet 应用程序中的 Windows 身份验证 (Active Directory)

身份验证选项

有关创建 Web 项目的新过程的详细信息,请参阅在 Visual Studio 2013 中创建 ASP.NET Web 项目。 有关新身份验证选项的详细信息,请参阅本文档后面的 ASP.NET 标识

ASP.NET 基架

ASP.NET 基架是一种适用于 ASP.NET Web 应用程序的代码生成框架。 它可以轻松地将样本代码添加到与数据模型交互的项目。

在早期版本的 Visual Studio 中,基架仅限于 ASP.NET MVC 项目。 使用 Visual Studio 2013,现在可以为任何 ASP.NET 项目(包括Web Forms)使用基架。 Visual Studio 2013当前不支持为Web Forms项目生成页面,但你仍可以通过向项目添加 MVC 依赖项,将基架与Web Forms结合使用。 将来的更新中将添加对生成Web Forms页面的支持。

使用基架时,我们确保在项目中安装所有必需的依赖项。 例如,如果从 ASP.NET Web Forms项目开始,然后使用基架添加 Web API 控制器,则所需的 NuGet 包和引用会自动添加到项目中。

若要将 MVC 基架添加到Web Forms项目,请添加“新建基架项”,并在对话框窗口中选择“MVC 5 依赖项”。 有两个选项可用于搭建 MVC 基架:最小和完整。 如果选择“最小”,则仅向项目添加 ASP.NET MVC 的 NuGet 包和引用。 如果选择“完整”选项,则会添加“最小依赖项”以及 MVC 项目所需的内容文件。

对基架异步控制器的支持使用 Entity Framework 6 中的新异步功能。

有关详细信息和教程,请参阅 ASP.NET 基架概述

新的 浏览器链接 功能允许将多个浏览器连接到 Visual Studio,并通过单击工具栏中的按钮刷新所有这些浏览器。 可以将多个浏览器(包括移动模拟器)连接到开发站点,然后单击“刷新”以同时刷新所有浏览器。 浏览器链接还公开了一个 API,使开发人员能够编写浏览器链接扩展。

Visual Studio 菜单的屏幕截图,其中突出显示了“刷新”图标,并在下拉菜单中突出显示了“浏览器链接仪表板”。

通过使开发人员能够利用浏览器链接 API,可以创建在 Visual Studio 与任何连接的浏览器之间跨越边界的非常高级的方案。 Web Essentials 利用 API 在 Visual Studio 和浏览器的开发人员工具、远程控制移动仿真器等之间创建集成体验。

Visual Studio Web 编辑器增强功能

Visual Studio 2013包括用于 Razor 文件和 Web 应用程序中的 HTML 文件的新 HTML 编辑器。 新的 HTML 编辑器提供基于 HTML5 的单个统一架构。 它具有自动大括号补全、jQuery UI 和 AngularJS 属性 IntelliSense、属性 IntelliSense 分组、ID 和类名 Intellisense 以及其他改进,包括更好的性能、格式设置和 SmartTag。

以下屏幕截图演示如何在 HTML 编辑器中使用 Bootstrap 属性 IntelliSense。

HTML 编辑器中的 Intellisense

Visual Studio 2013还内置了 CoffeeScript 和 LESS 编辑器。 LESS 编辑器附带 CSS 编辑器中所有很酷的功能,并针对链中 @import 所有 LESS 文档的变量和 mixin 具有特定的 Intellisense。

Visual Studio 中的Azure 应用服务 Web 应用支持

使用 Azure SDK for .NET 2.2 Visual Studio 2013,可以使用服务器资源管理器直接与远程 Web 应用交互。 可以登录到 Azure 帐户、创建新的 Web 应用、配置应用、查看实时日志等。 在 SDK 2.2 发布后不久,你将能够在 Azure 中以调试模式远程运行。 安装适用于 .NET 的 Azure SDK 的当前版本时,Azure 应用服务 Web 应用的大多数新功能也适用于 Visual Studio 2012。

有关详细信息,请参阅以下资源:

Web 发布增强功能

Visual Studio 2013包括新的和增强的 Web 发布功能。 下面是其中几个示例:

有关 ASP.NET Web 部署的详细信息,请参阅 ASP.NET 站点

NuGet 2.7

NuGet 2.7 包含一组丰富的新功能, NuGet 2.7 发行说明中对此进行了详细介绍。

此版本的 NuGet 还无需明确同意 NuGet 的包还原功能来下载包。 现在,通过安装 NuGet 授予同意 (和 NuGet 首选项对话框中的关联复选框) 。 现在,包还原默认有效。

ASP.NET Web 窗体

一个 ASP.NET

Web Forms项目模板与新的 One ASP.NET 体验无缝集成。 可以将 MVC 和 Web API 支持添加到Web Forms项目,还可以使用 One ASP.NET 项目创建向导配置身份验证。 有关详细信息,请参阅在 Visual Studio 2013 中创建 ASP.NET Web 项目

ASP.NET 标识

Web Forms项目模板支持新的 ASP.NET 标识框架。 此外,模板现在支持创建Web Forms Intranet 项目。 有关详细信息,请参阅在 Visual Studio 2013 中创建 ASP.NET Web 项目中的身份验证方法

Bootstrap

Web Forms模板使用 Bootstrap 提供可轻松自定义的时尚且响应迅速的外观。 有关详细信息,请参阅 Visual Studio 2013 Web 项目模板中的 Bootstrap

ASP.NET MVC 5

一个 ASP.NET

Web MVC 项目模板与新的 One ASP.NET 体验无缝集成。 可以使用 One ASP.NET 项目创建向导自定义 MVC 项目并配置身份验证。 有关 ASP.NET MVC 5 的介绍性教程,请参阅使用 ASP.NET MVC 5 的入门

有关将 MVC 4 项目升级到 MVC 5 的信息,请参阅 如何将 ASP.NET MVC 4 和 Web API 项目升级到 ASP.NET MVC 5 和 Web API 2

ASP.NET 标识

MVC 项目模板已更新为使用 ASP.NET 标识进行身份验证和标识管理。 有关 Facebook 和 Google 身份验证以及新成员资格 API 的教程,请参阅使用 Facebook 和 Google OAuth2 和 OpenID 登录创建 ASP.NET MVC 5 应用,并使用身份验证和 SQL DB 创建 ASP.NET MVC 应用并将其部署到 Azure 应用服务

Bootstrap

MVC 项目模板已更新为使用 Bootstrap ,提供可轻松自定义的时尚且响应迅速的外观。 有关详细信息,请参阅 Visual Studio 2013 Web 项目模板中的 Bootstrap

身份验证筛选器

身份验证筛选器是 ASP.NET MVC 中的一种新型筛选器,在 ASP.NET MVC 管道中的授权筛选器之前运行,可用于为所有控制器指定每个操作、每个控制器或全局身份验证逻辑。 身份验证筛选器处理请求中的凭据并提供相应的主体。 身份验证筛选器还可以添加身份验证质询,以响应未经授权的请求。

筛选器替代

现在,可以通过指定替代筛选器来替代应用于给定操作方法或控制器的筛选器。 替代筛选器指定一组不应在给定范围 (操作或控制器) 运行的筛选器类型。 这允许你配置全局应用的筛选器,但随后排除某些全局筛选器,使其不应用于特定操作或控制器。

属性路由

ASP.NET MVC 现在支持属性路由,这要归功于 作者 Tim McCall 的贡献 http://attributerouting.net。 使用属性路由,可以通过批注操作和控制器来指定路由。

ASP.NET Web API 2

属性路由

ASP.NET Web API现在支持属性路由,这要归功于 作者 Tim McCall 的贡献http://attributerouting.net。 使用属性路由,可以通过批注操作和控制器来指定 Web API 路由,如下所示:

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

通过属性路由,可以更好地控制 Web API 中的 URI。 例如,可以使用单个 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) { } 
}

属性路由还提供了一种便捷的语法,用于指定可选参数、默认值和路由约束:

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

有关属性路由的详细信息,请参阅 Web API 2 中的属性路由

OAuth 2.0

Web API 和单页应用程序项目模板现在支持使用 OAuth 2.0 进行授权。 OAuth 2.0 是用于授权客户端访问受保护资源的框架。 它适用于各种客户端,包括浏览器和移动设备。

对 OAuth 2.0 的支持基于 Microsoft OWIN 组件提供的用于持有者身份验证和实现授权服务器角色的新安全中间件。 或者,可以使用组织授权服务器(例如 azure Active Directory 或 Windows Server 2012 R2 中的 ADFS)对客户端进行授权。

OData 改进

支持$select、$expand、$batch和$value

ASP.NET Web API OData 现在完全支持 $select、$expand 和 $value。 还可以使用$batch对更改集进行请求批处理和处理。

通过$select和$expand选项,可以更改从 OData 终结点返回的数据的形状。 有关详细信息,请参阅 Web API OData 中的$select和$expand支持简介

改进了扩展性

OData 格式化程序现在可扩展。 可以添加 Atom 条目元数据、支持命名流和媒体链接条目、添加实例注释以及自定义链接的生成方式。

无类型支持

现在可以生成 OData 服务,而无需为实体类型定义 CLR 类型。 相反,OData 控制器可以获取或返回 IEdmObject 的实例,这些实例是 OData 格式化程序序列化/反序列化。

重用现有模型

如果已有现有实体数据模型 (EDM) ,现在可以直接重复使用它,而不必生成新的实体数据模型。 例如,如果使用实体框架,则可以使用 EF 为你生成的 EDM。

请求批处理

请求批处理将多个操作合并到单个 HTTP POST 请求中,以减少网络流量并提供更流畅、更不健谈的用户界面。 ASP.NET Web API现在支持多种请求批处理策略:

  • 使用 OData 服务的$batch终结点。
  • 将多个请求打包到单个 MIME 多部分请求中。
  • 使用自定义批处理格式。

若要启用请求批处理,只需将包含批处理处理程序的路由添加到 Web API 配置:

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

还可以控制请求或是按顺序执行还是按任意顺序执行。

可移植 ASP.NET Web API客户端

现在,可以使用 ASP.NET Web API 客户端创建可移植类库,这些库可跨 Windows 应用商店和 Windows Phone 8 应用程序运行。 还可以创建可在客户端和服务器之间共享的可移植格式化程序。

改进了可测试性

Web API 2 使对 API 控制器进行单元测试要容易得多。 只需使用请求消息和配置实例化 API 控制器,然后调用要测试的操作方法。 对于执行链接生成的操作方法,也很容易模拟 UrlHelper 类。

IHttpActionResult

现在可以实现 IHttpActionResult 来封装 Web API 操作方法的结果。 从 Web API 操作方法返回的 IHttpActionResult 由 ASP.NET Web API运行时执行,以生成生成的响应消息。 可以从任何 Web API 操作返回 IHttpActionResult,以简化 Web API 实现的单元测试。 为方便起见,提供了许多现成的 IHttpActionResult 实现,包括用于返回特定状态代码、格式化内容或内容协商响应的结果。

HttpRequestContext

新的 HttpRequestContext 跟踪与请求绑定但不可从请求立即获取的任何状态。 例如,可以使用 HttpRequestContext 获取路由数据、与请求关联的主体、客户端证书、 UrlHelper 和虚拟路径根。 可以轻松创建 HttpRequestContext 以进行单元测试。

由于请求的主体与请求一起流动,而不是依赖于 Thread.CurrentPrincipal,因此主体现在在请求的整个生存期内可用,而该主体位于 Web API 管道中。

CORS

由于 Brock Allen 的另一个巨大贡献,ASP.NET 现在完全支持跨源请求共享 (CORS) 。

浏览器安全性将阻止网页向另一个域发出 AJAX 请求。 CORS 是一种 W3C 标准,允许服务器放宽同源策略。 使用 CORS,服务器可以显式允许某些跨域请求,同时拒绝另一些跨域请求。

Web API 2 现在支持 CORS,包括预检请求的自动处理。 有关详细信息,请参阅在 ASP.NET Web API 中启用跨域请求

身份验证筛选器

身份验证筛选器是 ASP.NET Web API中的一种新筛选器,可在 ASP.NET Web API管道中的授权筛选器之前运行,并允许为所有控制器指定每个操作、每个控制器或全局的身份验证逻辑。 身份验证筛选器处理请求中的凭据并提供相应的主体。 身份验证筛选器还可以添加身份验证质询,以响应未经授权的请求。

筛选器替代

现在,可以通过指定替代筛选器来替代应用于给定操作方法或控制器的筛选器。 替代筛选器指定一组筛选器类型,这些筛选器类型不应针对给定范围 (操作或控制器) 运行。 这允许添加全局筛选器,但随后从特定操作或控制器中排除某些筛选器。

OWIN 集成

ASP.NET Web API现在完全支持 OWIN,并且可以在任何支持 OWIN 的主机上运行。 还包括一个 HostAuthenticationFilter ,它提供与 OWIN 身份验证系统的集成。

通过 OWIN 集成,可以与其他 OWIN 中间件(如 SignalR)一起在自己的进程中自承载 Web API。 有关详细信息,请参阅使用 OWIN Self-Host ASP.NET Web API

ASP.NET SignalR 2.0

以下部分介绍 SignalR 2.0 的功能。

有关如何将现有 1.x 项目升级到 SignalR 2.0 的示例,请参阅 升级 SignalR 1.x 项目

基于 OWIN 构建

SignalR 2.0 完全基于 OWIN (.NET) 开放 Web 接口 构建。 此更改使 SignalR 的设置过程在 Web 托管和自承载 SignalR 应用程序之间更加一致,但还需要进行大量 API 更改。

MapHubs 和 MapConnection 现在是 MapSignalR

为了与 OWIN 标准兼容,这些方法已重命名为 MapSignalRMapSignalR 在不使用参数的情况下调用 将映射所有中心 (,如 MapHubs 版本 1.x) 中那样;若要映射单个 PersistentConnection 对象,请将连接类型指定为类型参数,将连接的 URL 扩展指定为第一个参数。

方法 MapSignalR 在 Owin 启动类中调用。 Visual Studio 2013包含 Owin 启动类的新模板;若要使用此模板,请执行以下操作:

  1. 右键单击项目
  2. 选择 “添加”、“ 新建项...”
  3. 选择“ Owin 启动类”。 将新类命名 为 Startup.cs

Web 应用程序中, 包含 MapSignalR 方法的 Owin 启动类随后会使用 Web.Config 文件的应用程序设置节点中的条目添加到 Owin 的启动进程,如下所示。

自承载应用程序中,Startup 类作为 方法的类型 WebApp.Start 参数传递。

从 Web 应用程序中的全局应用程序文件映射 SignalR 1.x (中的中心和连接) :

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");
}

来自 Owin Startup 类文件的 SignalR 2.0 (映射中心和连接) :

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");
        }
    }
}

自承载应用程序中,Startup 类作为 方法的类型参数 WebApp.Start 传递,如下所示。

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

跨域支持

在 SignalR 1.x 中,跨域请求由单个 EnableCrossDomain 标志控制。 此标志控制 JSONP 和 CORS 请求。 为了获得更大的灵活性,已从 SignalR 的服务器组件中删除所有 CORS 支持 (如果检测到浏览器) 支持 CORS,并且已提供新的 OWIN 中间件来支持这些方案,则 JavaScript 客户端仍会正常使用 CORS。

在 SignalR 2.0 中,如果在客户端 (上需要 JSONP 来支持) 旧浏览器中的跨域请求,则需要通过将 对象上的 HubConfiguration 设置为 EnableJSONPtrue显式启用,如下所示。 JSONP 默认处于禁用状态,因为它的安全性低于 CORS。

若要在 SignalR 2.0 中添加新的 CORS 中间件,请将 Microsoft.Owin.Cors 库添加到项目,并在 SignalR 中间件之前调用 UseCors ,如以下部分所示。

将 Microsoft.Owin.Cors 添加到项目:若要安装此库,请在包管理器控制台中运行以下命令:

Install-Package Microsoft.Owin.Cors

此命令会将包的 2.0.0 版本添加到项目中。

调用 UseCors

以下代码片段演示如何在 SignalR 1.x 和 2.0 中实现跨域连接。

从全局应用程序文件在 SignalR 1.x (中实现跨域请求)

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

从 C# 代码文件在 SignalR 2.0 (中实现跨域请求)

以下代码演示如何在 SignalR 2.0 项目中启用 CORS 或 JSONP。 此代码示例使用 MapRunSignalR 而不是 MapSignalR,以便 CORS 中间件仅针对需要 CORS 支持 (的 SignalR 请求运行,而不是针对 .) Map 中指定的MapSignalR路径上的所有流量运行,也可以用于需要针对特定 URL 前缀运行的任何其他中间件,而不是整个应用程序。

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);
            });
        }
    }
}

通过 MonoTouch 和 MonoDroid 提供 iOS 和 Android 支持

已添加对使用 Xamarin 库中 MonoTouch 和 MonoDroid 组件的 iOS 和 Android 客户端的支持。 有关如何使用它们的详细信息,请参阅 使用 Xamarin 组件。 当 SignalR RTW 版本可用时,这些组件将在 Xamarin Store 中提供。

### 可移植 .NET 客户端

为了更好地促进跨平台开发,Silverlight、WinRT 和 Windows Phone 客户端已替换为支持以下平台的单个可移植 .NET 客户端:

  • NET 4.5
  • Silverlight 5
  • Windows 应用商店应用的 WinRT (.NET)
  • Windows Phone 8

新建Self-Host包

现在有一个 NuGet 包,可以更轻松地开始使用在进程或其他应用程序中托管的 SignalR Self-Host (SignalR 应用程序,而不是托管在 Web 服务器) 中。 若要升级使用 SignalR 1.x 生成的自主机项目,请删除 Microsoft.AspNet.SignalR.Owin 包,并添加 Microsoft.AspNet.SignalR.SelfHost 包。 有关自主机包入门的详细信息,请参阅 教程:SignalR 自主机

向后兼容的服务器支持

在早期版本的 SignalR 中,客户端和服务器中使用的 SignalR 包的版本需要相同。 为了支持难以更新的厚客户端应用程序,SignalR 2.0 现在支持对较旧客户端使用较新的服务器版本。 注意:SignalR 2.0 不支持使用较旧版本的客户端生成的服务器。

删除了对 .NET 4.0 的服务器支持

SignalR 2.0 已放弃对与 .NET 4.0 的服务器互操作性的支持。 .NET 4.5 必须与 SignalR 2.0 服务器一起使用。 仍有适用于 SignalR 2.0 的 .NET 4.0 客户端。

向客户端和组列表发送消息

在 SignalR 2.0 中,可以使用客户端和组 ID 列表发送消息。 以下代码片段演示如何执行此操作。

使用 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);
    }
}

使用中心向客户端和组列表发送消息

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();
    }
}

向特定用户发送消息

此功能允许用户通过新接口 IUserIdProvider 指定基于 IRequest 的 userId:

IUserIdProvider 接口

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

默认情况下,将有一个使用用户的 IPrincipal.Identity.Name 作为用户名的实现。

在中心,你将能够通过新 API 向这些用户发送消息:

使用 Clients.User API

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

更好的错误处理支持

用户现在可以从任何中心调用引发 HubExceptionHubException 的构造函数可以获取字符串消息和对象额外的错误数据。 SignalR 将自动序列化异常,并将其发送到客户端,客户端将用于拒绝/失败中心方法调用。

显示详细的中心异常设置与 HubException 是否发送回客户端没有关系;始终发送它。

演示向客户端发送 HubException 的服务器端代码

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);
    }
}

JavaScript 客户端代码演示如何响应从服务器发送的 HubException

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

演示如何响应从服务器发送的 HubException 的 .NET 客户端代码

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

更轻松地对中心进行单元测试

SignalR 2.0 包括一个在中心上调用的 IHubCallerConnectionContext 接口,以便更轻松地创建模拟客户端调用。 以下代码片段演示如何将此接口与常用测试工具 xUnit.netmoq 配合使用。

使用 xUnit.net 对 SignalR 进行单元测试

[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);
}

使用 moq 对 SignalR 进行单元测试

[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();

JavaScript 错误处理

在 SignalR 2.0 中,所有 JavaScript 错误处理回调都返回 JavaScript 错误对象,而不是原始字符串。 这允许 SignalR 将更丰富的信息流向错误处理程序。 可以从错误的 属性获取内部异常 source

处理 Start.Fail 异常的 JavaScript 客户端代码

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

ASP.NET 标识

新 ASP.NET 会员制度

ASP.NET 标识是 ASP.NET 应用程序的新成员身份系统。 ASP.NET Identity 可以轻松地将特定于用户的配置文件数据与应用程序数据集成。 ASP.NET 标识还允许为应用程序中的用户配置文件选择持久性模型。 你可以将数据存储在 SQL Server 数据库或其他数据存储中,包括 Azure 存储表等 NoSQL 数据存储。 有关详细信息,请参阅在 Visual Studio 2013 中创建 ASP.NET Web 项目中的单个用户帐户

基于声明的身份验证

ASP.NET 现在支持基于声明的身份验证,其中用户的标识表示为来自受信任颁发者的一组声明。 可以使用在应用程序数据库中维护的用户名和密码或使用社交标识提供者 ((例如 Microsoft 帐户、Facebook、Google、Twitter) )或使用组织帐户(通过 Azure Active Directory 或 Active Directory 联合身份验证服务 (ADFS) )对用户进行身份验证。

与 Azure Active Directory 和 Windows Server Active Directory 集成

现在可以创建使用 Azure Active Directory 或 Windows Server Active Directory (AD) 进行身份验证的 ASP.NET 项目。 有关详细信息,请参阅在 Visual Studio 2013 中创建 ASP.NET Web 项目中的组织帐户

OWIN 集成

ASP.NET 身份验证现在基于可在任何基于 OWIN 的主机上使用的 OWIN 中间件。 有关 OWIN 的详细信息,请参阅以下 Microsoft OWIN 组件 部分。

Microsoft OWIN 组件

.NET (OWIN) .NET 开放 Web 接口定义 .NET Web 服务器和 Web 应用程序之间的抽象。 OWIN 将 Web 应用程序与服务器分离,使 Web 应用程序与主机无关。 例如,可以在 IIS 中托管基于 OWIN 的 Web 应用程序,或在自定义进程中自承载它。

Microsoft OWIN 组件 (也称为 Katana 项目) 中引入的更改包括新的服务器和主机组件、新的帮助程序库和中间件以及新的身份验证中间件。

有关 OWIN 和 Katana 的详细信息,请参阅 OWIN 和 Katana 中的新增功能

注意: OWIN 应用程序无法在 IIS 经典模式下运行;它们必须在集成模式下运行。

注意: OWIN 应用程序必须完全信任运行。

新服务器和主机

在此版本中,添加了新组件以启用自承载方案。 这些组件包括以下 NuGet 包:

  • Microsoft.Owin.Host.HttpListener。 提供使用 HttpListener 侦听 HTTP 请求并将其定向到 OWIN 管道的 OWIN 服务器。
  • Microsoft.Owin.Hosting 为希望在自定义进程(如控制台应用程序或 Windows 服务)中自承载 OWIN 管道的开发人员提供库。
  • OwinHost。 提供一个独立的可执行文件,用于包装 Microsoft.Owin.Hosting OWIN 管道,并允许你自行托管 OWIN 管道,而无需编写自定义主机应用程序。

此外,包 Microsoft.Owin.Host.SystemWeb 现在允许中间件向 SystemWeb 服务器提供提示,指示应在特定的 ASP.NET 管道阶段调用中间件。 此功能对于身份验证中间件特别有用,该中间件应在 ASP.NET 管道中早期运行。

帮助程序库和中间件

尽管只能使用 OWIN 规范中的函数和类型定义来编写 OWIN 组件,但新 Microsoft.Owin 包提供了一组更便于用户使用的抽象。 此包将多个早期包 (例如 Owin.ExtensionsOwin.Types) 合并为一个结构良好的对象模型,然后可供其他 OWIN 组件轻松使用。 事实上,大多数 Microsoft OWIN 组件现在都使用此包。

注意

OWIN 应用程序无法在 IIS 经典模式下运行;它们必须在集成模式下运行。

注意

OWIN 应用程序必须完全信任运行。

此版本还包括 Microsoft.Owin.Diagnostics 包,其中包括用于验证正在运行的 OWIN 应用程序的中间件,以及用于帮助调查故障的错误页中间件。

身份验证组件

以下身份验证组件可用。

  • Microsoft.Owin.Security.ActiveDirectory。 使用本地或基于云的目录服务启用身份验证。
  • Microsoft.Owin.Security.Cookies 支持使用 Cookie 进行身份验证。 此包以前名为 Microsoft.Owin.Security.Forms
  • Microsoft.Owin.Security.Facebook 使用 Facebook 的基于 OAuth 的服务启用身份验证。
  • Microsoft.Owin.Security.Google 使用 Google 基于 OpenID 的服务启用身份验证。
  • Microsoft.Owin.Security.Jwt 启用使用 JWT 令牌进行身份验证。
  • Microsoft.Owin.Security.MicrosoftAccount 启用使用 Microsoft 帐户进行身份验证。
  • Microsoft.Owin.Security.OAuth。 提供 OAuth 授权服务器和中间件,用于对持有者令牌进行身份验证。
  • Microsoft.Owin.Security.Twitter 支持使用 Twitter 的基于 OAuth 的服务进行身份验证。

此版本还包括 Microsoft.Owin.Cors 包,其中包含用于处理跨域 HTTP 请求的中间件。

注意

Visual Studio 2013的最终版本中已删除对 JWT 签名的支持。

Entity Framework 6

有关 Entity Framework 6 中的新功能和其他更改的列表,请参阅 Entity Framework 版本历史记录

ASP.NET Razor 3

ASP.NET Razor 3 包括以下新功能:

  • 支持选项卡编辑。 以前,使用“保留选项卡”选项时,Visual Studio 中的“设置文档格式”命令、自动缩进和自动格式设置无法正常工作。 此更改更正了用于选项卡格式的 Razor 代码的 Visual Studio 格式。
  • 生成链接时支持 URL 重写规则。
  • 删除安全透明属性。

    注意

    这是一项中断性变更,使 Razor 3 与 MVC4 及更早版本不兼容,而 Razor 2 与 MVC5 不兼容或针对 MVC5 编译的程序集。

=======

ASP.NET 应用挂起

ASP.NET 应用暂停是 .NET Framework 4.5.1 中的一项改变游戏规则的功能,它从根本上改变了在单台计算机上托管大量 ASP.NET 网站的用户体验和经济模型。 有关详细信息,请参阅 ASP.NET 应用挂起 - 响应式共享 .NET Web 托管

已知问题和重大更改

本部分介绍Visual Studio 2013 ASP.NET 和 Web 工具中的已知问题和中断性变更。

NuGet

  • 使用 SLN 文件时,新包还原在 Mono 上不起作用 - 将在即将nuget.exe下载和 NuGet.CommandLine 包 更新中修复。
  • 新的包还原不适用于 Wix 项目 - 将在即将发布的nuget.exe下载和 NuGet.CommandLine 包 更新中修复。

ASP.NET Web API

  1. ODataQueryOptions<T>.ApplyTo(IQueryable) 不会始终返回 IQueryable<T> ,因为我们添加了对 $select$expand的支持。

    我们之前的示例 ODataQueryOptions<T> 始终将返回值从 ApplyTo 强制转换为 IQueryable<T>。 这在以前起作用,因为我们之前支持的查询选项 ($filter$orderby$skip$top) 不会更改查询的形状。 现在,我们支持 $select ,并且 $expandApplyTo 返回值不会始终为 IQueryable<T>

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

    如果使用前面的示例代码,则客户端不发送 $select$expand时,它会继续工作。 但是,如果想要支持 $select$expand 则必须将代码更改为此代码。

    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 或 RequestContext.Url 在批处理请求期间为 null

    在批处理方案中,从 Request.Url 或 RequestContext.Url 访问 UrlHelper 时为 null。

    此问题的解决方法是创建 UrlHelper 的新实例,如以下示例所示:

    创建 UrlHelper 的新实例

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

ASP.NET MVC

  1. 使用 MVC5 和 OrgAuth 时,如果有执行 AntiForgerToken 验证的视图,则向视图发布数据时可能会遇到以下错误:

    错误

    '/' 应用程序中出现服务器错误。

    提供的 ClaimsIdentity 上不存在类型为 或 的http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifierhttps://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider声明。 若要通过基于声明的身份验证启用防伪令牌支持,请验证配置的声明提供程序是否在生成的 ClaimsIdentity 实例上提供这两个声明。 如果配置的声明提供程序改用其他声明类型作为唯一标识符,则可以通过设置静态属性 AntiForgeryConfig.UniqueClaimTypeIdentifier 对其进行配置。

    解决方法

    在 Global.asax 中添加以下行以修复此问题:

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;

    此问题将在下一版本中得到修复。

  2. 将 MVC4 应用升级到 MVC5 后,生成解决方案并启动它。 应会看到以下错误:

    [A]System.Web.WebPages.Razor.Configuration.HostSection 无法转换为 [B]System.Web.WebPages.Razor.Configuration.HostSection。 类型 A 源自位于“C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll”的上下文“Default”中的“System.Web.WebPages.Razor,Version=2.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”。 类型 B 源自“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”位置的上下文“Default”中的“System.Web.Web.WebPages.Razor,Version=3.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35”。

    若要修复上述错误,请打开 所有 Web.config文件 (包括项目) Views 文件夹中的文件,然后执行以下操作:

    1. 将“System.Web.Mvc”版本“4.0.0.0”的所有匹配项更新为“5.0.0.0”。

    2. 将“System.Web.Helpers”、“System.Web.WebPages”和“System.Web.WebPages.Razor”版本“2.0.0.0”的所有匹配项更新为“3.0.0.0”

      例如,进行上述更改后,程序集绑定应如下所示:

      <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>
      

      有关将 MVC 4 项目升级到 MVC 5 的信息,请参阅 如何将 ASP.NET MVC 4 和 Web API 项目升级到 ASP.NET MVC 5 和 Web API 2

  3. 将客户端验证与 jQuery 非干扰验证结合使用时,对于 type='number' 的 HTML 输入元素,验证消息有时不正确。 当输入无效数字而不是正确消息“需要有效数字”时,将显示必填值 (“年龄字段是必需的”) 验证错误。

    此问题通常是在创建和编辑视图上具有整数属性的模型的基架代码中找到的。

    若要解决此问题,请从以下操作更改编辑器帮助程序:

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

    到:

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

  4. ASP.NET MVC 5 不再支持部分信任。 链接到 MVC 或 WebAPI 二进制文件的项目应删除 SecurityTransparent 属性和 AllowPartiallyTrustedCallers 属性。 删除这些属性将消除编译器错误,如下所示。

    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.

    请注意,这样做的副作用是,不能在同一应用程序中使用 4.0 和 5.0 程序集。 需要将其全部更新到 5.0。

当网站托管在 Intranet 区域中时,具有 Facebook 授权的 SPA 模板可能会导致 IE 不稳定

SPA 模板提供 Facebook 的外部登录。 使用模板创建的项目在本地运行时,登录可能会导致 IE 崩溃。

解决方案:

  1. 在 Internet 区域中托管网站;或

  2. 在 IE 以外的浏览器中测试方案。

Web 窗体基架

Web Forms基架已从 VS2013 中删除,并将在 Visual Studio 的未来更新中提供。 但是,仍可以通过添加 MVC 依赖项和生成 MVC 基架,在Web Forms项目中使用基架。 项目将包含Web Forms和 MVC 的组合。

若要将 MVC 添加到Web Forms项目,请添加新基架项,然后选择“MVC 5 依赖项”。 根据是否需要所有内容文件(如脚本)选择“最小”或“完整”。 然后,为 MVC 添加基架项,这将在项目中创建视图和控制器。

MVC 和 Web API 基架 - HTTP 404,找不到错误

如果在向项目添加基架项时遇到错误,则项目可能处于不一致状态。 基架所做的一些更改将回滚,但不会回滚其他更改,例如已安装的 NuGet 包。 如果回滚路由配置更改,用户在导航到基架项时将收到 HTTP 404 错误。

解决方法:

  • 若要修复 MVC 的此错误,请添加新基架项,并选择“MVC 5 依赖项” (“最小”或“完整) ”。 此过程会将所有必需的更改添加到项目。

  • 若要修复 Web API 的此错误,请执行以下操作:

    1. 将 WebApiConfig 类添加到项目。

      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. 在 Global.asax 的 Application_Start 方法中配置 WebApiConfig.Register,如下所示:

      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