设为首页 收藏本站
查看: 1204|回复: 0

[经验分享] 解读ASP.NET 5 & MVC6系列(2):初识项目

[复制链接]

尚未签到

发表于 2017-2-22 11:00:29 | 显示全部楼层 |阅读模式
初识项目
  打开VS2015,创建Web项目,选择ASP.NET Web Application,在弹出的窗口里选择ASP.NET 5 Website模板创建项目,图示如下:
DSC0000.png

  我们可以看到,此时Web Forms\MVC\Web API复选框都选择不了,原有是因为在ASP.NET 5中做了大量更改,移除了Web Forms功能,将MVC、Web API、Web Pages这些功能合在了一起,所以自然就不需要这些复选框了。另外由于是CTP版,所以目前还没有提供单元测试项目的创建。
  新创建的项目在VS的解决方案目录结构和实际文件夹的目录结构分别如下:
DSC0001.png

DSC0002.png


  注意:上图是在VS 预览版中的截图,在新版的RC版本中,默认的客户端构建工具变成了gulp(即配置文件是gulpfile.js),而非原来的grunt了。

  两个图的差异非常大,我们来一一分析一下这些差异。

项目结构差异
  通过图示,我们可以看到,在根目录中,不仅项目文件从从csproj变成了xproj,还少了很多之前的文件(如web.config),但也多了很多不同的文件以及文件夹,我们先列出这些不同的文件盒文件夹,再来一一讲解这些内容。

文件/文件夹
功能描述
config.json
程序的配置文件,类似于web.config。
project.json
该项目的主要配置,主要是负责程序集、项目部署等方面。部分功能类似于之前的package.config。
package.json
npm的配置文件,npm是基于Nodejs的包管理器。
bower.json
Bower管理器的配置文件,Bower是专门用于管理前端项目的包管理器。
gulpfile.js
是gulp的配置文件,gulp是基于Nodejs的Javascript任务管理器,在ASP.NET5中主要是用于管理NPM和Bower中的内容。
Stratup.cs
程序启动入口,类似于Global.asax。
Project_Readme.html
项目说明文件,没啥用。
wwwroot
静态资源文件(如css、图片、js)的存放目录。
Dependencies
Bower和NPM的依赖管理包。
References
程序集引用,和以前的类似,但现在有了版本之分(如ASP.NET 5.0和ASP.NET Core 5.0)。
project.json
  project.json是项目的核心配置文件,示例如下:
{  "webroot": "wwwroot",
  "version": "1.0.0-*",
  "dependencies": {
  "Microsoft.AspNet.Diagnostics": "1.0.0-beta4",
  "Microsoft.AspNet.Mvc": "6.0.0-beta4",
  "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta4",
  "Microsoft.AspNet.Server.IIS": "1.0.0-beta4",
  "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
  "Microsoft.AspNet.StaticFiles": "1.0.0-beta4",
  "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta4",
  "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
  "Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta4",
  "Microsoft.Framework.Logging": "1.0.0-beta4",
  "Microsoft.Framework.Logging.Console": "1.0.0-beta4",
  "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta4",
  "Microsoft.Framework.ConfigurationModel.UserSecrets": "1.0.0-beta4"
  },
  "commands": {
  "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000",
  "gen": "Microsoft.Framework.CodeGeneration"
  },
  "frameworks": {
  "dnx451": { },
  "dnxcore50": { }
  },
  "exclude": [
  "wwwroot",
  "node_modules",
  "bower_components"
  ],
  "publishExclude": [
  "node_modules",
  "bower_components",
  "**.xproj",
  "**.user",
  "**.vspscc"
  ],
  "scripts": {
  "postrestore": [ "npm install", "bower install" ],
  "prepare": [ "gulp copy" ]
  }
  
}
  由于该文件的详细参数非常多,具体详细内容请参考http://go.microsoft.com/fwlink/?LinkID=517074 ,在这里我们主要讲解如下3个类型的内容。

webroot
  webroot是指定该web项目的静态文件存放地址,目前是用于在发布的时候讲该目录中的内部发布的正确的位置(详细内容可以在部署发布章节中找到)。注意BookStore解决方案中带有地球图标的wwwroot目录是真实的文件夹路径,我们可以对其进行修改,比如将其修改为wwwroot1,那么相应的webroot的值也应该修改为wwwroot1,因为gulpfile.js里代码要通过project.webroot来使用该目录,以便能够将bower管理的前端库都复制到正确的目录。

