Asp net core iis

После завершения работы над приложением приложение его можно опубликовать, чтобы оно стало доступно широкому кругу пользователей. Как правило, для хостирования приложения будет применяться один из внешних хостингов, список которых можно посмотреть здесь. В данном же случае рассмотрим основные моменты публикации и развертывания приложения на локальном компьютере.

Традиционно веб-сервер IIS (Internet Information Services) применялся для развертывания веб-приложений. Для хостирования веб-приложений ASP.NET Core также может применяться IIS, только в отличие от предыдущих версий ASP.NET теперь его роль будет сводиться к прокси-серверу. Хостирование приложений ASP.NET Core на IIS происходит с помощью нативного модуля AspNetCoreModule , который сконфигурирован таким образом, чтобы перенаправлять запросы на веб-сервер Kestrel. Этот модуль управляет запуском внешнего процесса dotnet.exe, в рамках которого хостируется приложение, и перенаправляет все запросы от IIS к этому хостирующему процессу.

При разработке в Visual Studio публиковать приложения очень легко — среда разработки имеет для этого весь необходимый инструментарий. Так, возьмем какой-нибудь проект и в Visual Studio нажмем на него правой кнопкой мыши и в появившемся контекстном меню выберем пункт Publish :

И перед нами откроется окно публикации приложения:

Здесь нам доступно несколько вариантов публикации:

Microsoft Azure App Service : публикация в облаке Azure

IIS, FTP, etc : публикация через FTP

Folder : публикация в виде отдельного пакета в файловой системе текущей рабочей машины

Import Profile : импорт профиля, который содержит настройки публикации

Microsoft Azure Virtual Machines : публикация в облаке Azure, по сравнению с первой опцией обладает большими возможностями по управлению инфраструктурой развертывания

В данном случае выберем опцию Folder для создания пакета для публикации в файловой системе. И также укажем путь, по которому будет находиться пакет. В моем случае это каталог "C:CoreApp". И в конце нажмем на кнопку Publish.

Далее откроется окно, где будут оображаться выбранные настройки конфигурации, и для продолжения публикации нажмем в нем кнопку Publish:

И после окончания публикации по указанному пути (в моем случае это каталог C:CoreApp) появятся опубликованные файлы.

Настройка IIS

Прежде всего нам надо включить функциональность Web Server (IIS) и настроить роли сервера. Для этого перейдем по пути Панель управления -> Программы и компоненты -> Включение или отключение компонентов Windows . В списке компонентов найдем Службы IIS (Internet Information Services) и отметим ее:

Здесь также надо отметить подпункт "Службы Интернета" (World Wide Web Services) и все его подпункты, а также подпункт "Консоль управления IIS" (IIS Management Console).

Нажмем на ОК, и весь необходимый функционал будет добавлен в операционную систему.

Затем нам необходимо установить специальный пакет .NET Core Windows Server Hosting . Его можно найти, перейдя на страницу https://www.microsoft.com/net/download/all. Далее на этой странице надо выбрать нужную версию .NET Core Runtime ( .NET Core Runtime > .NET Core Runtime x.y.z . Далее на странице выбранной версии .NET Core Runtime перейти к подразделу Windows и выбрать Server Hosting Installer . После этого загрузится нужный пакет. Этот пакет устанавливает .NET Core Runtime, .NET Core Library и модуль ASP.NET Core Module. Данный модуль, как говорилось выше, как раз и создает проксирование между IIS и сервером Kestrel.

После установки этого пакета выполним в командной строке команду iisreset или вручную перезапустим IIS, чтобы сервер применил изменения.

Конфигурация сервера

Для конфигурации IIS перейдем к консоли управления веб-сервером. Для этого перейдем по пути Панель управления -> Администрирование -> Диспетчер служб IIS :

Нажмем правой кнопкой на узел "сайты" и в контекстном меню выберем пункт "Добавить веб-сайт. ". После этого нам откроется окно для добавления нового сайта:

В поле "Физический путь" здесь укажем каталог, в котором опубликовано приложение. А в качестве имени узла определим "localhost". Нажмем на OK, и приложение будет запущено.

Теперь перейдем к пункту Пулы приложений . Выберем пул нашего приложения и справа нажмем на ссылку Основные настройки :

