Как IIS узнает, обслуживает ли он веб-сайт или проект веб-приложения?

Я понимаю, что проекты веб-сайтов компилируют исходный код на лету, а проекты веб-приложений предварительно компилируют исходный код в DLL (во многом как ASP.Net 1.x).

Но как разница указывается в IIS?

Я знаю, что Visual Studio знает - для каждого есть разные проекты и т. Д. Но работающий экземпляр (IIS + Framework) должен знать, какая модель компиляции используется, верно? Потому что как еще он узнает, компилировать на лету или нет?

Приходит запрос, попадает в файл ASPX ... и как процесс узнает, нужно ли скомпилировать связанный файл CS (веб-сайт) или это уже было сделано перед развертыванием (веб-приложение)?

Мне просто любопытно, где указывается эта разница. Где-нибудь в web.config?


person Deane    schedule 07.05.2009    source источник
comment
Дарен, если хочешь знать, проголосуй за вопрос   -  person Johnno Nolan    schedule 08.05.2009


Ответы (4)


В файле .aspx есть небольшая разница, которую вы найдете в этих типах проектов.

Если вы посмотрите на проект веб-сайта, вы должны увидеть что-то вроде этого ...

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

... где, поскольку проект веб-приложения будет иметь файлы .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. Создайте новое веб-приложение. Это будет включать Default.aspx и Default.aspx.cs.
  2. Добавьте следующий код в Default.aspx.cs:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("hello");
    }
    
  3. Скомпилируйте проект, запустите его, посмотрите, как в браузере появится текст «привет».

  4. Теперь измените код, чтобы он выглядел так, и сохраните файл .cs:

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("goodbye");
    }
    
  5. НЕ СОБИРАЙТЕ. Обновите ваш браузер. Вы по-прежнему будете видеть "привет", потому что в скомпилированном коде по-прежнему используется эта строка.

  6. Теперь измените атрибут в Default.aspx с CodeBehind на CodeFile. Сохраните этот файл.

  7. Обновите ваш браузер. Вы увидите сообщение "до свидания".

  8. Измените «до свидания» в коде на «Я верю!». Сохраните .aspx.cs, но не компилируйте.

  9. Обновите страницу в браузере, посмотрите «Я верю!» И танцуйте по комнате просветлённо :-)

person Martin Peck    schedule 07.05.2009
comment
Если предположить, что это верно, это именно то, что я искал. Я знал, что где-то должна быть небольшая обстановка ... - person Deane; 08.05.2009
comment
Итак, попробуйте. Возьмите проект веб-приложения, измените файл .aspx, чтобы он имел атрибут CodeFile вместо атрибута CodeBehind, и посмотрите, можете ли вы теперь редактировать .cs на действующем сайте и видеть различия без использования VS.NET для компиляции кода. Я только что сделал этот тест и доказал, что это правда. - person Martin Peck; 08.05.2009
comment
Итак, могут ли некоторые веб-формы на одном сайте иметь CodeFile, а другие - CodeBehind? Что случилось бы? (Понятия не имею, зачем вы это сделали, но интересно подумать ...) - person Deane; 08.05.2009
comment
Да, вы можете смешивать и сочетать. Как вы говорите, это было бы странно. На самом деле, я склонен думать, что механизм веб-сайта, позволяющий компилировать материалы ASP.NET во время выполнения, - плохая идея - мне нравится, когда мой код тестируется модулем, FxCop'd, и я знаю, что это хорошо (а не просто бросать какие-то .cs файлы на веб-сайт и надеемся на лучшее). - person Martin Peck; 08.05.2009
comment
Я также даю этому +1. Это помогло мне с неприятной ошибкой, которую я не мог воспроизвести локально (и все мы знаем, как сильно клиенты ненавидят это слышать. Ну, это работает на моей машине). - person Malice; 26.04.2011
comment
Я также нахожу этот совет на этой странице: blog.kjeldby.dk/2008/11/dynamic-compilation-in-a-web-application/ - person Ubikuity; 29.10.2011
comment
Подходит ли этот хак для продакшена? Или только для разработки (чтобы включить компиляцию проектов веб-приложений на лету на моем компьютере разработчика)? - person Ubikuity; 29.10.2011
comment
Это не взлом - это то, как работает ASP.NET. Лично я предпочитаю, чтобы мой код был скомпилирован в сборку перед развертыванием. Я хочу это, чтобы протестировать эти компоненты. Я также использую ASP.NET MVC, чтобы избавиться от многих проблем (у вас обычно нет кода программной части в ваших представлениях MVC). - person Martin Peck; 31.10.2011

Все, что делает IIS, - это передает входящий запрос соответствующему обработчику. В случае сайта / приложения ASP.NET это aspnet_isapi.dll. Затем обработчик позаботится обо всем оттуда.

person Colin Cochrane    schedule 07.05.2009
comment
Вы можете просмотреть / отредактировать / удалить эту ссылку в администраторе IIS: откройте свойства веб-сайта или виртуального каталога, выберите вкладку «Домашний каталог», нажмите кнопку «Конфигурация» (внизу справа), вкладку «Сопоставления». - person Stijn Sanders; 08.05.2009

После того, как веб-сайт или веб-приложение скомпилированы, для веб-сервера нет никакой разницы. Обработчики .NET в IIS всегда:

  1. Скомпилируйте страницы ASPX.
  2. Переместите построенные сборки в область временных файлов.
  3. Запустить запрос

В сценариях, где сайт полностью скомпилирован в единую dll, по-прежнему существуют однострочные файлы ASPX, сообщающие обработчикам .NET в IIS, где взять код. Или страницы ASPX могут быть полностью удалены с помощью некоторых дополнительных строк конфигурации в файле web.conig.

Но краткий ответ - действительно, когда они скомпилированы, они идентичны.

person David McEwing    schedule 07.05.2009
comment
Я понимаю, что они идентичны, но как IIS (или фреймворк - что угодно) знает, что файлы .cs в корневом веб-каталоге уже скомпилированы в DLL в корзине ... или нет? - person Deane; 08.05.2009
comment
Это не так. Обработчик заботится об этом и обращается с этим каждый раз одинаково. ЕСЛИ код позади указан в директиве aspx @Page, то обработчик, очевидно, должен сначала выполнить это. В VS это в основном символическая разница, но после развертывания в IIS фильтр aspnet_isapi обрабатывает их обоих одинаково. - person David McEwing; 08.05.2009

Я почти уверен, что фреймворк справится с этим и прозрачен для IIS.

person Jimmie R. Houts    schedule 07.05.2009
comment
Но откуда фреймворк знает? Где-то на производственном веб-сервере должен быть какой-то параметр или флаг, который говорит, скомпилировать это на лету или нет, потому что все это находится в этой DLL. - person Deane; 08.05.2009