程序集管理
  在解决方案的References节点点,我们看到有两个分类,分别是:DNX 4.5.1和DNX Core 5.0,其中DNX Core 5.0就是我们所说的云优化版(即可以在其它操作系统下部署的跨平台版),而DNX 4.5.1则是和之前版本一样的全功能版,这两个版本的程序集是通过dependencies节点进行管理的。
  在一级dependencies节点,主要是定义该项目的通用程序集引用以及版本,而不同的版本的程序集则在framworks下的各版本下的dependencies节点进行维护,比如:
"frameworks": {  "dnx451": {
  "dependencies": {"log4net": "2.0.3"} /* 只在全功能版中引入log4net程序集*/
  

  },
  "dnxcore50": { }
  
}
  上述两种类型的程序集在维护的时候,都有智能提示(包括程序集名称以及版本号),在当定义完自己要用的程序集并保持之后,系统会自动从Nuget上下载所需要的程序集,你也可以通过右键References选择Restore Packages来更新所有的程序集引用。同时你依然可以通过右键References的形式通过Nuget来管理这些程序集。

脚本事件
  新版的VS2015允许我们在build解决方案之前、之后、过程;下载程序集之前、之后;更新程序集之前、之后自定义一些基于Nodejs的自定义事件来执行。该事件在project.json中的定义节点是scripts,示例如下:
"scripts": {  "postrestore": [ "npm install" ],  // 在更新所有的程序集之前执行npm install事件
  "prepare": [ "gulp copy" ]
  // 在打开解决方案之前,执行gulp任务,调用bower的install方法。
  
}
  具体的事件名称如下:

时机
描述
prebuild
构建之前执行
postbuild
构建之后执行
prepack
packing之前执行
postpack
packing之后执行
prerestore
restoring packages之前执行
postrestore
restoring packages之后执行
package.json
  package.json是NPM管理器的配置文件,由于在VS2015默认就深度集成了Nodejs,而NPM又是Nodejs的默认包管理器,所以所有基于Nodejs的包都要在这里进行配置。该配置文件的默认配置如下:
{  "name": "ASP.NET",
  "version": "0.0.0",
  "devDependencies": {
  "gulp": "3.8.11",//gulp任务管理器
  "rimraf": "2.2.8" // 递归删除文件的nodejs包
  }
  
}
  上述代码中的rimraf是一个递归删除文件的nodejs包,我们也可以引用其他插件,像project.json文件中管理程序集一样,在package.json文件中来管理前端程序的各种包,例如jquery,bootstrap等等,比如我们要安装一个express包,只需要在json文件中添加一个express字符串键,并选择器版本就可以了,系统会自动下载该NPM包并显示在解决方案的Dependencies->NPM节点下。

  注意:已经安装的包不能自动移除(即不能通过在JSON中移除配置),需要右键执行该包,并手工卸载。


bower.json
  所有的前端包都配置子bower.json文件中,比如你需要的jquery、bootstrap、angular等等,其管理方式与project.json里的程序集和package.json里的npm包一样,都是通过在dependencies节点下声明包的名称和版本来实现的。
  我们可以在此声明一个angular包,保存以后就可以看到在解决方案Dependencie->Bower节点下该angular已经自动下载好了,编译项目,就可以看到在wwroot/lib也可以看到angular文件夹以及相应的文件了。
  在bower.json还有一个exportsOverride节点非常重要,他扩展了原来bower的前端文件copy机制,默认情况下bower只会复制main节点定义的文件。但有时候我们要复制的文件可能不止这些,所以grunt-bower-task插件就扩展了该功能,定义了这个exportsOverride节点,其使用规则如下:


  • 如果Bower包定义了main文件节点,就将其复制到wwwroot/lib下。
  • 如果Bower包定义了的main节点为空,则将整个包的目录都复制到wwwroot/lib下。
  • 如果定义了exportsOverride节点,则只会把该节点指定的文件复制到wwwroot/lib下。
  注意,exportsOverride节点中定义的key/value,其中key表示要文件复制目标(即wwwroot/lib下)对应包名下的子目录,value表示源文件目录或文件。例如:
"bootstrap": {  "js": "dist/js/*.*", //将dist/js/下的所有文件,复制到wwwroot/lib/bootstrap/js目录下
  "css": "dist/css/*.*",
  "fonts": "dist/fonts/*.*"
  
},
  
"jquery": {
  "": "jquery.{js,min.js,min.map}" // 将jquery.js,jquery.min.js,jquery.min.map文件复制到wwwroot/lib/jquery目录下
  
},

  注意:和NPM类似,bower.json里的配置的包,不能自动移除,需要从Bower里卸载该包,并将相关的文件从wwwroot/lib中移除。


gulpfile.js
  gulpfile.js是gulp任务管理器的配置文件,默认情况下,该配置文件会把wwwroot/lib目录下的所有文件清除(clean任务),然后重新从bower_components目录中复制一份(copy任务)。
  该文件配置的修改会影响到VS里的Task Runner Explorer的显示,如下图所示:
DSC0003.png

  以默认配置为例,该配置文件在Task目录下注册了两个任务,分别是clean和copy,并默认在VS解决方案清除编译以后重新执行clean任务,但我们也可以给该任务绑定任何一个执行时间点,我们可以右键该任务->绑定->在构建之前,然后在点击面板左边的刷新按钮,这时候该绑定内容就会同步保存在gulpfile.js的第一行,代码如下:
/// <binding BeforeBuild='copy' Clean='clean' />  此时,删除wwwroot/lib目录下所有的文件,然后重新编译BookStore项目,就会自动在wwwroot/lib目录下生成所有需要的文件,即将Bower.json里定义的各种包按照配置需求复制到该目录下。

clean任务
  clean任务的主要作用,是在编译之前或清理解决方案是,将lib目录下的前端文件全部删除,以便重新copy新的文件。具体分析如下:
var gulp = require(&quot;gulp&quot;), // 引用gulp  rimraf = require(&quot;rimraf&quot;),// 引用rimraf
  fs = require(&quot;fs&quot;);  //引用文件系统
  

  
eval(&quot;var project = &quot; + fs.readFileSync(&quot;./project.json&quot;));  //读取project.json配置文件
  

  
var paths = {
  bower: &quot;./bower_components/&quot;,
  lib: &quot;./&quot; + project.webroot + &quot;/lib/&quot;
  
};
  

  
gulp.task(&quot;clean&quot;, function (cb) {  //注册clean任务
  rimraf(paths.lib, cb);  // 递归删除lib目录下的所有文件
  
});

copy任务
  copy任务则很简单,将bower_components目录下符合条件的文件复制lib目录下,分析如下:
gulp.task(&quot;copy&quot;, [&quot;clean&quot;], function () {  // 注册copy任务  var bower = { // 目录对应关系
  &quot;bootstrap&quot;: &quot;bootstrap/dist/**/*.{js,map,css,ttf,svg,woff,eot}&quot;,
  &quot;bootstrap-touch-carousel&quot;: &quot;bootstrap-touch-carousel/dist/**/*.{js,css}&quot;,
  &quot;hammer.js&quot;: &quot;hammer.js/hammer*.{js,map}&quot;,
  &quot;jquery&quot;: &quot;jquery/jquery*.{js,map}&quot;,
  &quot;jquery-validation&quot;: &quot;jquery-validation/jquery.validate.js&quot;,
  &quot;jquery-validation-unobtrusive&quot;: &quot;jquery-validation-unobtrusive/jquery.validate.unobtrusive.js&quot;
  }
  

  for (var destinationDir in bower) {
  gulp.src(paths.bower + bower[destinationDir])  // 读取源目录
  .pipe(gulp.dest(paths.lib + destinationDir));  //复制到目标文件夹
  }
  
});