В открывшемся окне для параметра Версия среды CLR .NET установим значение Без управляемого кода :

После этого пул будет перезапущен, и мы сможем обращаться к нашему приложению по адресу localhost.

Supported operating systems¶

The following operating systems are supported:

  • Windows 7 and newer
  • Windows Server 2008 R2 and newer*

*Conceptually, the IIS configuration described in this document also applies to hosting ASP.NET Core applications on Nano Server IIS, but refer to ASP.NET Core on Nano Server for specific instructions.

IIS configuration¶

Enable the Web Server (IIS) server role and establish role services.

Windows desktop operating systems¶

Navigate to Control Panel > Programs > Programs and Features > Turn Windows features on or off (left side of the screen). Open the group for Internet Information Services and Web Management Tools. Check the box for IIS Management Console. Check the box for World Wide Web Services. Accept the default features for World Wide Web Services or customize the IIS features to suit your needs.

Windows Server operating systems¶

For server operating systems, use the Add Roles and Features Wizard via the Manage menu or the link in Server Manager. On the Server Roles step, check the box for Web Server (IIS).

On the Role services step, select the IIS role services you desire or accept the default role services provided.

Proceed through the Confirmation step to enable the web server role and services.

Install the .NET Core Windows Server Hosting bundle¶

  1. Install the .NET Core Windows Server Hosting bundle on the server. The bundle will install the .NET Core Runtime, .NET Core Library, and the ASP.NET Core Module. The module creates the reverse-proxy between IIS and the Kestrel server.
  2. Execute iisreset at the command line or restart the server to pickup changes to the system PATH.

For more information on the ASP.NET Core Module, including configuration of the module and setting environment variables with web.config, the use of app_offline.htm to suspend request processing, and activation of module logging, see ASP.NET Core Module Configuration Reference .

Application configuration¶

Enabling the IISIntegration components¶

Include a dependency on the Microsoft.AspNetCore.Server.IISIntegration package in the application dependencies. Incorporate IIS Integration middleware into the application by adding the .UseIISIntegration() extension method to WebHostBuilder() .

Note that code calling .UseIISIntegration() does not affect code portability.

Setting IISOptions for the IISIntegration service¶

To configure IISIntegration service options, include a service configuration for IISOptions in ConfigureServices .

Option Setting
AutomaticAuthentication
ForwardClientCertificate
ForwardWindowsAuthentication

publish-iis tool¶

The publish-iis tool can be added to any .NET Core application and will configure the ASP.NET Core Module by creating or modifying the web.config file. The tool runs after publishing with the dotnet publish command or publishing with Visual Studio and will configure the processPath and arguments for you. If you’re publishing a web.config file by including the file in your project and listing the file in the publishOptions section of project.json, the tool will not modify other IIS settings you have included in the file.

To include the publish-iis tool in your application, add entries to the tools and scripts sections of project.json.

Deploy the application¶

  1. On the target IIS server, create a folder to contain the application’s published folders and files, which are described in Directory Structure .
  2. Within the folder you created, create a logs folder to hold application logs (if you plan to enable logging). If you plan to deploy your application with a logs folder in the payload, you may skip this step.
  3. Deploy the application to the folder you created on the target IIS server. MSDeploy (Web Deploy) is the recommended mechanism for deployment, but you may use any of several methods to move the application to the server (for example, Xcopy, Robocopy, or PowerShell). Visual Studio users may use the default Visual Studio web publish script. For information on using Web Deploy, see Публикация на IIS с помощью Web Deploy и Visual Studio .

.NET Core applications are hosted via a reverse-proxy between IIS and the Kestrel server. In order to create the reverse-proxy, the web.config file must be present at the content root path (typically the app base path) of the deployed application, which is the website physical path provided to IIS.

Sensitive files exist on the app’s physical path, including subfolders, such as my_application.runtimeconfig.json, my_application.xml (XML Documentation comments), and my_application.deps.json. The web.config file is required to create the reverse proxy to Kestrel, which prevents IIS from serving these and other sensitive files. Therefore, it is important that the web.config file is never accidently renamed or removed from the deployment.

Configure the website in IIS¶

  1. In IIS Manager, create a new website. Prov >

If you change the default identity of the application pool from ApplicationPoolIdentity, verify the new identity has the required permissions to access the application’s assets and database.

