dudu 的一篇博文:在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题

针对 IIS 部署 ASP.NET 5 应用程序的问题,在上面博文中主要采用两种方式尝试:

  1. VS2015 的 Publish 方式(成功)。
  2. 手动复制文件的方式(失败)。

本篇博文主题:

  1. 初步理解 ASP.NET 5 的编译及部署问题。
  2. 解决 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 完全的组件化,不只是开发,部署也是如此,这样的结果就是充满着无限可能,看我七十二变!!!

其他相关资料:

【续集】在 IIS 中部署 ASP.NET 5 应用程序遭遇的问题的更多相关文章

  1. 在IIS中部署ASP.NET 5应用程序遭遇的问题

    用VS2015中创建了一个非常简单的ASP.NET5程序: 在Startup.cs中只输入一行代码: using System; using Microsoft.AspNet.Builder; usi ...

  2. 在IIS中部署Asp.Net网站

    在IIS中部署Asp.Net网站 1.添加IIS或者删除IIS,在控制面板=>程序和功能=>打开或关闭功能 启动iis,右键计算机=>管理=>服务和应用程序=>Inter ...

  3. 在IIS中部署Asp.net Mvc

    概述: 最近在做一个MVC 3的项目,在部署服务器时破费了一番功夫,特将过程整理下来,希望可以帮到大家! 本文主要介绍在IIS5.1.IIS6.0.IIS7.5中安装配置MVC 3的具体办法! 正文: ...

  4. IIS 上部署 ASP.NET Core 应用程序

    1.下载 .Net Core Runtime 和 Hosting Bundle 下载地址:https://dotnet.microsoft.com/download/dotnet-core 分别下载 ...

  5. Windows + IIS 环境部署Asp.Net Core App

    环境:Windows Server 2012, IIS 8, Asp.Net Core 1.1. 不少人第一次在IIS中部署Asp.Net Core App的人都会遇到问题,会发现原来的部署方式无法运 ...

  6. 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 ...

  7. 如何在IIS6,7中部署ASP.NET网站

    http://www.cnblogs.com/fish-li/archive/2012/02/26/2368989.html 阅读目录 开始 查看web.config文件 在IIS中创建网站 IIS6 ...

  8. 如何在IIS6,7中部署ASP.NET网站(转载)

    查看web.config文件 web.config通常会放在网站的根目录,这个文件中包含了一最重要的网站运行参数.比如: connectionStrings,httpHandlers,httpModu ...

  9. [Asp.Net Core] 1. IIS中的 Asp.Net Core 和 dotnet watch

    在基于传统的.NET Framework的Asp.Net Mvc的时候,本地开发环境中可以在IIS中建立一个站点,可以直接把站点的目录指向asp.net mvc的项目的根目录.然后build一下就可以 ...

随机推荐

  1. 应用TortoiseGit为github账号添加SSH keys

    每次同步或者上传代码到githun上的代码库时,需要每次都输入用户名和密码,这时我们设置一下SSH key就可以省去这些麻烦了.若果使用TortoiseGit作为github本地管理工具,Tortoi ...

  2. Web服务网站故障分析常用的命令

    1.查看TCP连接状态netstat -nat |awk ‘{print $6}’|sort|uniq -c|sort -rn netstat -n | awk ‘/^tcp/ {++S[$NF]}; ...

  3. Python 爬虫3——第一个爬虫脚本的创建

    在进行真正的爬虫工程创建之前,我们先要明确我们所要操作的对象是什么?完成所有操作之后要获取到的数据或信息是什么? 首先是第一个问题:操作对象,爬虫全称是网络爬虫,顾名思义,它所操作的对象当然就是网页, ...

  4. ajax教程

    本文来自w3school 简介: AJAX = Asynchronous JavaScript and XML 异步的javascript和xml ajax不是新的编程语言,而是一种使用现有标准的新方 ...

  5. 【hihoCoder】1036 Trie图

    题目:http://hihocoder.com/problemset/problem/1036 给一个词典dict,词典中包含了一些单词words.要求判断给定的一个文本串text中是否包含这个字典中 ...

  6. MAC下使用Charles抓取安卓模拟器数据

    一.安装Charles,这个不多记录 二.Charles数据乱码问题(参照这篇文章 http://blog.csdn.net/huanghanqian/article/details/52973651 ...

  7. LabVIEW 吸星大法 - 看见的好东西都是我的(中篇)

    前言 写了多年的LabVIEW程序,你是否面临这样的问题 总是在做一些重复的工作,感觉很没有意思: 总在不停的写代码,做类似的控件,实现相同的功能,丝毫没有成就感: 总在天加班,没有时间去提高自己; ...

  8. Struct2 csv文件上传读取中文内容乱码

    网络上搜索下,发现都不适合 最终改写代码: FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br= n ...

  9. Javascript中call和apply的区别和用法

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别.其实就是更改对象的内部指针,即改变对象的this指向的内容.这在面向对象的js编程过程中有时是很有用的.call ...

  10. Oracle EBS - Doc

    Oracle EBS spec.: http://vianet/IT/IT%20Dept/IT%20Project%20Update2/Active%20Projects%20%20Manufactu ...