[转]Publishing and Running ASP.NET Core Applications with IIS

时间:2022-10-21 13:40:42

本文转自:https://weblog.west-wind.com/posts/2016/Jun/06/Publishing-and-Running-ASPNET-Core-Applications-with-IIS#DoyouneedIIS?

When you build ASP.NET Core applications and you plan on running your applications on IIS you'll find that the way that Core applications work in IIS is radically different than in previous versions of ASP.NET.

In this post I'll explain how ASP.NET Core runs in the context of IIS and how you can deploy your ASP.NET Core application to IIS.

IIS and ASP.NET Core

The most important thing to understand about hosting ASP.NET Core is that it runs as a standalone, out of process Console application. It's not hosted inside of IIS and it doesn't need IIS to run. ASP.NET Core applications have their own self-hosted Web server and process requests internally using this self-hosted server instance.

You can however run IIS as a front end proxy for ASP.NET Core applications, because Kestrel is a raw Web server that doesn't support all features a full server like IIS supports. This is actually a recommended practice on Windows in order to provide port 80/443 forwarding which kestrel doesn't support directly. For Windows IIS (or another reverse proxy) will continue to be an important part of the server even with ASP.NET Core applications.

Let's take a look and see how IIS fits into ASP.NET Core applications.

Classic ASP.NET Hosting

Before we take a look at ASP.NET Core hosting lets review how classic ASP.NET runs ASP.NET applications:

[转]Publishing and Running ASP.NET Core Applications with IIS

In a classic ASP.NET application everything is hosted inside of an IIS Worker Process (w3wp.exe) which is the IIS Application Pool. The AppPool hosts your ASP.NET application and your application is instantiated by the built-in ASP.NET hosting features in IIS. The native runtime manager instantiates the .NET Runtime on your application's behalf and brings up the HttpRuntime object which is then used to fire requests through the ASP.NET application pipeline as requests come in from the native http.sys driver. Requests come in from http.sys and are dispatched to the appropriate site that is mapped to the Application Pool and the HttpRuntime instance hosted there.

ASP.NET Core with IIS

Things are quite different with ASP.NET Core which doesn't run in-process to the IIS worker process, but rather runs as a separate, out of process Console application that runs its own Web server using the Kestrel component. Kestrel is a .NET Web Server implementation that has been heavily optimized for throughput performance. It's fast and functional in getting network requests into your application, but it's 'just' a raw Web server. It does not include Web management services as a full featured server like IIS does.

If you run on Windows you will likely want to run Kestrel behind IIS to gain infrastructure features like port 80/443 forwarding via Host Headers, process lifetime management and certificate management to name a few.

Here's what it looks like when you run your ASP.NET Core application behind an IIS Web front:

[转]Publishing and Running ASP.NET Core Applications with IIS

ASP.NET Core applications are standalone Console applications invoked through the dotnet runtime command. They are not loaded into an IIS worker process, but rather loaded through a native IIS module called AspNetCoreModule that executes the external Console application.

The AspNetCoreModule has to be installed on your server and is part of the ASP.NET Core Server Hosting Bundle.

Once you've installed the hosting bundle (or you install the .NET Core SDK on your Dev machine) the AspNetCoreModule is available in the IIS native module list:

[转]Publishing and Running ASP.NET Core Applications with IIS

The AspNetCoreModule is a native IIS module that hooks into the IIS pipeline very early in the request cycle and immediately redirects all traffic to the backend ASP.NET Core application. All requests - even those mapped to top level Handlers like ASPX bypass the IIS pipeline and are forwarded to the ASP.NET Core process. This means you can't easily mix ASP.NET Core and other frameworks in the same Site/Virtual directory, which feels a bit like a step back given that you could easily mix frameworks before in IIS.

While the IIS Site/Virtual still needs an IIS Application Pool to run in, the Application Pool should be set to use No Managed Code. Since the App Pool acts merely as a proxy to forward requests, there's no need to have it instantiate a .NET runtime.

[转]Publishing and Running ASP.NET Core Applications with IIS

The AspNetCoreModule's job is to ensure that your application gets loaded when the first request comes in and that the process stays loaded if for some reason the application crashes. You essentially get the same behavior as classic ASP.NET applications that are managed by WAS (Windows Activation Service).

Once running, incoming Http requests are handled by this module and then routed to your ASP.NET Core application.