Open the Add Website window.

Configure the website.

In the Application Pools panel, open the Edit Application Pool window by right-clicking on the website’s application pool and selecting Basic Settings. from the popup menu.

Set the .NET CLR version to No Managed Code.

Browse the website.

Create a Data Protection Registry Hive¶

Data Protection keys used by ASP.NET applications are stored in registry hives external to the applications. To persist the keys for a given application, you must create a registry hive for the application’s application pool.

For standalone IIS installations, you may use the Data Protection Provision-AutoGenKeys.ps1 PowerShell script for each application pool used with an ASP.NET Core application. The keys will be persisted in the registry.

In web farm scenarios, an application can be configured to use a UNC path to store its data protection key ring. By default, the data protection keys are not encrypted. You can deploy an x509 certificate to each machine to encrypt the key ring. See Configuring Data Protection for details.

Защита данных используется различным связующим ПО ASP.NET, включая то, которое используется при аутентификации. Даже если вы специально не вызываете API защиты данных из кода, вы должны настроить защиту данных с помощью скрипта или в коде. Если вы не настроите защиту данных при использовании IIS, ключи будут храниться in-memory и сбрасываться при закрытии или перезапуске приложения. Тогда, например, любые куки, созданные для аутентификации, станут недействительными, и пользователям придется логиниться снова.

Configuration of sub-applications¶

When adding applications to an IIS Site’s root application, the root application web.config file should include the section, which adds the ASP.NET Core Module as a handler for the app. Applications added to the root application shouldn’t include the section. If you repeat the section in a sub-application’s web.config file, you will receive a 500.19 (Internal Server Error) referencing the faulty config file when you attempt to browse the sub-application.

Common errors¶

The following is not a complete list of errors. Should you encounter an error not listed here, please leave a detailed error message in the DISQUS section below (click Show comments to open the DISQUS panel).

Several of the common errors do not appear in the browser, Application Log, and ASP.NET Core Module Log until the module startupTimeLimit (default: 120 seconds) and startupRetryCount (default: 2) have passed. Therefore, wait a full six minutes before deducing that the module has failed to start a process for the application.

A quick way to determine if the application is working properly is to run the application directly on Kestrel. If the application was published as a portable app, execute dotnet .dll in the deployment folder. If the application was published as a self-contained app, run the application’s executable directly on the command line, .exe , in the deployment folder. If Kestrel is listening on default port 5000, you should be able to browse the application at http://localhost:5000/ . If the application responds normally at the Kestrel endpoint address, the problem is more likely related to the IIS-ASP.NET Core Module-Kestrel configuration and less likely within the application itself.

A way to determine if the IIS reverse proxy to the Kestrel server is working properly is to perform a simple static file request for a stylesheet, script, or image from the application’s static assets in wwwroot using Static File middleware . If the application can serve static files but MVC Views and other endpoints are failing, the problem is less likely related to the IIS-ASP.NET Core Module-Kestrel configuration and more likely within the application itself (for example, MVC routing or 500 Internal Server Error).

In most cases, enabling application logging will assist in troubleshooting problems with application or the reverse proxy. See Logging for more information.

Common errors and general troubleshooting instructions:

Installer unable to obtain VC++ Redistributable¶

  • Installer Exception: Installation of the .NET Core Windows Server Hosting Bundle fails with 0x80070002 — The system cannot find the file specified.
  • If the server does not have Internet access while installing the server hosting bundle, this exception will ensue when the installer is prevented from obtaining the Microsoft Visual C++ 2015 Redistributable (x64) packages online. You may obtain an installer for the packages from the Microsoft Download Center.

Platform conflicts with R >Troubleshooting:

  • If you published a self-contained application, confirm that you didn’t set a platform in buildOptions of project.json that conflicts with the publishing RID. For example, do not specify a platform of x86 and publish with an RID of win81-x64 (dotnet publish -c Release -r win81-x64). The project will publish without warning or error but fail with the above logged exceptions on the server.

URI endpoint wrong or stopped website¶

  • Browser: ERR_CONNECTION_REFUSED
  • Application Log: No entry
  • ASP.NET Core Module Log: Log file not created
  • Confirm you are using the correct URI endpoint for the application. Check your bindings.
  • Confirm that the IIS website is not in the Stopped state.

