ASP.NET Core 是对 ASP.NET 的一次意义重大的重构。本文介绍了 ASP.NET Core 中的一些新概念,并且解释了它们如何帮助你开发现代的 Web 应用程序。
ASP.NET Core 是一个新的开源和跨平台的框架,用于构建如 Web 应用、物联网(IoT)应用和移动后端应用等连接到互联网的基于云的现代应用程序。ASP.NET Core 应用可运行于 .NET Core 和完整的 .NET Framework 之上。 构建它的目的是为那些部署在云端或者内部运行(on-premises)的应用提供一个优化的开发框架。它由最小开销的模块化的组件构成,因此在构建你的解决方案的同时可以保持灵活性。你可以在 Windows、Mac 和 Linux 上跨平台的开发和运行你的 ASP.NET Core 应用。 ASP.NET Core 开源在 GitHub 上。
ASP.NET 的首个预览版作为 .NET Framework 的一部分发布于15年前。自那以后数百万的开发者用它开发和运行着众多非常棒的 Web 应用,而且在这么多年之间我们也为它增加和改进了很多的功能。
ASP.NET Core 有一些架构上的改变,这些改变会使它成为一个更为精简并且模块化的框架。ASP.NET Core 不再基于 System.Web.dll 。当前它基于一系列颗粒化的,并且良好构建的 NuGet 包。这一特点能够让你通过仅仅包含需要的 NuGet 包的方法来优化你的应用。一个更小的应用程序接口通过“只为你需要的功能付出”(pay-for-what-you-use)的模型获得的好处包括更可靠的安全性、简化服务、改进性能和减少成本。
通过 ASP.NET Core,你可以获得的改进:
一个统一的方式用于构建 web UI 和 web APIs
集成 现代的客户端开发框架 和开发流程
一个适用于云的,基于环境的 配置系统
内置的 依赖注入
新型的轻量级的、模块化 HTTP 请求管道
运行于 IIS 或者自宿主(self-host)于你自己的进程的能力
基于支持真正的 side-by-side 应用程序版本化的 .NET Core 构建
完全以 NuGet 包的形式发布
新的用于简化现代 web 开发的工具
可以在 Windows 、Mac 和 Linux 上构建和运行跨平台的 ASP.NET 应用
开源并且重视社区
一个 ASP.NET Core 应用其实就是一个在其 Main
方法中创建一个 web 服务器的简单控制台应用程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System; using Microsoft.AspNetCore.Hosting; namespace aspnetcoreapp{ public class Program { public static void Main( string [] args){ var host = new WebHostBuilder() .UseKestrel() .UseStartup<Startup>() .Build(); host.Run(); } } } |
Main
调用遵循 builder 模式的 WebHostBuilder ,用于创建一个 web 应用程序宿主。这个 builder 有些用于定义 web 服务器 (如 UseKestrel
)和 startup 类型( UseStartup
)的方法。在上面的示例中,web 服务器 Kestrel 被启用,但是你也可以指定其它 web 服务器。我们将会在下一节展示更多关于 UseStartup
的内容。WebHostBuilder
提供了一些可选方法,其中包括寄宿在 IIS 和 IIS Express 中的 UseIISIntegration
和用于指定根内容目录的 UseContentRoot
。Build
和 Run
方法构建了用于宿主应用程序的 IWebHost
然后启动它来监听传入的 HTTP 请求。
WebHostBuilder
的 UseStartup
方法为你的应用指定了 Startup
类。
1 2 3 4 5 6 7 8 9 10 | public class Program{ public static void Main( string [] args) { var host = new WebHostBuilder() .UseKestrel() .UseStartup<Startup>() //手工高亮 .Build(); host.Run(); } } |
Startup
类是用来定义请求处理管道和配置应用需要的服务。 Startup
类必须是公开的(public)并且包含如下方法:
1 2 3 4 5 6 | public class Startup{ public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { } } |
ConfigureServices 定义你的应用所使用的服务(在下面查看 服务(Services) )(例如 ASP.NET MVC Core framework、Entity Framework Core、Identity 等等)
Configure 定义你的请求管道中的 中间件(middleware)
更多内容请参考: Application Startup
服务是应用中用于通用调用的组件。服务通过依赖注入获取并使用。 ASP.NET Core 内置了一个简单的控制反转(IoC) 容器,它默认支持构造器注入,并且可以方便的替换成你自己选用的 IoC 容器。由于它的松耦合特性,依赖注入(DI) 使服务在整个应用中都可以使用。例如,Logging 在你整个应用中都可用。查看 Dependency Injection 获取更多信息。
在 ASP.NET Core 中,你可以使用 Middleware 构建你的请求处理管道。 ASP.NET Core 中间件为一个 HttpContext
执行异步逻辑,然后按顺序调用下一个中间件或者直接终止请求。一般来说你要使用一个中间件,只需要在 Configure
方法里调用 IApplicationBuilder
上一个对应的 UseXYZ
扩展方法。
ASP.NET Core 带来了丰富的内置中间件:
你也可以创建你自己的 自定义中间件。
你也可以在 ASP.NET Core 中使用任何基于 OWIN 的中间件。查看 OWIN 获取更多信息。
ASP.NET Core 托管模式并不直接监听请求;而是依赖于一个 HTTP server 实现来转发请求到应用程序。这个被转发的请求会以一组 feature 接口的形式被包装,然后被应用程序组合到一个 HttpContext
中去。 ASP.NET Core 包含了一个托管的跨平台 web 服务器,被称为 Kestrel,它往往会被运行在一个如 IIS 或者 nginx 的生产 web 服务器之后。
内容根目录是应用程序所用到的所有内容的根路径,例如它的 views 和 web 内容。内容根目录默认与宿主应用的可执行程序的应用根目录相同;一个替代的地址可以通过 WebHostBuilder 来设置。
你的应用的Web根目录(Web root)是你项目中所有公共的、静态的资源,如 css、js 和 图片文件的目录。静态文件中间件将默认只发布 Web 根目录(Web root)和其子目录中的文件。 Web 根目录(Web root)默认为 /wwwroot,但是你也可以通过 WebHostBuilder 来指定另外一个地址。
ASP.NET Core 使用了一个新的配置模型用于处理简单的键值对。新的配置模型并非基于System.Configuration
或者 web.config ;而是从一个有序的配置提供者集合拉取数据。内置的配置提供者支持多种不同的文件格式如(XML,JSON, INI)和用于支持基于环境的配置环境变量。你也可以实现你自己自定义的配置提供者。查看 Configuration 获取更多信息。
环境,如 “Development” 和 “Production”,是 ASP.NET Core 中的第一级概念而且它可以设置成使用环境变量。查看 Working with Multiple Environments 获取更多信息。
你可以使用 Model-View-Controller(MVC)模式创建优秀的并且可测试的 web 应用程序。查看 MVC 和 测试。
你可以构建支持多种格式并且完全支持内容协商的 HTTP 服务。 查看 Formatting
Tag Helpers 启用服务器端的代码参与到 - Razor 文件的创建和 HTML 元素渲染
你可以使用自定义或者内置的 formatters (JSON, XML)来构建完全支持内容协商的 HTTP 服务
Model Binding 模型绑定 自动的映射 HTTP 请求中的数据到 action 方法参数
Model Validation 模型验证 自动的执行客户端和服务器端验证
ASP.NET Core 在设计时已考虑到和各种客户端框架(AngularJS,KnockoutJS 和 Bootstrap)的无缝集成。查看 Client-Side Development 获取更多信息。
Building your first ASP.NET Core MVC Application
用 Visual Studio Code 在 Mac OS 上创建首个 ASP.NET Core 应用程序
用 ASP.NET Core MVC 创建你的第一个 Web API
Fundamentals
最新版本的 ASP.NET 叫做 ASP.NET Core (也被称为 ASP.NET 5) 它颠覆了过去的 ASP.NET。
ASP.NET Core 1.0 是一个开源跨平台的开发框架,用于构建基于云的现代 Web 应用 。它是从底层开始重新构建来提供性能优良的Web应用开发框架,可以部署在云上或者本地服务器上。另外,它使得 ASP.NET 应用更加精简和模块化(可以根据你的应用需要向里面添加其他模块),跨平台(你可以很容易的在 Windows, Mac or Linux 上开发和部署你的应用),云优化(你可以在云上在云上部署和调试你的应用)。
对于使用 ASP.NET 旧版本的我们来说,这意味着什么?
如果你正在使用旧版本的 ASP.NET 或者你有 WebForms 的开发背景,那么你将会认识到 ASP.NET Core 有多完美,这感觉起来就像从古典的 ASP 时代来到全新的 ASP.NET 的世界。
下面列出 ASP.NET Core 1.0 的核心变化.
你可以在 OSX 和 Linux上运行 ASP.NET Core 应用,这对于 ASP.NET 来说,这具有跨时代的意义,也给 ASP.NET 开发者和设计师们带来了全新的体验。ASP.NET Core 具有两个运行时,这意味着你可以选择不同的运行环境来部署你的应用,使得你的应用将更加灵活。
ASP.NET Core 1.0 是一个 ASP.NET 的重构版本,它运行于最新的 .NET Core。它是模块化的,允许开发者以插件的形式添加应用所需要的模块,大多数的功能都将作为插件提供并通过 NuGet 程序包管理。这样做的一个好处就是你可以升级应用的一个模块,但丝毫不会影响其他模块;另外,.NET Core 是一个跨平台的运行时,因此你可以在 OSX 或 Linux 操作系统上部署你的应用;它也是一个云优化的运行时,用于在云上部署和调试应用;.NET Core 可以和你的应用程序一起被部署,当服务器上有多个 .NET Core 版本时, 你依旧可以运行 ASP.NET Core 应用。
你也可以创建只运行在 windows 下完整 .NET 框架的 ASP.NET Core 应用。
ASP.NET 4.6 是最新的完整 .NET Framework 的发布版本,它允许你可以利用所有的 .NET 组件并且具备向后兼容能力。如果你计划将应用迁移到 .NET core,那么你需要做适量的修改,因为 .NET Core 相对于完整 .NET Framework 来说有所限制。
需要明确的是,ASP.NET 4.6 更加成熟。它如今久经考验并且现已发布并可使用。ASP.NET Core 1.0 是1.0 发布版本,包含 Web API 和 MVC,但是现在还没有 SignalR 和 Web Pages。,它也不支持VB 和 F# 语言。
ASP.NET Core 的跨平台,让它不再只依赖 Visual Studio,开发者和设计师们可以在自己喜欢的环境上工作。比如 Sublime Text,WebStorm ,这真是太棒了!
如果你使用 Visual Studio 创建了一个空的 ASP.NET Core 工程,那么你将会看到下面的惊喜。(除非你没有使用之前的 ASP.NET 创建过任何项目)
你感觉到惊喜了吗?新的工程结构完全不一样了, 工程模板焕然一新,包含以下的新文件:
· global.json: 你可以在这里放置解决方案的配置信息和工程之间的引用。
· Program.cs: 这个文件包含了 ASP.NET Core RC2 应用的 Main 方法,负责配置和启动应用程序。
· src folder: 包含组成你应用程序的全部项目代码。
· wwwroot: 你的静态文件将被放置在这个文件夹,它们都将作为资源直接提供给客户端,包含 HTML,CSS 和 JavaScript 文件。
· project.json: 包含项目设置。在 ASP.NET Core中,你可以通过使用 NuGet 程序包管理工具(NPM)添加 NuGet 包或者编辑这个文件来管理从属。你可以通过任何文本编辑器来编辑这个文件,如果你使用 Visual Studio 2015,,这将会更加 轻松,因为它的智能提示会帮助你找到合适的 NuGet 包作为从属。project.json 就像下面这样。
· startup.cs 这个主要放置你 ASP.NET Core 的 stratup 和 configuration 代码,下面就是 stratup 类的样子。
ConfigureServices 方法定义了你应用程序使用的服务,Configure 方法用来定义组成请求管道的中间件。
· References: 它包含了 .NETCoreApp 第一个版本运行时的引用。
是的,WebForms 不再是 ASP.NET 5 的一部分,这真令人悲伤。你可以继续使用 VS2015 的 .NET 4.6 来构建 Web Forms 应用,但是却不能体会 ASP.NET 5 的新特性了。
我已经开发了很多年从小型到大型的企业级 Web Forms 应用。 我很喜欢 Web Forms,,事实上我还会继续支持在各种论坛使用 WebForms 的社区,比如 http://forums.asp.net。但是我们是时候进步了,去学习一些新东西。这是学习 ASP.NET MVC 最后的时间了,就像过去的许多事物,你要么去适应,要么被淘汰。
除了 WebForms, the .NET Core 也没有包含 Windows Forms, WCF, WPF, Silverlight 等等。
目前,在当前 ASP.NET Core 1.0 RC2 版本中, VB.NET 和 F# 也不被支持。
ASP.NET Core 将见证 MVC, Web API 和 Web Pages(可能包含)组合在一个架构中,它被称为 ASP.NET MVC Core。尽管当前发布版本中,还不支持 Web Pages and SignalR。
在之前的 ASP.NET MVC 中, MVC 控制器和 Web API 控制器是不同的。 一个 MVC 控制器使用基类 System.Web.MVC.Controller ,一个 Web API 控制器使用基类 System.Web.Http.ApiController 。 在 MVC Core 中,会为它们提供一个共同的基类,就是 Microsoft.AspNetCore.Mvc.Controller 。
对于 HTML Helpers 来说,MVC 和 Web Pages 的合并是非常有可能的。 Web Pages 编程模型对当前版本来说还不适用,所以我们还不能负责任地说下一步计划合并哪些特性。 但是我们可以预测到,传统的 MVC 模型绑定将会出现。
在之前 ASP.NET MVC 中,, Html.Action() 帮助方法一般用于调用一个 sub-controller。ASP.NET MVC Core 将会使用新的 View Components 用来代替使用Html.Action() 的部件。
View Components 支持完全异步,这允许你创建异步的视图组件。
下面是一个简单的视图组件的例子,根据身份会返回个人介绍。
using Microsoft.AspNetCore.Mvc; using MVC6Demo.Models; using System.Threading.Tasks; using System.Collections.Generic; namespace MVC6Demo.ViewComponents { public class PersonListViewComponent : ViewComponent { public async Task<iviewcomponentresult> InvokeAsync(string status) { string viewToUse = "Default"; bool isFiltered = false; PersonModel model = new PersonModel(); if (status.ToLower().Equals("registered")) { viewToUse = "Registered"; isFiltered = true; } var p = await GetPersonAsync(status, isFiltered); return View(viewToUse,p); } private Task<ienumerable<person>> GetPersonAsync(string status, bool isFiltered) { return Task.FromResult(GetPerson(status,isFiltered)); } private IEnumerable<person> GetPerson(string status, bool isFiltered) { PersonModel model = new PersonModel(); if (isFiltered) return model.GetPersonsByStatus(status); else return model.GetAll; } } } </person>
下面是 View Component 的视图:
<h3>Person List</h3> <ul> @foreach (var p in Model) { <li>@string.Format("{0} {1}",p.FirstName,p.LastName)</li> } </ul>
这里展示了如何在主视图中调用 View Components
<div> @await Component.InvokeAsync("PersonList", new { type = "Registered" }) </div>
ASP.NET MVC Core 提供了少量新指令。 下面我们来看看如何使用 @inject。 @inject 指令允许你注入一个类中的方法到你的视图中。
这是一个简单的类,来展示一些异步的方法。
using System.Threading.Tasks; using System.Linq; namespace MVC6Demo.Models { public class Stats { private PersonModel _persons = new PersonModel(); public async Task<int> GetPersonCount() { return await Task.FromResult(_persons.GetAll.Count()); } public async Task<int> GetRegisteredPersonCount() { return await Task.FromResult( _persons.GetAll.Where(o => o.Status.ToLower().Equals("registered")).Count()); } public async Task<int> GetUnRegisteredPersonCount() { return await Task.FromResult( _persons.GetAll.Where(o => o.Status.ToLower().Equals("")).Count()); } } }
现在我们就可以在视图中使用 @inject 指令来调用那些方法:
@inject MVC6Demo.Models.Stats Stats @{ ViewBag.Title = "Stats"; } <div>
这是不是很酷?
查看我关于 ASP.NET MVC 新指令详细例子的文章: Getting Started with ASP.NET MVC Core
ASP.NET MVC Core 另外一个非常酷的东西就是 Tag Helpers。对于之前的 HTML Helpers,Tag Helpers 是可选的替代语法。
所以相比于以下代码:
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>Use a local account to log in.</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" }) </div> </div> }
你可以使用这些代码:
<form asp-controller="Account" asp-action="Login" method="post" class="form-horizontal" role="form"> <h4>Use a local account to log in.</h4> <hr /> <div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="UserName" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="UserName" class="col-md-2 control-label" /> <span asp-validation-for="UserName" class="text-danger"></span> </div> </div> </form>
14年前,ASP.NET 平台基本只能部署在一种服务器上,那就是 IIS。几年之后,Visual Studio Development Web Server(也叫作“Cassini”)作为一种开发服务被使用,但是它们最终都是调用 System.Web 作为应用程序和 Web 服务器中间的主机层。System.Web 主机与 IIS 耦合度很高,所以要想运行在另一台主机上会非常困难。
后来 OWIN 作为应用程序和 Web 服务器中间的接口出现。 Microsoft 开发了 Katana 作为一个 OWIN 的实现,可以部署 ASP.NET Web API, SignalR 和其他第三方框架,这些框架可以在 IIS 和 IIS Express, Katana's 自托管主机和自定义主机。
ASP.NET Core 是不强调主机的,它在 Katana 和 OWIN 上行为一致。ASP.NET Core 也可以部署在 IIS, IIS Express 或者自托管在你自己的进程里。另外,ASP.NET Core 也会包含一个叫做 Kestrel 的 Web 服务器,它建立在 libuv 上,主要用于 iOS 和 Linux 操作系统。
ASP.NET Core 提供了一种更加模块化的 HTTP 请求管道, 你可以只添加你需要的组件。这个管道不再依赖 System.Web,通过降低管道中的开销,你的 app 性能更加优良,更好的调谐 HTTP 协议栈。新的管道基于 Katana 项目经验,同时支持 OWIN。
Visual Studio 2015 中另一个非常酷的特性就是支持动态编译。在过去的 ASP.NET 中,当我们修改了应用的后台代码,我们需要重新编译并且运行才能看到页面的变化。 在新版本的 Visual Studio 中,你不需要再做这些额外的步骤,仅仅是保存你的修改和刷新浏览器即可。
这是在刷新页面之后的输出:
在过去的 MVC 和 Web API 中,使用路由属性可能会导致一些问题,尤其是你正在做一些代码重构。这是因为路由必须设定为字符串类型,当你修改了控制器的名字,你就必须修改路由属性的字符串
MVC Core 提供了新的 [controller] 和 [action] 标记,它们可以解决这个问题。下面这篇文章重点说明了这些新标记的用法。 : ASP.NET MVC 6 Attribute Routing.
ASP.NET Core 内嵌了对依赖注入和 Service Locator 模式的支持,这意味着你不在需要通过第三方依赖注入框架 Ninject 或 AutoFac。
Visual Studio 2015 内嵌了对流行开源 Web 开发工具的支持。 Grunt 和 Gulp 可以帮你自动化构建 Web 开发工作流, 你可以使用它们来编译和压缩 JavaScript 文件。Bower 是一个用于客户端库的管理工具,包含 CSS 和 JavaScript 库。
AngularJs 是当前最流行的前端框架之一,用于构建单页面应用程序(SPAs)。Visual Studio 包含了用于创建 AngularJs 模块,控制器,指令和工厂。
对 GruntJS 的支持使得 ASP.NET 成为一个用于构建客户端 AngularJs 应用的优秀服务器端框架。 当完成一个版本,你可以自动合并和压缩全部 AngularJs 文件。查看我的关于开始在 ASP.NET 中使用 Angular 和 Angular2 的文章 。
· ASP.NET 5: Jump Start to AngularJS with MVC 6 Web API
· ASP.NET Core:Getting Started with AngularJS 2
ASP.NET Core 也是以 SignalR 3 为基础,这使得你可以向云连接的应用程序添加实时功能。查看我之前的 SignalR 例子: ASP.Net SignalR: Building a Simple Real-Time Chat Application
在 ASP.NET Core 中,混乱的 web.config 文件被新的云就绪配置文件代替,它称作 “config.json”。微软希望开发人员更容易地在云中部署应用程序,并使得应用能够根据特殊环境自动的读取正确的配置参数。
这是一个新的配置文件的样子:
由于 ASP.NET Core 都是插件化的,你需要配置 Stratup 类的源代码,就像下面这样:
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath); builder.AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddTransient<MVC6Demo.Models.HeroStats>(); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseMvc(m => { m.MapRoute( name: "default", template: "{controller}/{action}/{id?}", defaults: new { controller = "Home", action="Index"}); }); }
在之前的 ASP.NET MVC 中,默认的测试框架是 Visual Studio 单元测试框架(有时候也叫作mstest),这个框架使用 [TestClass] 和 [TestMethod] 特性来描述一个单元测试。
ASP.NET Core 使用 xUnit.net 作为它的单元测试框架。这个框架使用 [Fact] 特性来代替 [TestMethod] 特性,也消除了对 [TestClass] 属性的依赖。
是的,ASP.NET Core 被作为一个开源项目托管到 GitHub上, 你可以查看源代码,并下载并提交你的更改。
我认同开源的 .NET 会产生重大的意义,它产生了积极的商业意义和社区意义,十分感谢微软所做出的工作。
以上 ASP.NET Core 1.0 的新特性和新概念的介绍,是为了更好的帮助我们使用 ASP.NET Core 进行开发,同时在开发过程中,我们还可以借助一些好的工具来提高开发效率,并减少代码量,如 ComponentOne Studio for Asp.net MVC,它兼容 ASP.NET Core RC2 版本,是一款快速轻量级的控件来满足用户的所有需求。
2016 © donet5.comApache Licence 2.0