本文将对微软下一代ASP.NET框架做个概括性介绍,方便大家进一步熟悉该框架。

  在介绍ASP.NET Core 1.0之前有必要澄清一些产品名称及版本号。ASP.NET Core1.0是微软下一代ASP.NET 框架,在这之前ASP.NET版本稳定在ASP.NET  4.6,对应的.NET Framework版本为.net 4.6.2。

  曾经一段时间微软将下一代ASP.NET 命名为ASP.NET 5和MVC 6,在ASP.NET 5 is dead – Introducing ASP.NET Core 1.0 and .NET Core 1.0一文中,微软第一次提到ASP.NET 5将会改为ASP.NET Core1.0。

  该文还指出了.NET其他产品命名变化

  1. ASP.NET 5 现在叫做 ASP.NET Core 1.0
  2. .NET Core 现在叫做 .NET Core 1.0
  3. Entity Framework 7 现在叫做 Entity Framework Core 1.0 或者简称 EF Core 1.0

  之所以有这样的改变,微软解释为:下一代的ASP.NET并不是ASP.NET 4.6的简单升级,如果命名为ASP.NET 5则会给开发者一个错误的暗示,开发者会误认为这只是功能上的升级。而事实是微软首先写了一个轻量级跨平台的.NET Core,然后在该平台下重新设计了ASP.NET,新一代的ASP.NET Core 1.0有着众多新的特性,当然最重要的是实现了跨平台。

  值得注意的是从ASP.NET 5到ASP.NET Core 1.0这一命名的转变会对开发人员造成一些困惑,因为在一些ASP.NET相关的网站中,仍然可以不时地看到Asp.net 5 或者MVC 6等名称。事实上,由于ASP.NET Core 1.0正式版还没有发布,命名的改变还在进行当中,整个命名的改变过程到ASP.NET Core1.0正式发布之后才会全部结束。

  于此同时也产生了一些新的概念:

  DNX:.NET Execution Environment,即.NET运行时环境,在Windows,Mac和Linux下运行.NET应用程序的环境(有点目前windows环境下的.NET Framework的意思),当然这东西是跨平台的,这是跟.NET Framework最大的不同之处。

  DNVM:NX Version Manager,即DNX的版本管理工具,利用DNVM可以管理DNX的不同版本,你可以轻松切换到不同的DNX版本中。

  .NET Core:可以理解为一个经过精简的、模块化的.NET Framework子集,目的是为了跨平台。.NET Core有一系列的类库组成,叫做"CoreFX",一个更精简的版本叫做"CoreCLR"。

  整个.NET Core所有类库包括之前提到的ASP.NET Core都是通过Nuget来管理的。

 一、安装ASP.NET Core 1.0

  这一过程在Windows、Mac和Linux下各不相同,微软给出了详细的安装文档,以Windows为例又分为两种方式,下载安装或通过命令行安装

 二、新建ASP.NET Core项目

  安装完毕后,VS2015会增加对应的模板,值得注意的是该模板目前仍旧叫做ASP.NET 5。

 三、项目结构

  1、project.json文件:

  dependencies节点:用来管理Nuget依赖,支持智能提示,这一过程等价于在Nuget package Manager中管理依赖项。

  commands节点:在DNX环境下可以使用dnx [command]命令来执行一组命令,对于:

  1. "commands": {
  2. "web": "Microsoft.AspNet.Server.Kestrel",
  3. "ef": "EntityFramework.Commands"
  4. },

  可以这样使用:

  1. dnx web //这一命令将会启动KestrelHttp 服务器,KestrelHttpServer是微软基于libuv编写的跨平台web 服务器
  2.  
  3. dnx ef

  2、frameworks节点:该节点定义了DNX环境

  1. "frameworks": {
  2. "dnx451": { },
  3. "dnxcore50": { }
  4. },

  dnx451表示.NET Framework 4.5.1,dnxcore50表示.NET Core5。

  该节点表明此程序可以跑在这两种DNX环境中,在代码中还可以通过下面的方式针对具体的环境编写代码。

  1. #if DNX451
  2. // utilize resource only available with .NET Framework
  3. #endif

 四、ASP.NET Core1.0带来的新特性

  1、采用新的文件系统,不再通过工程文件(.sln和.csproj)来定义项目文件清单。

  以本Demo为例,所有添加在AspnetCore.Practice文件夹下的文件都会被自动添加在项目中,举个例子:

  打开AspnetCore.Practice\Controllers文件夹:在文件夹内手工添加一个文件ServiceController.cs,并添加如下测试代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.AspNet.Mvc;
  6.  
  7. namespace AspnetCore.Practice.Controllers
  8. {
  9. public class ServiceController : Controller
  10. {
  11. public IActionResult Index()
  12. {
  13. return Content("hello world");
  14. }
  15.  
  16. }
  17. }

  注意,此时打开VS的项目管理器,可以看到ServiceController已经添加到了项目中。这时若在浏览器中直接输入测试代码的url,即可看到测试结果。也就是说VS在后台监视到了新文件便会自动添加在项目中并自动完成编译。

  2、Startup类。

  该类可以看作整个ASP.NET Core的启动入口,该类主要存在3个方法:Main函数是入口点,方法ConfigureServices用来向IOC容器中注册组建,方法Configure则用来注册Middleware。

  也许你第一次见到这个类会有点不明觉厉,该类中3个方法既没有接口约束,也没有从父类继承。微软在该处采用了这样一种约定:必须要存在一个名叫Startup的类,同时该类必须要存在上面提到的3个方法,该ASP.NET项目才能顺利运行成功。

  采用约定而非契约编程的原因在于约定更加灵活。特别是在方法Configure()签名中,参数可以从容器中注入,意味着你可以定义这样的Configure方法:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env,
  2. ILoggerFactory loggerFactory)
  3. {
  4. //...
  5. }

  也可以定义这样的Configure方法:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env,
  2. ILoggerFactory loggerFactory,IUserProvider userProvider)
  3. {
  4. //...
  5. }

  要保证这样的灵活性对于契约编程很难做到。

  即便你对约定这一事实一无所知,一些异常信息也会帮助你朝着正确的方向编写代码。比如当你将Startup类重命名为其他,例如命名为Bootstrapper,你将会得到如下的提示:

  同样的道理,如果方法ConfigureServices或Configure漏写也会得到相似的提示。

  该类除了采用约定,大部分代码都是在接口上实现扩展方法的风格,想进一步了解这种代码风格请阅读《再谈扩展方法,从string.IsNullOrEmpty()说起》。

  3、读取Appsetting

  由于已经不再存在web.config文件,所以新的Appsetting也采取了更加通用的设计。在新建项目的时候VS已经帮我们添加了默认的appsettings.json文件。

  定义一个键值对:"hello": "Hello, world",同时在Startup类的构造函数中将appsettings.json文件添加到了ConfigurationBuilder对象中:

  1. public Startup(IHostingEnvironment env)
  2. {
  3. // Set up configuration sources.
  4. var builder = new ConfigurationBuilder()
  5. .AddJsonFile("appsettings.json")
  6. .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
  7. //…
  8. Configuration = builder.Build();
  9. }

  同时我们还可以看到一个环境变量env.EnvironmentName,这个设计也有利于我们区分QA,INT,UAT,Production等不同的运行环境。这一变量可以在项目配置中设置:

  在代码中可以通过Configuration["hello"]的方式读取我们之前定义的Appsettings。

  3、默认自带IOC容器,统一依赖注入API

  依赖注入技术从很大程度上使得代码更加模块化,会在一定程度上迫使你写出低耦合,SRP的代码,另外有着良好设计的代码也具备更好的可测试性。

  ASP.NET Core自己内置了一个非常轻量级的IOC容器,例如以下代码将组建IEmailSender和ISmsSender分别注册在了容器中。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. // Add application services.
  4. services.AddTransient<IEmailSender, AuthMessageSender>();
  5. services.AddTransient<ISmsSender, AuthMessageSender>();
  6. }

  当然你可以引入第三方比较成熟的IOC容器,项目Dependency Injection定义了一组抽象,只需要将具体的IOC容器实现该抽象即可整合进ASP.NET Core中。就目前的情况来看ASP.NET Core内置的容器比较适合ASP.NET Core内部的组建使用,而实际业务依赖则可以使用第三方更强大的容器来注册。

  另外在ASP.NET Core新的设计中,不光Controller可以进行依赖注入,Filter,View以及ViewModel都可进行注入。这方面的内容比较多,也许会在单独的文章中进行介绍。

  4、Middleware

  这一设计借鉴自OWIN katana 项目的管道设计。什么是Middleware?下面这幅图很好的描述了Middleware是如何在http请求过程中工作的。

  在方法Configure中调用的内容都可以理解为Middleware:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  2. {
  3. //…
  4. app.UseIISPlatformHandler(); //Middleware
  5.  
  6. app.UseStaticFiles(); //Middleware
  7.  
  8. app.UseMvc(routes =>
  9. {
  10. routes.MapRoute(
  11. name: "default",
  12. template: "{controller=Home}/{action=Index}/{id?}");
  13. }); //Middleware
  14. }

  注册一个Middleware有两种写法,比如你自定义了一个CustomerMiddleware,

  第一种注册方法:

  app.UseMiddleware<CustomerMiddleware>();

  第二种则更常用:首先写一个扩展方法

  1. public static class MiddlewareExtensions
  2. {
  3. public static IApplicationBuilder UseCustomerMiddleware(this IApplicationBuilder builder)
  4. {
  5. return builder.UseMiddleware<CustomerMiddleware>();
  6. }
  7. }

  然后就可以这样使用了:app.UseCustomerMiddleware();

  自定义Middleware请关注后续文章。

  5、统一MVC和WebAPI

  ASP.NET Core统一了MVC和WebAPI,这表现在这两者共用同一套代码,并且在开发过程中不用再继承各自独立的Controller基类了。下面展示了如何在同一个Controller中编写MVC和WebAPI:

  1. public class ServiceController : Controller
  2. {
  3. private readonly IConfigurationRoot _configurationRoot;
  4.  
  5. public ServiceController(IConfigurationRoot configurationRoot)
  6. {
  7. _configurationRoot = configurationRoot;
  8. }
  9.  
  10. public IActionResult Index()
  11. {
  12. return Content("hello world");
  13. }
  14.  
  15. public User GetUser()
  16. {
  17. var user = _configurationRoot.Get<User>("Users");// 读取appsettings.json中的对象
  18. return user;
  19. }
  20.  
  21. }

  这一示例采用了构造器注入,为了让IOC容器注入IConfigurationRoot参数,我们需要将该实例注册进IOC容器中:

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. //…
  4.  
  5. services.AddInstance(Configuration);
  6. }

  6、Razor页面中引入新的Tag Helpers

  在之前的Razor页面中,我们可以利用HtmlHelper扩展来完成数据绑定和页面展示,例如:

  1. @Html.EditorFor (i => i.Email, new {htmlAttributes = new {@class = "form-control"}})

  ASP.NET Core设计了新的方案:

  1. <input asp-for="Email" class="form-control" />

  这种写法更加接近HTML,对纯前段人员更加友好,也更利于结合一些前端的MVVM框架来使用。当然我们还可以根据自己的需求编写自定义的Tag Helpers。使用Tag Helpers需要添加如下Nuget package:

  1. "dependencies": { ... "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final"}

  另外一个例子对比:

  HtmlHelpers:

  1. @using (Html.BeginForm( "Register", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form" }))
  2. {
  3.  
  4. @Html.AntiForgeryToken()
  5.  
  6. @Html.ValidationSummary(true, "", new { @class = "text-danger" })
  7.  
  8. }

  TagHelpers:

  1.  
  1. <form class="form-horizontal" method="post" role="form" asp-controller="Account" asp-action="Register">
  2.  
  3. <div class="text-danger" asp-validation-summary="ValidationSummary.All"></div>
  4.  
  5. <!-- other tags or tag helpers -->
  6.  
  7. </form>

  7、其他一些特性如View Components,Caching…

  本文介绍了下一代的ASP.NET版本ASP.NET Core 1.0并且对其新的特性做了概括性的介绍,有助于.NET开发者对ASP.NET Core有一个全面的认识,随着我对ASP.NET Core的进一步了解还会对一些细节进行更进一步的补充,欢迎大家关注。

asp.net core 1.0初识的更多相关文章

  1. 初识ASP.NET Core 1.0

    本文将对微软下一代ASP.NET框架做个概括性介绍,方便大家进一步熟悉该框架. 在介绍ASP.NET Core 1.0之前有必要澄清一些产品名称及版本号.ASP.NET Core1.0是微软下一代AS ...

  2. .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布

    众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL)系统上的一流开发平台选项.这个团队已经一起工作好几个月了,RHEL对.NET有许多需求.今天在 ...

  3. ASP.NET Core 1.0 开发记录

    官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...

  4. ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录

    升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...

  5. ASP.NET 5 改名 ASP.NET Core 1.0

    今天,Scott Hanselman在其博客上宣布<ASP.NET 5 is dead - Introducing ASP.NET Core 1.0 and .NET Core 1.0>, ...

  6. ASP.NET Core 1.0中实现文件上传的两种方式(提交表单和采用AJAX)

    Bipin Joshi (http://www.binaryintellect.net/articles/f1cee257-378a-42c1-9f2f-075a3aed1d98.aspx) Uplo ...

  7. 坎坷路:ASP.NET Core 1.0 Identity 身份验证(中集)

    上一篇:<坎坷路:ASP.NET 5 Identity 身份验证(上集)> ASP.NET Core 1.0 什么鬼?它是 ASP.NET vNext,也是 ASP.NET 5,以后也可能 ...

  8. vs2015 已经支持开发asp .net core 1.0 rc2 程序了

    vs2015 已经支持开发asp .net core 1.0 rc2 程序了 http://mp.weixin.qq.com/s?__biz=MzI0MzM1ODczOQ==&mid=2247 ...

  9. [转]Writing Custom Middleware in ASP.NET Core 1.0

    本文转自:https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/ One of the new ...

随机推荐

  1. caffe Python API 之Dropout

    net.pool1 = caffe.layers.Pooling(net.myconv, pool=caffe.params.Pooling.MAX, kernel_size=2, stride=2) ...

  2. 【LabVIEW技巧】LabVIEW OOP怎么学

    前言 有很多人对LabVIEW OOP存在比较极端的看法,大致分为两类: 1. 绝对否定派认为LabVIEW OOP只不过是LabVIEW为了追求时髦,在面向过程的基础上用簇做了一些特性,实际上完全不 ...

  3. webapi-1 给现有MVC 项目添加 WebAPI

    1. 增加一个WebApi Controller, VS 会自动添加相关的引用,主要有System.Web.Http,System.Web.Http.WebHost,System.Net.Http 2 ...

  4. U43597 积木

    题目背景 小 XX 感到很无聊,从柜里翻出了小时候玩的积木. 题目描述 这套积木里共有 \(n\) 块,每块积木都是一个长方体. 小 X 想知道这些积木拼成一个积木塔(不必每一块 积木都使用). 所谓 ...

  5. MySQL索引基础知识点

    什么是索引 索引类似于书本目录,是数据库存储引擎维护的用于快速查找到记录的一种数据结构,它是对查询性能优化的最有效手段. MySQL索引是在存储引擎层而不是服务器层实现的,不同存储引擎的索引工作方式也 ...

  6. hdu 4496(并查集逆向添边)

    D-City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...

  7. 使用JAXB读写xml

    1.注解 在Java模型中的创建与 xml 文件对应的节点和属性需要用注解来表示 @XmlRootElement 作用:将一个Java类映射为一段XML的根节点参数:    name  定义这个根节点 ...

  8. BZOJ1898: [Zjoi2004]Swamp 沼泽鳄鱼

    1898: [Zjoi2004]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 478  Solved: 286[Submit][St ...

  9. 我的第一个web开发框架

    怎么才能成为一名架构师?需要具备哪些条件? 作为一名码农我迫切希望自己成为一个比较合格的web架构师,昨晚心血来潮小弟花了4个小时的时间整了个简易的web开发框架,本着开源的精神做个分享,希望和更多的 ...

  10. centos 时间日期设置

    date  时间窗口 date -s '2015-02-02 10:10:00'  更改年月日小时分秒 date -s 10:00:02  只更改时间 不更改年月 clock -w 写入系统时间 hw ...