CoreWebEngine or W3SVC server features disabled¶

  • OS Exception: The IIS 7.0 CoreWebEngine and W3SVC features must be installed to use the Microsoft HTTP Platform Handler 1.x.
  • Confirm that you have enabled the proper server role and features. See IIS Configuration.

Incorrect website physical path or application missing¶

  • Browser: 403 Forbidden: Access is denied –OR– 403.14 Forbidden: The Web server is configured to not list the contents of this directory.
  • Application Log: No entry
  • ASP.NET Core Module Log: Log file not created
  • Check the IIS website Basic Settings and the physical application assets folder. Confirm that the application is in the folder at the IIS website Physical path.

Incorrect server role, module not installed, or incorrect permissions¶

  • Browser: 500.19 Internal Server Error: The requested page cannot be accessed because the related configuration data for the page is invalid.
  • Application Log: No entry
  • ASP.NET Core Module Log: Log file not created

Hosting bundle not installed or server not restarted¶

  • Browser: 502.3 Bad Gateway: There was a connection error while trying to route the request.
  • Application Log: Process ‘0’ failed to start. Port = PORT, Error Code = ‘-2147024894’.
  • ASP.NET Core Module Log: Log file created but empty
  • You may have deployed a portable application without installing .NET Core on the server. If you are attempting to deploy a portable application and have not installed .NET Core, run the .NET Core Windows Server Hosting Bundle Installer on the server. See Install the .NET Core Windows Server Hosting Bundle.
  • You may have deployed a portable application and installed .NET Core without restarting the server. Restart the server.

Incorrect proecessPath , missing PATH variable, or dotnet.exe access violation¶

  • Browser: HTTP Error 502.5 — Process Failure
  • Application Log: Failed to start process with commandline ‘“dotnet” .my_application.dll’ (portable app) or ‘”.my_application_Foo.exe”’ (self-contained app), ErrorCode = ‘0x80070002’.
  • ASP.NET Core Module Log: Log file created but empty

Incorrect arguments of element¶

  • Browser: HTTP Error 502.5 — Process Failure
  • Application Log: Failed to start process with commandline ‘“dotnet” .my_application_Foo.dll’, ErrorCode = ‘0x80004005’.
  • ASP.NET Core Module Log: The application to execute does not exist: ‘PATHmy_application_Foo.dll’

Missing .NET Framework version¶

  • Browser: 502.3 Bad Gateway: There was a connection error while trying to route the request.
  • Application Log: Failed to start process with commandline ‘[IIS_WEBSITE_PHYSICAL_PATH] ‘, Error Code = ‘0x80004005’.
  • ASP.NET Core Module Log: Missing method, file, or assembly exception. The method, file, or assembly specified in the exception is a .NET Framework method, file, or assembly.
  • Install the .NET Framework version missing from the server.

Stopped Application Pool¶

  • Browser: 503 Service Unavailable
  • Application Log: No entry
  • ASP.NET Core Module Log: Log file not created
  • Confirm that the Application Pool is not in the Stopped state.

IIS Integration middleware not implemented or .UseUrls() after .UseIISIntegration() ¶

  • Browser: HTTP Error 502.5 — Process Failure
  • Application Log: Process was created with commandline ‘“dotnet” .my_application.dll’ (portable app) or ‘”.my_application.exe”’ (self-contained app) but either crashed or d >Troubleshooting
  • Confirm that you have correctly referenced the IIS Integration middleware by calling the .UseIISIntegration() method of the application’s WebHostBuilder() .
  • If you are using the .UseUrls() extension method when self-hosting with Kestrel, confirm that it is positioned before the .UseIISIntegration() extension method on WebHostBuilder() . .UseIISIntegration() must set the Url for the reverse-proxy when running Kestrel behind IIS and not have its value overridden by .UseUrls() .

This is part II of the blog post series in which I share some of ways to build and deploy an ASP.NET core application to IIS running on a Windows VM. In the previous post, I cover how to build and published an ASP.NET core application. The end result is an artifact (a published directory). In this post, I go over how to deploy the artifact to IIS. Along the way, we’ll discuss:

  • Enabling IIS
  • .NET core runtime and hosting bundle
  • IIS website and application configuration
  • IIS application pool