So, requests come in from the Web and int the kernel mode http.sys driver which routes into IIS on the primary port (80) or SSL port (443). The request is then forwarded to your ASP.NET Core application on the HTTP port configured for your application which is not port 80/443. In essence, IIS acts a reverse proxy simply forwarding requests to your ASP.NET Core Web running the Kestrel Web server on a different port.

Kestrel picks up the request and pushes it into the ASP.NET Core middleware pipeline which then handles your request and passes it on to your application logic. The resulting HTTP output is then passed back to IIS which then pushes it back out over the Internet to the HTTP client that initiated the request - a browser, mobile client or application.

The AspNetCoreModule is configured via the web.config file found in the application's root, which points a the startup command (dotnet) and argument (your application's main dll) which are used to launch the .NET Core application. The configuration in the web.config file points the module at your application's root folder and the startup DLL that needs to be launched.

Here's what the web.config looks like:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*"
modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet"
arguments=".\AlbumViewerNetCore.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
forwardWindowsAuthToken="false" />
</system.webServer>
</configuration>

You can see that module references dotnetexe and the compiled entry point DLL that holds your Main method in your .NET Core application.

Do you need IIS?

We've already discussed that when running ASP.NET Core on Windows, it's recommended you use IIS as a front end proxy. While it's possible to directly access Kestrel via an IP Address and available port, there are number of reasons why you don't want to expose your application directly this way in production environments.

First and foremost, if you want to have multiple applications running on a single server that all share port 80 and port 443 you can't run Kestrel directly. Kestrel doesn't support host header routing which is required to allow multiple port 80 bindings on a single IP address. Without IIS (or http.sys actually) you currently can't do this using Kestrel alone (and I think this is not planned either).

The AspNetCoreModule running through IIS also provides the necessary process management to ensure that your application gets loaded on the first access, ensures that it stays up and running and is restarted if it crashes. The AspNetCoreModule provides the required process management to ensure that your AspNetCore application is always available even after a crash.

It's also a good idea to run secure SSL requests through IIS proper by setting up certificates through the IIS certificate store and letting IIS handle the SSL authentication. The backplane HTTP request from IIS can then simply fire a non-secure HTTP request to your application. This means only a the front end IIS server needs a certificate even if you have multiple servers on the backplane serving the actual HTTP content.

IIS can also provide static file serving, gzip compression of static content, static file caching, Url Rewriting and a host of other features that IIS provides natively. IIS is really good and efficient at processing non-application requests, so it's worthwhile to take advantage of that. You can let IIS handle the tasks that it's really good at, and leave the dynamic tasks to pass through to your ASP.NET Core application.

The bottom line for all of this is if you are hosting on Windows you'll want to use IIS and the AspNetCoreModule.

Running IIS as a Development Server - no

So I've seen this question comes up occasionally:

Can I run full IIS to run and debug my ASP.NET Core Applications like I could with classic applications?

To sidestep this question a little: There should be very few reasons for you to run IIS during development. Yes, in the past there were very good reasons to run full IIS because there were always a number of things that behaved very differently in full IIS compared to IIS Express.

However, with ASP.NET Core there's little to no reason to be running full IIS during development. Why? Because ASP.NET Core applications aren't actually running inside of IIS. Whether you running called from IIS, IIS Express or whether you do dotnet run directly from the command line - you are running the exact same code and in most cases the exact same execution environment. Running inside of IIS really doesn't buy you anything anymore that you can't easily simulate with a command line environment.

The only reason you might need to run under IIS if there is something that IIS provides in terms of HTTP services that is really separate from the ASP.NET Core processing. But even then it's likely that those features won't be something you need to debug in the context of your application.

'Running' IIS

The reason that you can't 'just run IIS' from your development environment is that an ASP.NET Core application has to be published before it can be executed. The development folder doesn't hold all the files necessary to run your application. When you 'debug' or 'run' your application the application is first published to a separate location and run from there. For this reason you don't see IIS as an option in Visual Studio for example.

If you absolutely have to run with IIS, you can publish the application to a local folder first, then configure an IIS virtual directory or site and use that to run your site.

Publishing ASP.NET Core Applications for IIS

In order to run an application with IIS you have to first publish it. There are two ways to that you can do this today:

  • Use dotnet publish
  • Use the Visual Studio Publishing Features

Using dotnet publish

