【问题标题】:How does IIS know if it's serving a Web Site or a Web Application project?IIS 如何知道它是服务于网站还是 Web 应用程序项目?
【发布时间】:2009-05-07 20:15:51
【问题描述】:

我了解网站项目会即时编译源代码,而 Web 应用程序项目会将源代码预编译成 DLL(很像 ASP.Net 1.x)。

但是在 IIS 中指定的区别是什么?

我知道 Visual Studio 知道——每个都有不同的项目,等等。但是运行实例(IIS + 框架)必须知道正在使用哪种编译模型,对吗?因为它怎么知道是否要即时编译?

一个请求进来,命中一个 ASPX 文件......进程如何知道相关的 CS 文件是否需要编译(网站),或者是否在部署之前已经完成(Web 应用程序)?

我只是好奇这种差异是在哪里指定的。在 web.config 的某个地方?

【问题讨论】:

  • 达人如果你想知道投票的问题

标签: asp.net iis compilation


【解决方案1】:

在这些项目类型中您会发现 .aspx 文件存在细微差别。

如果您查看网站项目,您应该会看到类似这样的内容...

<%@ Page Language="C#" AutoEventWireup="true"  
CodeFile="Default.aspx.cs" Inherits="_Default" %>

... Web 应用程序项目将包含类似这样的 .aspx 文件...

<%@ Page Language="C#" AutoEventWireup="true" 
CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>

请注意,第一个具有 CodeFile 属性,第二个具有 CodeBehind 属性。这就是区分的地方。

在运行时不使用 CodeBehind 属性 - 它用于告诉 VS.NET 代码所在的位置,而 Inherits 属性告诉运行时在二进制文件中搜索哪个类。

CodeFile属性是在运行时使用的,被aspnet_compiler.exe用来生成代码,然后Inherits属性如上使用。

有关这些属性的更多信息,请看这里...

http://msdn.microsoft.com/en-us/library/ydy4x04a.aspx

但要回答您的问题“IIS 是如何知道的?”答案是“没有”。 ASP.NET 知道。

您可以通过执行以下操作来证明是这种情况:

  1. 创建一个新的 Web 应用程序。这将包括一个 Default.aspx 和一个 Default.aspx.cs。
  2. 将以下代码添加到 Default.aspx.cs 中:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("hello");
    }
    
  3. 编译项目,运行它,查看 文本“hello”出现在浏览器中。

  4. 现在,更改代码,使其看起来 像这样,并保存 .cs 文件:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("goodbye");
    }
    
  5. 不要编译。刷新您的浏览器。你仍然会看到“hello”,因为编译后的代码仍然使用这个字符串。

  6. 现在,将 Default.aspx 中的属性从 CodeBehind 更改为 CodeFile。保存此文件。

  7. 刷新您的浏览器。您会看到显示“再见”。

  8. 将代码中的“再见”更改为“我相信!”。保存 .aspx.cs 但不要编译。

  9. 刷新您的浏览器,看到“我相信!”,然后在开悟的房间里跳舞 :-)

【讨论】:

  • 假设这是准确的,它正是我正在寻找的。我知道某处必须有一些小设置...
  • 所以,试试看。以 Web 应用项目为例,将 .aspx 文件更改为具有 CodeFile 属性而不是 CodeBehind 属性,然后查看您现在是否可以在实时站点上编辑 .cs 并查看差异,而无需使用 VS.NET 编译代码。我刚刚做了这个测试并证明它是真的。
  • 那么,同一站点中的某些 Web 表单是否有 CodeFile,而其他 Web 表单有 CodeBehind?会发生什么? (我不知道你为什么要这样做,但考虑一下很有趣......)
  • 是的——你可以混搭。正如你所说,这样做将是一件奇怪的事情。事实上,我倾向于认为让 ASP.NET 在运行时编译东西的网站机制是一个糟糕的主意——我喜欢对我的代码进行单元测试,FxCop'd 它,并且知道它很好(而不是仅仅抛出一些.cs 文件到网站上并希望获得最好的结果)。
  • 我也给了这个+1。它帮助我解决了一个我无法在本地重现的令人讨厌的错误(而且我们都知道客户多么讨厌听到“它在我的机器上工作”)。
【解决方案2】:

IIS 所做的只是将传入的请求传递给适当的处理程序。对于 ASP.NET 站点/应用程序,它是 aspnet_isapi.dll。然后处理程序从那里处理所有事情。

【讨论】:

  • 您可以在 IIS 管理员中查看/编辑/破坏此链接:打开网站或虚拟目录的属性,选择主目录选项卡,单击配置按钮(右下角),映射选项卡。
【解决方案3】:

一旦网站或网络应用程序被编译,网络服务器就没有区别了。 IIS 中的 .NET 处理程序始终:

  1. 编译 ASPX 页面。
  2. Jit 构建的程序集到临时文件区域。
  3. 运行请求

在站点完全编译成单个 dll 的情况下,仍然有单行 ASPX 文件告诉 IIS 中的 .NET 处理程序从哪里获取代码。或者,可以通过 web.conig 中的一些额外配置行来完全删除 ASPX 页面。

但简短的答案是真的一旦编译它们是相同的。

【讨论】:

  • 我意识到它们是相同的,但是 IIS(或框架——无论如何)如何知道 Web 根目录中的 .cs 文件已经编译成 bin 中的 DLL ......或者不是吗?
  • 它没有。处理程序会照顾它,并且每次都以相同的方式对待它。如果在 aspx @Page 指令中指定了后面的代码,那么处理程序显然需要首先编译它。在 VS 中,它基本上是一个语义上的区别,但是一旦它被部署到 IIS,aspnet_isapi 过滤器就会对它们进行相同的处理。
【解决方案4】:

我很确定框架可以处理这个问题,而且它对 IIS 是透明的。

【讨论】:

  • 但是框架是怎么知道的呢?在某个地方,在生产 Web 服务器上,必须有一些设置或标志,上面写着“即时编译”或“不要,因为它都在那个 DLL 中。”
猜你喜欢
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 2014-04-22
  • 2011-08-20
相关资源
最近更新 更多