【续集】在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题
dudu 的一篇博文:在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题
针对 IIS 部署 ASP.NET 5 应用程序的问题,在上面博文中主要采用两种方式尝试:
- VS2015 的 Publish 方式(成功)。
- 手动复制文件的方式(失败)。
本篇博文主题:
- 初步理解 ASP.NET 5 的编译及部署问题。
- 解决 ASP.NET 5 预编译,并成功部署到 IIS 上。
先啰嗦两句:
首先,现在的 IIS 对于 ASP.NET 5 来说,其实已经没有太大的关系了,用不用它都无所谓,ASP.NET 5 应用程序可以采用 Self-Hosting(自寄宿)的方式,也就是自己当作 Web 服务器,实现方式只要在 project.json 中添加 Microsoft.AspNet.Hosting 程序包就可以了,我们知道,Web 服务器的作用其实就是监听请求,并分发请求给相应模块进行处理,最后再输出处理结果,如果我们把这个请求处理过程进行分化,交给不同的组件或模块进行处理,我们就可以脱离集成化的 IIS,在 Owin 体系结构中,ASP.NET 5 应用程序部署到 IIS 上,这个 IIS 的作用就只是一个 Host(管理应用程序的线程,打开、关闭或加载组件),Server(如 Microsoft.AspNet.Server.WebListener)和 Middleware(如 Microsoft.AspNet.StaticFiles)都有相应的处理组件,不需要用到 IIS 的那一套东西,比如之前我们需要在 IIS 中进行 HttpModule 配置等。
既然我们不使用 IIS 的那一套东西,如果将 ASP.NET 5 应用程序部署到 IIS 上,那就必须有个东西将 IIS 和 ASP.NET 5 独立运行时(KRE)之间的通道(Pipeline)打通,这个东西就是 AspNet.Loader.dll(位置:application/wwwroot/bin),使用它的条件是在 project.json 中添加 Microsoft.AspNet.Server.IIS 程序包,而且只在 IIS 中才会出现,如果采用的是 Self-Hosting 方式,这个程序集将会“消失”,关于 AspNet.Loader.dll,一篇非常好的解答文章:AspNet.Loader.dll – what is this for?
另外,在 IIS 中部署 ASP.NET 5 应用程序,不像我们之前的方式,直接把相应的文件和程序集拷贝到站点目录下,因为你会发现,在生成 ASP.NET 5 项目的时候没有生成对应的程序集,只是在 Bin 目录下有一个 AspNet.Loader.dll,dudu 已经试过在 ASP.NET 5 项目属性页的 Build 选项中,把“Produce outputs on build”选项打勾,就会生成相应的程序集文件(位置:../application/artifacts/bin),既然有了程序集,那是不是就可以像之前部署站点的方式进行操作呢?答案当然不是,这也就是为什么手动复制文件会失败,因为 ASP.NET 5 并没想象中的那么简单,呵呵,采用 VS2015 的 Publish 方式部署是成功的,那我们就从它下手,观察下它到底是怎么回事,dudu 没做完这步,我们下面接着做。
言归正传
用 VS2015 创建一个简单的 ASP.NET 5 项目:
project.json 配置:
{
"webroot": "wwwroot",
"version": "1.0.0-*",
"exclude": [
"wwwroot"
],
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-beta1",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta1",
"HelloClassLibrary": "1.0.0-*"
},
"commands": {
/* Change the port number when you are self hosting this application */
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
},
"frameworks": {
"aspnet50": { },
"aspnetcore50": { }
}
}
Startup.cs 代码:
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
namespace HelloAspNet5
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(context => context.Response.WriteAsync("Hello, ASP.NET 5 world! \{HelloClassLibrary.TestClass.testContent}"));
}
}
}
为了演示 ASP.NET 5 与依赖类库之间的关系,我们还创建了一个 HelloClassLibrary 项目,并在 Startup 中进行调用。在 project.json 中配置 commands 是为了方便我们通过 Publish 发布出来的程序检测是否可以正常运行。
Publish 发布文件结构:
approot 为程序文件及程序包目录,packages 下面是整个应用程序运行所需要的程序包,src 为程序源代码目录,wwwroot 为站点目录(我们等下 IIS 部署的时候,就是指向的这个目录),里面有一个 bin 目录(只有一个 AspNet.Loader.dll)和一个 web.config 文件(里面主要配置一些地址路径,比如程序包的地址路径)。web.cmd 是批处理文件,它其实就是我们在 commands 中制定的命令(还可以配置 EF 迁移的命令)。
上面是本地运行结果(注意,我并没有安装 IIS),你也可以直接点击 web.cmd 来启动站点。
既然本机运行没问题,那我们就把它发布到 IIS 上试试,但是却报下面的错误:
错误信息:Couldn't find package 'KRE-CLR-amd64.1.0.0-beta1'. Locations probed,什么意思?本机是 32 位系统,服务器是 64 位系统,发布设置我们选的是“KRE-CLR-x86.1.0.0-beta1”,不报错才怪,重新更改发布设置为“KRE-CLR-amd64.1.0.0-beta1”:
然后把发布生成 HelloAspNet5.Web\approot\packages\KRE-CLR-amd64.1.0.0-beta1 下的文件,添加到服务器相应目录下,重新刷新浏览器,运行成功:
Hello, ASP.NET 5 world! HeiHei
上面这些操作其实 dudu 已经完成了,并且也是成功的,但这并不是我们想要的,因为这时候,服务器运行的程序是“动态编译”的,程序代码地址就在 HelloAspNet5.Web\approot\src 目录下,里面直接是源代码,并不是生成的程序集文件,那该如何“预编译”我们的 ASP.NET 5 应用程序呢?
首先,我们需要生成我们的应用程序,就像我们之前的 ASP.NET 应用程序一样,而 ASP.NET 5 默认是“动态编译”的,如果想设置成预编译,需要我们手动设置一下:
在项目属性页的 Build 选择中,把“Produce outputs on build”打勾就可以了,HelloClassLibrary 类库项目同样这样设置,设置好了,重新生成项目,生成的程序集目录为:\HelloAspNet5\artifacts\bin\HelloAspNet5\Debug,在相应目录下,就会看到我们想要的两个程序集文件:HelloAspNet5.dll 和 HelloClassLibrary.dll,既然项目程序集生成成功,那部署应该没有什么问题,但 dudu 已经尝试过,是失败的,问题出在哪?直接把相应的程序集文件拷贝过去不行吗?当然不行,因为我们使用 VS2015 Publish 的时候,运行环境是“动态编译”,那怎么使 Pulish 的时候预编译呢?答案就在下面:
在 Publish 的时候,还有一个发布选项“Precompile during publishing”,就是配置预编译的,重新发布一下,你会发现在 packages 目录下多了两个文件夹:
这就是预编译生成的项目文件地址,我们再来看下 HelloAspNet5 的文件目录:
一个是 lib 目录,里面就是生成的程序集文件,root 是程序的其他类型文件,比如 MVC Views 文件就在这里,而不是在 wwwroot 目录下。另外一个非常重要的地方就是,wwwroot 下的 web.config 变成了:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="kpm-package-path" value="..\approot\packages" />
<add key="bootstrapper-version" value="1.0.0-beta1" />
<add key="kre-package-path" value="..\approot\packages" />
<add key="kre-version" value="1.0.0-beta1" />
<add key="kre-clr" value="CLR" />
<add key="kre-app-base" />
</appSettings>
</configuration>
好像也没怎么变化?跟之前的自习对比一下,会发现 key(kre-app-base)的 value 值不见了,之前的配置为
<add key="kre-app-base" value="..\approot\src\HelloAspNet5" />
看到这你应该懂了,没错,你可以把 approot\src 目录下的 HelloAspNet5 源代码文件删掉了,使用 k web 命令重新启用项目,运行成功:
Hello, ASP.NET 5 world! HeiHei
接着我们重新在服务器的 IIS 上也这样搞,但是却出现了下面的错误:
错误信息:Couldn't find package 'KRE-CLR-amd64.1.0.0-beta1',找不到“KRE-CLR-amd64.1.0.0-beta1”程序包,在 approot\packages 目录下明明就有啊,查看下面的提示发现 IIS 并没有从这个目录下进行查找,怎么办?手动配置一下:
<add key="kre-app-base" value="..\approot\packages\HelloAspNet5\1.0.0\root"/>
需要注意的是,要配置到 root 目录下,重新启动项目,运行成功:
Hello, ASP.NET 5 world! HeiHei
我们接下来修改代码,然后通过编译程序集上传到 IIS 服务器。
app.Run(context => context.Response.WriteAsync("Hello, ASP.NET 5 world!!! \{HelloClassLibrary.TestClass.testContent}"));
public static string testContent = " HeiHeiHei";
可以看出,上面代码和之前的代码是有些不同的,之前有说过使用 VS2015 编译的程序集地址为 artifacts,我们把相应的程序集文件上传到服务器的 approot\packages 目录下,奇怪的事,我运行后发现改的代码并没有效果,还是之前的,这个问题搞了我很久,都快被搞死了,我以为是生成的程序集文件有问题,没有生成最新的,就各种设置生成测试,最后还是没有成功,然后无意间把 IIS 站点停掉,然后再进行上传程序集文件,最后再启动站点,刷新浏览器,你猜怎么着?Oh, My God !!!,居然出现了:
Hello, ASP.NET 5 world!!! HeiHeiHei
最后再啰嗦两句:
从上面整个配置过程中可以看出,ASP.NET 5 是如何在 IIS 进行运行的(只是从 Publish 上来看),首先,站点目录为 wwwroot,包含一个 bin 目录的 AspNet.Loader.dll 文件(用来打通 IIS 和 Owin 组件之间的管道),还有一个 web.config 文件(主要配置程序包及应用程序路径地址),除此之外,还有一些静态文件(如 css、js 和图片文件),如果是动态编译站点,默认直接运行 approot\src 目录下的源代码文件,如果是预编译站点,根据 kre-app-base 的路径配置(如 approot\packages\HelloAspNet5\1.0.0\root),运行 ASP.NET 5 运行程序,注意在 root\project.json 文件中,有如下配置:"webroot": "..\..\..\..\..\wwwroot",这个指向的地址就是 IIS 站点。。。
其实,上面虽然只是一个简单的 IIS 部署过程,但涉及到非常多的东西,也有很多的感触,或许有些没表达出来,总的来说,这次部署给我最重要的感受是:ASP.NET 5 完全的组件化,不只是开发,部署也是如此,这样的结果就是充满着无限可能,看我七十二变!!!
其他相关资料:
- AspNet.Loader.dll – what is this for?
- DEVELOPING AND SELF-HOSTING SIMPLE ASP.NET VNEXT APPLICATION USING COMMAND LINE TOOLS
- Introducing the ASP.NET 5 Preview
- A First Look at ASP.NET vNext
- ASP.NET Internals – Managed runtime loader
- Possible ASP.NET 5 (vNext) Deployed Folder Structure(With and Without Source)
- ASP.NET 5 on Azure Websites
- Cant get a basic ASP.Net 5 website working on Azure
- How to disable source code publishing in ASP.NET 5 apps?
【续集】在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题的更多相关文章
- 在IIS中部署ASP.NET 5应用程序遭遇的问题
用VS2015中创建了一个非常简单的ASP.NET5程序: 在Startup.cs中只输入一行代码: using System; using Microsoft.AspNet.Builder; usi ...
- 在IIS中部署Asp.Net网站
在IIS中部署Asp.Net网站 1.添加IIS或者删除IIS,在控制面板=>程序和功能=>打开或关闭功能 启动iis,右键计算机=>管理=>服务和应用程序=>Inter ...
- 在IIS中部署Asp.net Mvc
概述: 最近在做一个MVC 3的项目,在部署服务器时破费了一番功夫,特将过程整理下来,希望可以帮到大家! 本文主要介绍在IIS5.1.IIS6.0.IIS7.5中安装配置MVC 3的具体办法! 正文: ...
- IIS 上部署 ASP.NET Core 应用程序
1.下载 .Net Core Runtime 和 Hosting Bundle 下载地址:https://dotnet.microsoft.com/download/dotnet-core 分别下载 ...
- Windows + IIS 环境部署Asp.Net Core App
环境:Windows Server 2012, IIS 8, Asp.Net Core 1.1. 不少人第一次在IIS中部署Asp.Net Core App的人都会遇到问题,会发现原来的部署方式无法运 ...
- Windows Server 2008 R2 + IIS 环境部署Asp.Net Core App
Windows + IIS 环境部署Asp.Net Core App 环境:Windows Server 2012, IIS 8, Asp.Net Core 1.1. 不少人第一次在IIS中部署A ...
- 如何在IIS6,7中部署ASP.NET网站
http://www.cnblogs.com/fish-li/archive/2012/02/26/2368989.html 阅读目录 开始 查看web.config文件 在IIS中创建网站 IIS6 ...
- 如何在IIS6,7中部署ASP.NET网站(转载)
查看web.config文件 web.config通常会放在网站的根目录,这个文件中包含了一最重要的网站运行参数.比如: connectionStrings,httpHandlers,httpModu ...
- [Asp.Net Core] 1. IIS中的 Asp.Net Core 和 dotnet watch
在基于传统的.NET Framework的Asp.Net Mvc的时候,本地开发环境中可以在IIS中建立一个站点,可以直接把站点的目录指向asp.net mvc的项目的根目录.然后build一下就可以 ...
随机推荐
- STM32之ADC+步骤小技巧(英文)
神通广大的各位互联网的网友们.大家早上中午晚上好好好.今早起来很准时的收到了两条10086的扣月租的信息.心痛不已.怀着这心情.又开始了STM32的研究.早上做了计算机控制的PID实验,又让我想起了飞 ...
- (转)win7 64 安装mysql-python:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory
原文地址:http://www.cnblogs.com/fnng/p/4115607.html 作者:虫师 今天想在在win7 64位环境下使用python 操作mysql 在安装MySQL-pyth ...
- Python之路Day15--JavaScript(一)
一.JavaScript简介 JavaScript是世界上最流行的脚本语言,因为你在电脑.手机.平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱动的. ...
- SQL语句操作数据与一些函数使用的丰富数据库
数据库有多重要,其实不用我说,但该怎么运用好数据库下SQL语句与其它的如“函数”等等,那就需要我们大家多多去练习并总结其中的窍门,或许你的总结没那么好,担只要你的练习足够多,就算那不是窍门,那也将是你 ...
- 拯救无法启动的虚拟机文件.vmdk中的数据
FROM: http://blog.csdn.net/npy_lp/article/details/7686583 从事Linux开发的软件工程师几乎都使用过虚拟机软件,如VMware worksta ...
- 使用Javascript来实现二级联动菜单的效果
效果图如下: 具体实现步骤如下: 1.所用js代码如下: <script type="text/javascript"> var arr_province=[" ...
- rails4.0 session activerecord
Active Record Session Store A session store backed by an Active Record class. A default class is pro ...
- SQL Server 2012大幅增强T-SQL
SQL Server 2012对T-SQL进行了大幅增强,其中包括支持ANSI FIRST_VALUE和LAST_VALUE函数,支持使用FETCH与OFFSET进行声明式数据分页,以及支持.NET中 ...
- 8天掌握EF的Code First开发系列之动手写第一个Code First应用
返回<8天掌握EF的Code First开发>总目录 本篇目录 创建控制台项目 根据.Net中的类来创建数据库 简单的CRUD操作 数据库模式更改介绍 本章小结 自我测试 上一篇<8 ...
- NodeJS入门(四)—— path对象
很快Node就会迎来4.0的时代,届时将并入现有的iojs,所以先前写过的iojs入门系列直接更名为NodeJS入门. 本篇开始将逐个介绍Node的各主要模块,依循API文档走一遍,但会给出比API文 ...