Using dotnet publish builds your application and copies a runnable, self-contained version of the project to a new location on disk. You specify an output folder where all the files are published. This is not so different from classic ASP.NET which ran Web sites out of temp folders. With ASP.NET Core you explicitly publish an application into a location of your choice - the files are no longer hidden away and magically copied around.

A typical publish command may look like this:

dotnet publish
--framework netcoreapp1.0
--output "c:\temp\AlbumViewerWeb"
--configuration Release

This publishes the application to the c:\temp\albumviewerWeb.

If you open this folder you'll find that it contains your original application structure plus all the nuget dependency assemblies dumped into the root folder:

[转]Publishing and Running ASP.NET Core Applications with IIS

Manual IIS Hosting of a Publish Folder

Once you've published your application and you've moved it to your server (via FTP or other mechanism) we can then hook up IIS to the folder.

I'm going to create a virtual Application directory:

[转]Publishing and Running ASP.NET Core Applications with IIS

Note that I created an AspNetCore Application Pool that has its .NET Runtime set to No Managed Code as shown earlier.

IIS Identity and Permissions

You might also have to tweak the IIS App Pool Identity to something other than the default ApplicationPoolIdentity in order to ensure that your application has access to resources it needs to run. I generally start with NETWORKSERVICE and then move to a custom account that matches the actual rights required by the application.

And that's really all that needs to happen. You should be able to now navigate to your site or Virtual and the application just runs.

You can now take this locally deployed Web site, copy it to a Web Server (via FTP or direct file copy or other publishing solution), set up a Site or Virtual and you are off to the races.

Publishing from Visual Studio

The dotnet publish step works to copy the entire project to a folder, but it doesn't actually publish your project to a Web site (currently - this is likely coming at a later point).

In order to get incremental publishing to work, which is really quite crucial for ASP.NET Core applications because there are so many dependencies, you need to use MsDeploy which is available as part of Visual Studio's Web Publishing features.

Currently the Visual Studio Tooling UI is very incomplete, but the underlying functionality is supported. I'll point out a few tweaks that you can use to get this to work today.

When you go into Visual Studio in the RC2 Web tooling and the Publish dialog, you'll find that you can't create a publish profile that points at IIS. There are options for file and Azure publishing but there's no way through the UI to create a new Web site publish.

However, you can cheat by creating your own .pubxml file and putting it into the \Properties\PublishProfiles folder in your project.

Version Specific Workaround

Note it's almost certain this will get fixed post RC2 with a tooling update, so before you go through these steps if you read this article a month from now, check whether you can create an IIS publish profile directly through the Visual Studio UI.

To create a 'manual profile' in your ASP.NET Core Web project:

  • Create a folder \Properties\PublishProfiles
  • Create a file <MyProfile>.pubxml

You can copy an existing .pubxml from a non-ASP.NET Core project or create one. Here's an example of a profile that works with IIS:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://samples.west-wind.com/AlbumViewerCore/index.html</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<PublishFramework>netcoreapp1.0</PublishFramework>
<UsePowerShell>True</UsePowerShell>
<EnableMSDeployAppOffline>True</EnableMSDeployAppOffline>
<MSDeployServiceURL>https://publish.west-wind.com</MSDeployServiceURL>
<DeployIisAppPath>samples site/albumviewercore</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>RemoteAgent</MSDeployPublishMethod>
<EnableMSDeployBackup>False</EnableMSDeployBackup>
<UserName>username</UserName>
<_SavePWD>True</_SavePWD>
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<AuthType>NTLM</AuthType>
</PropertyGroup>
</Project>

AuthType NTLM Fix

Note the <AuthType>NTLM</AuthType> key at the bottom of the file. This key is very important or else the publish operation doesn't work. If you're copying from an existing file make sure you add this key as it's unlikely to have it by default.

Once you've created a .pubxml file you can now open the publish dialog in Visual Studio with this Profile selected:

[转]Publishing and Running ASP.NET Core Applications with IIS

At this point you should be able to publish your site to IIS on a remote server and use incremental updates with your content.

#And it's a Wrap Currently IIS hosting and publishing is not particularly well documented and there are some rough edges around the publishing process. Microsoft knows of these issues and this will get fixed by RTM of ASP.NET Core.

In the meantime I hope this post has provided the information you need to understand how IIS hosting works and a few tweaks that let you use the publishing tools available to get your IIS applications running on your Windows Server.

Rock on...

