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

作者:Microsoft

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

目录

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

Installation Notes(SAP 支持说明 #1984787 - SUSE Linux Enterprise Server 12:安装说明)

适用于 Visual Studio 2013 的 ASP.NET 和 Web 工具捆绑在主安装程序中,可以在此处下载

文档

ASP.NET 网站提供了有关 Visual Studio 2013 ASP.NET 和 Web 工具的教程和其他信息。

软件要求

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

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

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

一个 ASP.NET

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

新的 Web 项目体验

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

新建 ASP.NET 项目

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

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

身份验证选项

有关新身份验证选项的详细信息,请参阅 本文档后面的 ASP.NET 标识

ASP.NET 基架

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

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

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

若要将 MVC 基架添加到 Web 窗体项目,请在对话框窗口中添加新 基架项 并选择 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 包含 Web 应用程序中 Razor 文件和 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 文档的变量和 mixinsense 具有特定的 Intellisense。

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

在 Visual Studio 2013 中,使用适用于 .NET 2.2 的 Azure SDK,可以使用 服务器资源管理器 直接与远程 Web 应用交互。 可以登录到 Azure 帐户、创建新的 Web 应用、配置应用、查看实时日志等。 SDK 2.2 发布后不久,你将能够在 Azure 中远程运行调试模式。 安装适用于 .NET 的 Azure SDK 的当前版本时,Azure App 服务 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 窗体项目模板与新的 One ASP.NET 体验无缝集成。 可以将 MVC 和 Web API 支持添加到 Web 窗体项目,还可以使用 One ASP.NET 项目创建向导配置身份验证。

ASP.NET Identity

Web 窗体项目模板支持新的 ASP.NET 标识框架。 此外,这些模板现在支持创建 Web 窗体 Intranet 项目。

Bootstrap

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 Identity

MVC 项目模板已更新为使用 ASP.NET 标识进行身份验证和标识管理。 在创建具有 Facebook 和 Google 身份验证的 MVC 5 应用和 Google OAuth2 和 OpenID 登录的 ASP.NET MVC 5 应用以及创建具有身份验证和 SQL DB 的 ASP.NET MVC 应用并将其部署到Azure App 服务中可以找到一个教程。

Bootstrap

MVC 项目模板已更新为使用 Bootstrap 提供流畅且响应迅速的外观,让你可以轻松自定义。

身份验证筛选器

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

筛选器替代

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

属性路由

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

ASP.NET Web API 2

属性路由

ASP.NET Web API 现在支持属性路由,这要归功于作者 http://attributerouting.netTim McCall 的贡献。 使用属性路由,可以通过批注操作和控制器来指定 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 组件提供的新安全中间件,用于持有者身份验证并实现授权服务器角色。 或者,可以使用组织授权服务器(例如 Windows Server 2012 R2 中的 Azure Active Directory 或 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),现在可以直接重复使用它,而无需生成新的实体模型。 例如,如果使用 Entity Framework,则可以使用 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

由于布罗克艾伦的另一项巨大贡献,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 自承载 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 调用时不带参数将映射所有中心(与版本 1.x 中一样 MapHubs );若要映射单个 PersistentConnection 对象,请将连接类型指定为类型参数,并将连接的 URL 扩展指定为第一个参数。

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

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

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

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

SignalR 1.x 中的映射中心和连接(来自 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");
}

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

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 请求。 为了提高灵活性,所有 CORS 支持都已从 SignalR 的服务器组件中删除(如果检测到浏览器支持 CORS,JavaScript 客户端仍正常使用 CORS),并且已提供新的 OWIN 中间件来支持这些方案。

在 SignalR 2.0 中,如果客户端上需要 JSONP(若要在较旧的浏览器中支持跨域请求),则需要通过在对象trueHubConfiguration设置为EnableJSONP显式启用,如下所示。 默认情况下禁用 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);
}

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

以下代码演示如何在 SignalR 2.0 项目中启用 CORS 或 JSONP。 此代码示例使用 Map CORS 中间件, RunSignalR 而不是 MapSignalR,以便 CORS 中间件仅针对需要 CORS 支持(而不是用于 .中指定的 MapSignalR路径的所有流量) Map 的 SignalR 请求运行,也可用于需要针对特定 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 应用商店 中提供。

### 可移植 .NET 客户端

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

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

新建自承载包

现在有一个 NuGet 包,可以更轻松地开始使用 SignalR 自承载(在进程或其他应用程序中托管的 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);
    }
}

更好的错误处理支持

用户现在可以从任何中心调用引发 HubException 。 HubException构造函数可以获取字符串消息和对象额外的错误数据。 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);
                }
            });

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

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 Identity

新的 ASP.NET 成员身份系统

ASP.NET 标识是 ASP.NET 应用程序的新成员身份系统。 ASP.NET 标识,可以轻松地将特定于用户的配置文件数据与应用程序数据集成。 ASP.NET 标识还允许你为应用程序中的用户配置文件选择持久性模型。 可以将数据存储在 SQL Server 数据库或其他数据存储中,包括 NoSQL 数据存储,例如Azure 存储表。 有关详细信息,请参阅 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 的 Web 接口(OWIN)定义 .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 为希望在自定义进程中自承载 OWIN 管道(例如控制台应用程序或 Windows 服务)的开发人员提供库。
  • OwinHost. 提供一个独立可执行文件,用于包装 Microsoft.Owin.Hosting 和自承载 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$expand 返回 ApplyTo 值不会 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.UrlRequestContext.Url 访问时,UrlHelpernull。

    此问题的解决方法是创建新的 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 源自 “System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35”位于位置“C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll”。 类型 B 源自 “System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35” 位于位置“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”。

    若要修复上述错误,请打开 项目中的所有 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 Unobtrusive Validation 配合使用时,对于类型为“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。

使用 Facebook 授权的 SPA 模板可能会导致 IE 不稳定,而网站托管在 Intranet 区域中

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

解决方案;

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

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

Web 窗体基架

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

若要将 MVC 添加到 Web 窗体项目,请添加新基架项并选择 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