Overview

Following are the steps for deploying a typical ASP.NET core application on IIS for the first time.

  1. Enable IIS.
  2. Install .NET core runtime and hosting bundle.
  3. Create and configure IIS website and root application
  1. Create and set application pool.
  2. Create IIS site.
    • Add bindings
    • SSL certificate
    • Set physical path to the directory containing the application files.
  3. If deploying the application as an application separating from the root application, create and configure the application under the site.
    • Set physical path to the directory containing the application files.
    • Enabling IIS

      Follow the steps below to check and enable IIS as necessary:

      1. Open Server Manager
        • You can search for it under the Start menu
        • In Server Manager, under Quick Start, click “Add roles and features”. The “Add Roles and Features Wizard” window pops up.
        • Click Next.
        • Under Select installation type, check “Role-based or feature-based installation”.
        • Under Select destination server, select the server which you want to enable IIS and click Next.
        • Under Server Roles, check “Web Server (IIS)”.
          • The system automatically select the default modules for IIS. Bes >

          .NET core runtime and hosting bundle

          When publishing the application, if you choose Framework dependent deployment (FDD), the server on which your app runs need to have the appropriate .NET core runtime installed. To check the runtime available on a server, run the following command:

          Note: To use the dotnet command tools, you need to install the SDK.

          Below shows a sample of the .net core runtimes installed on a Windows VM.

          The above runtimes mean the server can support any FDD of an application which targets .NET core between 2.0.0 and 2.2.2, thanks to the roll forward feature, which is available starting with .net core 2.0.0.

          Download and install the latest runtime and hosting bundle. As of this writing, the latest stable .net core runtime is 2.2. You can find it here.

          Caution: You need to enable IIS first before installing the runtime and hosting bundle. If you install the bundle without enabling IIS, then you need to run the installation again and choose “Repair”, after enabling IIS.

          Restart the server after the installation.

          Application Pools

          An application pool essentially allows you to control the resources for a web application. For example, you can have multiple applications share the same resources by assigning them to the same pool, or you can allocate dedicated resources for an application by assigning the application to an application pool, separating from the other pools.

          An application pool also acts as a sandbox to effectively isolate applications within the pool from applications within another pool. If an application runs under an application pool crashes or causes trouble, it does not affect applications running in another pool. You can have multiple applications share a same pool, and you can also have multiple pools for different applications. Each application pool represents a worker process. As such, the more application pools you have, the more memory you need.

          When you stop an application pool, you essentially stop the application(s) associated with the pool.

          IIS site

          A site is a container for web applications. Each site has a default root application, and you can create more applications under the site. All applications under a same site share the same root URL (binding).

          Although applications under a same site share the same bindings, each application can have its own application pool. As such, you can still achieve application isolation when hosting multiple applications under a same site. Ofcourse, you can also host multiple applications under multiple sites.

          You may want to host multiple applications under a same site to reuse DNS, or if the applications are closely related. For example, suppose you have two related applications; perhaps two different API versions of a same app. You can host both applications under the same site. They both share the same root URL, but different ending path (e.g myapi.com/v1 and myapi.com/v2).

          Binding

          A site binding basically suggests to IIS that a site can handle a request if the request’s header matches one or more parts of the binding. The primary parts of a binding are type, IP address, port and hostname. When an incoming request hits the server, based on the sites’ bindings, IIS can determine which site is the best match to handle the request.

          A binding consists primarily of the following:

          Type: Either http or https. In the case of https, you can associate a SSL certificate with the binding.

          Host name: A server can have one or more host names assigned to it. The default value is blank, or localhost. The hostname in the request address must match the hostname in the binding for the site to process the request.

          Port: The TCP port number. This is a required configuration. Specify the port number on which you want to bind the site. The port number specified in the request address must match the port number in the binding for the site to process the request.

          IP Address: A server can have more than 1 IP address assigned to it. When configuring a binding for a site, you can select a specific IP assigned to a server. You can also select the value “All Unassigned”, meaning all the ip addresses that have not been assigned to other IIS sites. If the request address has the form of an IP address, the request’s IP address must match the IP address of the binding for the site to process the request.

          SSL certificate

          An SSL certificate is for establishing a secured communication between a server and a client to prevent a Man-in-the-middle attack.

          Below I give a recap of how SSL works. For more details, checkout the article.

          To obtain an SSL certificate:

          1. Create a Certificate Signing Request.
          2. Send the Certificate Signing Request to a Certificate Authority (CA). The request contains the public key.
          3. The CA creates the certificate based on the public key. It does not know about the private key.
          4. Install the certificate on your server.

          Communication between browser and server using SSL:

          1. Browser creates a session key and encrypts it with the server’s public key.
          2. Browser sends the encrypted key to the server.
          3. Server decrypts the session key using its private key.
          4. Browser and server now encrypt and decrypt data using the session key which only the browser and server know.

          For testing purpose, you can also use a self signed certificate. See this post.

          Deploying sample ASP.NET core application

          For demonstration purpose, I have built and published a simple ASP.NET core application. The app targets .NET core 2.2.

          On the remote server, I have the published folder under “C:inetpubMyAspNetCoreApp”.

          I. Create IIS application pool

          To create an application pool,

          1. In IIS, click on the server name.
          2. Select and right click on “Application Pools”.
          3. Click “Add Application Pool .” to open the Add Application Pool dialog.
          4. Under Name, enter “MyAspNetCoreAppPool”.
          5. Under .NET CLR version, select “No Managed Code”.
          6. Under Managed pipeline mode, leave the default as “Integrated”.
          7. Check the box “Start application pool immediately”.

          .NET CLR version:

          The .NET CLR version refers to the version of the Common Language Runtime which the .NET framework includes. For this example, since we deploying an ASP.NET core application that targets .NET core, not .NET, so we choose “No Managed Code”.

          Displays the version of the .NET Framework that an application pool uses. If the application pool was configured to not use the .NET Framework, the value is No Managed Code.

          Managed pipeline mode: Integrated vs Classic

          This stackoverflow post talks about the differences between integrated vs classic mode. The main points come from the documentation. Below is just my summary.

          Integrated mode is the newer mode available since IIS 7.0. Integrated mode unifies the processing models of IIS and ASP.NET. In integrated mode, an order list of events process a request and then generate a response.

          Classic mode separates the processing models of IIS and ASP.NET. In classic mode, a request goes through native processing in IIS. Then, it goes through Aspnet_isapi.dll for processing of managed code.

          Some of the processing steps, such as authentication and authorization are the same in IIS and ASP.NET processing models. As such, it is less performant than integrated mode because of the duplicate processings a request has to go through. If you are deploying a new application, definitely choose integrated mode.

          II. Create IIS site.

          1. In IIS, under “Sites”, right click and select “Add Website” to open the Add Website dialog.
          2. Under Site name, enter “MyAspNetCoreApp”.
          3. Click “Select” to open the “Select Application Pool” dialog and select the “MyAspNetCoreApp” pool created earlier.
          4. Under physical path, click “Browse” and select the path to the published app. For this example, I have placed the published app at “C:inetpubMyAspNetCoreApp”
          5. Enter the information for the binding. For more details, see the above section. For this example, just use the defaults.
            • Select “http” for Type.
            • Select “All Unassigned” for IP address.
            • Select 8080 for port
            • For Host name, leave blank to use the default localhost.
            • Click “OK” to create the site.
            • Run the application.
            1. Under Sites, select your site “MyAspNetCoreApp”. On the right panel, under Manage WEbsite, click “Start” if your site has not started already.
            2. On the server, open the browser, and enter “http://localhost:8080”

            You should see the site loads. If so, congratulations.

            Next steps: Once you are able to load the site locally, you can configure the binding to allow the world to reach your site.

            • Add a new binding in which you use the DNS that maps to your server.
            • Use https.

            In the next post, I’ll share how to automate the build and deployment process using azure pipelines.

            IV. Troubleshooting

            If you get HTTP 500.19 – Internal Server Error. It can be the server does not have the correct .Net core runtime installed. See this cd .

            One way to troubleshoot is running the application directly using the dotnet command.

            Open the command line, CD to the directory containing the application files: C:inetpubMyAspNetCoreApp. Then type the command

            You should be able to browse to the application on port 5000.

            V. Where to go from here?

            Read my next post in this series to learn how to automate the build and deployment process so you can save time, reduce human errors and focus more on building your application.