[转]Publishing and Running ASP.NET Core Applications with IIS的更多相关文章

  1. Running ASP&period;NET Core applications on Windows Subsystem for Linux

    Setting up Linux on Windows 10 First thing is to enable Windows Subsystem for Linux. It doesn’t inst ...

  2. ASP&period;NET Core部署在IIS上

    1.下载安装 Windows Server Hosting ,它的作用是,让IIS有反向代理功能(Asp.Net Core Module负责反向代理工作),将请求转发到 Kestrel 2.发布网站, ...

  3. asp&period;net core 发布到iis session无法传递的问题

    网站是用asp.net core 的Razor Pages开发的,其中用户登录用到了session,调试运行没有问题,但是发布到iis之后出现session无法记录的问题. 我用log记录查看了一下, ...

  4. ASP&period;NET CORE 之 在IIS上部署MVC项目

    与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角色转发请求到Kestrel ...

  5. Asp&period;net core 学习笔记 &lpar; IIS&comma; static file 性能优化 &rpar;

    更新 : 2019-02-06 最后还是把 rewrite 给替换掉了. 所以 rewrite url 也不依赖 iis 了咯. refer : https://docs.microsoft.com/ ...

  6. asp&period;net core部署到iis

    asp.net core项目部署到IIS稍微不同于之前,记录几个要点: 一.下载安装.NET Core 托管捆绑包,下载地址,这个链接或许不是最新的了,官方文档里面有这个链接,到下图所示位置即可找到. ...

  7. RoadFlow ASP&period;NET Core工作流引擎IIS部署

    RoadFlow最新版本采用ASP.NET CORE2.1开发,部署步骤和.NET CORE部署一样,具体可参数ASP.NET CORE的部署方式. 1. 获取代码 首先从RoadFlow官网下载最新 ...

  8. 【Windows】ASP&period;NET Core 部署到 IIS

    如果你的系统环境没有 .NET CORE SDK,请到官网进行下载: https://www.microsoft.com/net/download/windows 接下来我们开始进行环境的部署,首先在 ...

  9. 解决ASP&period;NET Core部署到IIS,更新项目&quot&semi;另一个程序正在使用此文件,进程无法访问&quot&semi;

    问题:部署到IIS上的ASP.NET Core项目,在更新的时候会进程占用的错误 初步解决方案: 1,关闭应用程序池 2,关闭网站 3,更新项目 缺点:网站没法访问,部署项目停的时间过长 查询官方文档 ...

随机推荐

  1. Web报表工具FineReport中JavaScript的使用

    报表软件FineReport采用的是jQuery v1.9.2框架,jQuery是一个快速的,简洁的JavaScript库,能让用户更方便地处理HTML documents.events,实现动画效果 ...

  2. Android Activity返回键控制的两种方式

    Android Activity返回键监听的两种方式 1.覆写Activity的OnBackPressed方法 官方解释: Called when the activity has detected ...

  3. Java IO流题库

    一.    填空题 Java IO流可以分为   节点流   和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...

  4. javascript坐标:event&period;x、event&period;clientX、event&period;offsetX、event&period;screenX 用法

    clientX 设置或获取鼠标指针位置相对于窗口客户区域的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条. clientY 设置或获取鼠标指针位置相对于窗口客户区域的 y 坐标,其中客户区域不包 ...

  5. new 的用法

     在C#中,new关键字有三种用法: 1.new 运算符,用于创建对象和调用构造函数. 2.new  修饰符,在用作修饰符时,new关键字可以显式隐藏从基类继承的成员. 3.new 约束 ,用于在泛型 ...

  6. Binary Numbers(HDU1390)

    Binary Numbers 点我 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. on、where、having的区别&lpar;转载&rpar;

    on.where.having的区别 on.where.having这三个都可以加条件的子句中,on是最先执行,where次之,having最后.有时候如果这先后顺序不影响中间结果的话,那最终结果是相 ...

  8. 常用的html标签大全

    html标签大全 一.文字 1.标题文字 <h#>..........</h#> #=1~6:h1为最大字,h6为最小字 2.字体变化 <font>........ ...

  9. Maps JavaScript API的JavaScript代码

    要请求多个库,请用逗号分隔它们   <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY& ...

  10. python调用openstack的api,create&lowbar;instance的程序解析

    python调用openstack的api,create_instance的程序解析 2017年10月17日 15:27:24 CloudXli 阅读数:848   版权声明:本文为博主原创文章,未经 ...