Grunt任务
  VS2015中,虽然默认支持的是Gulp构建工具,但其实还支持Grunt构建工具,使用方式和Gulp类似,要使用Grunt,也需要引用类似的依赖包,示例如下:
{  &quot;version&quot;: &quot;0.0.0&quot;,
  &quot;name&quot;: &quot;&quot;,
  &quot;devDependencies&quot;: {
  &quot;grunt&quot;: &quot;0.4.5&quot;, //grunt任务管理器
  &quot;grunt-bower-task&quot;: &quot;0.4.0&quot; // 基于grunt的bower管理插件
  }
  
}
  上述代码中的grunt-bower-task是一个基于grunt的bower管理插件,用于自动执行bower的install命令来安装Bower包。

  注意:已经安装的包不能自动移除(即不能通过在JSON中移除配置),需要右键执行该包,并手工卸载。

  gruntfile.js是grunt任务管理器的配置文件,要使用grunt,就需要创建gruntfile.js文件,默认情况下,该配置文件只配置了grunt-bower-task插件的任务执行,该插件会读取bower.json配置信息,将相关的包通过bower:install命令都安装到指定的目录下(默认是通过targetDir设置的wwwroot/lib目录。
  该文件配置的修改会影响到VS里的Task Runner Explorer的显示,如下图所示:
DSC0004.png

  以默认配置为例,该配置文件注册了一个名为default的任务在该面板里(Alias Tasks列表中)显示,该任务也是Grunt的默认任务名称,但并没有定义该任务在什么时候执行,所以这时候我们可以给该任务绑定一个执行时间点,我们可以右键该任务->绑定->在构建之前,然后在点击面板左边的刷新按钮,这时候该绑定内容就会同步保存在gruntfile.js的第一行,代码如下:
/// <binding BeforeBuild='default' />  此时,删除wwwroot/lib目录下所有的文件,然后重新编译BookStore项目,就会自动在wwwroot/lib目录下生成所有需要的文件,即将Bower.json里定义的各种包按照配置需求复制到该目录下。而Tasks中的任务,则是从grunt.loadNpmTasks里加载的包里分析出来的任务,如bower。
  
我们再来练习一个例子,假设我们编译之前要对wwwroot/css/目录下的site.css文件进行压缩(压缩成site.min.css),我们则可以安装如下方式进行操作:
  首先,在package.json里定义一个可以压缩CSS代码的grunt插件:
{  &quot;version&quot;: &quot;0.0.0&quot;,
  &quot;name&quot;: &quot;&quot;,
  &quot;devDependencies&quot;: {
  &quot;grunt&quot;: &quot;0.4.5&quot;,
  &quot;grunt-bower-task&quot;: &quot;0.4.0&quot;,
  &quot;grunt-contrib-cssmin&quot;: &quot;0.12.2&quot;  /*新的插件*/
  }
  
}
  然后在grunt.initConfig下的bower同级节点下面,添加如下内容:
/*压缩css*/  
cssmin: {
  target: {
  options: {
  sourceMap: true,
  },
  files: {
  /*输出文件路径:原始文件路径*/
  'wwwroot/css/site.min.css': 'wwwroot/css/site.css'
  }
  }
  
}
  最后再注册此插件,代码如下:
grunt.loadNpmTasks('grunt-contrib-cssmin'); /*压缩css*/  这样,你就可以在Task Runner Explorer面板中看到cssmin任务,然后运行它了,当然你也可以将该任务和default任务一起添加到编译构建之前进行执行。代码如下:
/// <binding BeforeBuild='default, cssmin' />  另外,在给一些例子,一个是用于js压缩,一个是用于less编译,代码如下:
/*package.json*/  
&quot;grunt-contrib-uglify&quot;: &quot;0.9.1&quot;,
  
&quot;grunt-contrib-less&quot;: &quot;1.0.1&quot;
  

  
/*gruntfile.js*/
  
/*压缩js*/
  
uglify: {
  target: {
  options: {
  sourceMap: true,
  },
  files: {
  'wwwroot/Scripts/site.min.js': 'wwwroot/Scripts/site.js'
  }
  }
  
},
  
/*编译less*/
  
less: {
  //开发版(无压缩)
  development: {
  options: {
  sourceMap: true
  },
  files: {
  'wwwroot/Styles/site.css': 'wwwroot/Lesses/site.less'
  }
  },
  //生产版(压缩)
  production: {
  options: {
  compress: true
  },
  files: {
  'wwwroot/Styles/site.min.css': 'wwwroot/Lesses/site.less'
  }
  }
  
}
  
/*...*/
  
grunt.loadNpmTasks('grunt-contrib-uglify');  /*压缩js*/
  
grunt.loadNpmTasks('grunt-contrib-less');   /*编译less*/

  建议:不要在多个时期都绑定同一种任务。
  
推荐:grunt还有一个插件用于监控文件的修改,比如兼容css文件的修改,一旦修改了就调用css的压缩命令,详情请参考grunt-contrib-watch插件。


config.json
  config.json就是以前的web.config,但是没有web.config拥有各种类型的配置那么强大,其中各种功能的配置都以代码的形式转移到Startup.cs文件中了;另外一部分信息配置内容,则放在config.json文件中以json的格式进行保存。
  注意,该文件的信息默认并没有自动加载,而是需要自己手工加载该配置信息,代码如下:
  

//Startup.cs类的构造函数中  
Configuration = new Configuration()
  .AddJsonFile(&quot;config.json&quot;)
  .AddEnvironmentVariables();
  

  通过Configuration实例加载该配置文件,保存在Configuration属性中,以便可以在其它地方进行使用,而使用时候的key值,则是按照层级来定义的,以如下默认内容来说:
  

{  &quot;AppSettings&quot;: {
  &quot;SiteTitle&quot;: &quot;WebDemo01&quot;
  }
  
}
  

  要获取链接字符串,则需要使用如下key值:
  

var connString = Configuration.Get(&quot;AppSettings:SiteTitle&quot;);  

  使用起来,没有web.config方便了,但是为了兼容其它操作系统,只能这样了。

  注意:在ASP.NET5中,配置信息不仅支持json格式,还支持ini、xml等格式,具体详细请参考后续的配置信息管理章节。


Startup.cs
  Startup.cs是整个程序的启动入口,类似于Global.asax,和Global.asax文件一样,起到全局配置信息的作用。我们来分析一下该文件的几个重要作用。
  首先在构造函数中初始化基础配置信息(关于详细的配置信息内容请参考配置信息管理章节),注意这里的初始化后的配置信息绑定到一个Configuration属性上了,以便另外两个方法在后期进行使用,如果你要在其它类中进行使用,则需要将该实例保存到其它地方(如静态变量)。
  ConfigureServices方法是依赖注入的核心,在方法的传入参数services中,首先保存了默认依赖注入里定义的类型定义,然后我们在这个方法里,可以继续注册依赖注入的类型定义,关于依赖注入的详细内容,可以阅读依赖注入章节。
  同时一些重要的功能需要开启的话,也需要在这里开启,比如添加Mvc模块,就需要使用如下调用语句:
  

services.AddMvc();  

  原因是因为,在新版的ASP.NET 5中,除了最基础的模块以外,绝大部分模块都是纯组件化的,这里称为Middleware,而组件在使用的时候首先需要先添加该模块才能使用。再比如,添加EF模块的话,需要调用
  

services.AddEntityFramework()方法。  

  而另外一个Configure方法,顾名思义是对各种Middleware组件进行配置的地方,一般来说,配置模块的方法都是调用类似app.UseXXX()这样的方法,如使用静态文件处理流程,则调用如下语句即可:
  

app.UseStaticFiles();  

  如果要使用Mvc的功能,则需要使用app.UseMvc方法,在调用这些方法时,可以配置并传入响应的参数。
  注意,ConfigureServices里用到的services.AddXXX()类型的方法和Configure方法里用到的app.UseXXX()类型的方法都是扩展方法,AddXXX()方法是在IServiceCollection接口上进行扩展的,而UseXXX()方法则是在IApplicationBuilder接口上扩展的。

  关于该文件中提到的依赖注入、以及Configure方法中的3个类型的参数:IApplicationBuilder、IHostingEnvironment、ILoggerFactory;我们会在后续的章节中进行详细讲解。


其它
  通过查看,可以发现,Views目录下的web.config也被移除了,在RC版中,要统一引用命名空间,需要在 _ViewStart.cshtml 或者 _GlobalImport.cshtml 文件中,后续章节我们会讲到。
  我们不用做任何修改,F5运行项目即可运行,由于默认使用的是IIS Express,所以会自动打开新网站首页。如果不是IIS Express,请阅读后续的编译与部署章节。

关于上述json配置文件的scheme介绍
  关于上述配置文件(含global.json、project.json、config.json、package.json、bower.json)的scheme定义,以及js参数配置的定义,请访问http://schemastore.org/json/进行查看。
  推荐资料:


  • beiyuu.com/grunt-in-action/
  • http://www.it165.net/pro/html/201503/35652.html
同步与推荐
  本文已同步至目录索引:解读ASP.NET 5 & MVC6系列

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-345646-1-1.html 上篇帖子: 认识HTML5的WebSocket 下篇帖子: node.js 初体验
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表