{"id":625,"date":"2025-04-05T11:43:02","date_gmt":"2025-04-05T03:43:02","guid":{"rendered":"https:\/\/www.hyy.net\/?p=625"},"modified":"2025-04-05T11:43:02","modified_gmt":"2025-04-05T03:43:02","slug":"asp-net-core-in-action-27-publishing-and-deploying-your-application","status":"publish","type":"post","link":"https:\/\/diji.net\/?p=625","title":{"rendered":"ASP.NET Core in Action 27 Publishing and deploying your application"},"content":{"rendered":"<p>27 Publishing and deploying your application<br \/>\n27 \u53d1\u5e03\u548c\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>This chapter covers<br \/>\n\u672c\u7ae0\u6db5\u76d6<\/p>\n<p>\u2022  Publishing an ASP.NET Core application<br \/>\n\u53d1\u5e03 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>\u2022  Hosting an ASP.NET Core application in IIS<br \/>\n\u5728 IIS\u4e2d\u6258\u7ba1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>\u2022  Customizing the URLs for an ASP.NET Core app<br \/>\n\u81ea\u5b9a\u4e49 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684 URL<\/p>\n<p>We\u2019ve covered a vast amount of ground so far in this book. We\u2019ve gone over the basic mechanics of building an ASP.NET Core application, such as configuring dependency injection (DI), loading app settings, and building a middleware pipeline. We\u2019ve looked at building APIs using minimal APIs and web API controllers. We\u2019ve looked at the server-rendered UI side, using Razor templates and layouts to build an HTML response. And we\u2019ve looked at higher-level abstractions, such as Entity Framework Core (EF Core) and ASP.NET Core Identity, that let you interact with a database and add users to your application. In this chapter we\u2019re taking a slightly different route. Instead of looking at ways to build bigger and better applications, we\u2019ll focus on what it means to deploy your application so that users can access it.<br \/>\n\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u6211\u4eec\u5728\u8fd9\u672c\u4e66\u4e2d\u5df2\u7ecf\u6db5\u76d6\u4e86\u5927\u91cf\u7684\u5185\u5bb9\u3002\u6211\u4eec\u5df2\u7ecf\u4ecb\u7ecd\u4e86\u6784\u5efa ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u57fa\u672c\u673a\u5236\uff0c\u4f8b\u5982\u914d\u7f6e\u4f9d\u8d56\u9879\u6ce8\u5165 \uff08DI\uff09\u3001\u52a0\u8f7d\u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e\u548c\u6784\u5efa\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002\u6211\u4eec\u5df2\u7ecf\u7814\u7a76\u4e86\u4f7f\u7528\u6700\u5c11\u7684 API \u548c Web API \u63a7\u5236\u5668\u6765\u6784\u5efa API\u3002\u6211\u4eec\u5df2\u7ecf\u4e86\u89e3\u4e86\u670d\u52a1\u5668\u5448\u73b0\u7684 UI \u7aef\uff0c\u4f7f\u7528 Razor \u6a21\u677f\u548c\u5e03\u5c40\u6765\u6784\u5efa HTML \u54cd\u5e94\u3002\u6211\u4eec\u8fd8\u7814\u7a76\u4e86\u66f4\u9ad8\u7ea7\u522b\u7684\u62bd\u8c61\uff0c\u4f8b\u5982 Entity Framework Core \uff08EF Core\uff09 \u548c ASP.NET Core Identity\uff0c\u5b83\u4eec\u5141\u8bb8\u60a8\u4e0e\u6570\u636e\u5e93\u4ea4\u4e92\u5e76\u5c06\u7528\u6237\u6dfb\u52a0\u5230\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u91c7\u53d6\u4e86\u7565\u6709\u4e0d\u540c\u7684\u8def\u7ebf\u3002\u6211\u4eec\u4e0d\u4f1a\u7814\u7a76\u6784\u5efa\u66f4\u5927\u3001\u66f4\u597d\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u65b9\u6cd5\uff0c\u800c\u662f\u91cd\u70b9\u4ecb\u7ecd\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u4ee5\u4fbf\u7528\u6237\u53ef\u4ee5\u8bbf\u95ee\u5b83\u610f\u5473\u7740\u4ec0\u4e48\u3002<\/p>\n<p>We\u2019ll start by looking again at the ASP.NET Core hosting model in section 27.1 and examining why you might want to host your application behind a reverse proxy instead of exposing your app directly to the internet. I show you the difference between running an ASP.NET Core app in development using dotnet run and publishing the app for use on a remote server. Finally, I describe some of the options available when you\u2019re deciding how and where to deploy your app.<br \/>\n\u9996\u5148\uff0c\u6211\u4eec\u5c06\u518d\u6b21\u67e5\u770b\u7b2c 27.1 \u8282\u4e2d\u7684 ASP.NET Core \u6258\u7ba1\u6a21\u578b\uff0c\u5e76\u7814\u7a76\u4e3a\u4ec0\u4e48\u60a8\u53ef\u80fd\u5e0c\u671b\u5c06\u5e94\u7528\u7a0b\u5e8f\u6258\u7ba1\u5728\u53cd\u5411\u4ee3\u7406\u540e\u9762\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5411 Internet \u516c\u5f00\u5e94\u7528\u7a0b\u5e8f\u3002\u6211\u5c06\u5411\u60a8\u5c55\u793a\u4f7f\u7528 dotnet run \u5728\u5f00\u53d1\u4e2d\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e0e\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5728\u8fdc\u7a0b\u670d\u52a1\u5668\u4e0a\u4f7f\u7528\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6700\u540e\uff0c\u6211\u5c06\u4ecb\u7ecd\u5728\u51b3\u5b9a\u5982\u4f55\u4ee5\u53ca\u5728\u4f55\u5904\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u65f6\u53ef\u7528\u7684\u4e00\u4e9b\u9009\u9879\u3002<\/p>\n<p>In section 27.2 I show you how to deploy your app to one such option: a Windows server running Internet Information Services (IIS). This is a typical deployment scenario for many developers who are familiar with the legacy .NET Framework version of ASP.NET, so it acts as a useful case study, but it\u2019s certainly not the only possibility. I don\u2019t go into all the technical details of configuring the venerable IIS system; instead, I show you the bare minimum required to get it up and running. If your focus is cross-platform development, don\u2019t worry, because I don\u2019t dwell on IIS for too long.<br \/>\n\u5728\u7b2c 27.2 \u8282\u4e2d\uff0c\u6211\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u5c06\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u8fd9\u6837\u4e00\u4e2a\u9009\u9879\uff1a\u8fd0\u884c Internet Information Services \uff08IIS\uff09 \u7684 Windows \u670d\u52a1\u5668\u3002\u5bf9\u4e8e\u8bb8\u591a\u719f\u6089\u65e7\u7248 ASP.NET \u7684 .NET Framework \u7248\u672c\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u8fd9\u662f\u4e00\u4e2a\u5178\u578b\u7684\u90e8\u7f72\u65b9\u6848\uff0c\u56e0\u6b64\u5b83\u662f\u4e00\u4e2a\u6709\u7528\u7684\u6848\u4f8b\u7814\u7a76\uff0c\u4f46\u80af\u5b9a\u4e0d\u662f\u552f\u4e00\u7684\u53ef\u80fd\u6027\u3002\u6211\u4e0d\u4f1a\u6df1\u5165\u4ecb\u7ecd\u914d\u7f6e\u53e4\u8001\u7684 IIS \u7cfb\u7edf\u7684\u6240\u6709\u6280\u672f\u7ec6\u8282;\u76f8\u53cd\uff0c\u6211\u5411\u60a8\u5c55\u793a\u4e86\u542f\u52a8\u548c\u8fd0\u884c\u5b83\u6240\u9700\u7684\u6700\u4f4e\u9650\u5ea6\u3002\u5982\u679c\u60a8\u7684\u91cd\u70b9\u662f\u8de8\u5e73\u53f0\u5f00\u53d1\uff0c\u8bf7\u4e0d\u8981\u62c5\u5fc3\uff0c\u56e0\u4e3a\u6211\u4e0d\u4f1a\u5728 IIS \u4e0a\u505c\u7559\u592a\u4e45\u3002<\/p>\n<p>In section 27.3 I provide an introduction to hosting on Linux. You\u2019ll see how it differs from hosting applications on Windows, learn the changes you need to make to your apps, and find out about some gotchas to look out for. I describe how reverse proxies on Linux differ from IIS and point you to some resources you can use to configure your environments rather than give exhaustive instructions in this book.<br \/>\n\u5728 Section 27.3 \u4e2d\uff0c\u6211\u4ecb\u7ecd\u4e86\u5728 Linux \u4e0a\u6258\u7ba1\u3002\u60a8\u5c06\u4e86\u89e3\u5b83\u4e0e\u5728 Windows \u4e0a\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\u6709\u4f55\u4e0d\u540c\uff0c\u4e86\u89e3\u60a8\u9700\u8981\u5bf9\u5e94\u7528\u7a0b\u5e8f\u8fdb\u884c\u7684\u66f4\u6539\uff0c\u5e76\u4e86\u89e3\u4e00\u4e9b\u9700\u8981\u6ce8\u610f\u7684\u95ee\u9898\u3002\u6211\u5c06\u4ecb\u7ecd Linux \u4e0a\u7684\u53cd\u5411\u4ee3\u7406\u4e0e IIS \u7684\u4e0d\u540c\u4e4b\u5904\uff0c\u5e76\u5411\u60a8\u6307\u51fa\u4e00\u4e9b\u53ef\u7528\u4e8e\u914d\u7f6e\u73af\u5883\u7684\u8d44\u6e90\uff0c\u800c\u4e0d\u662f\u5728\u672c\u4e66\u4e2d\u63d0\u4f9b\u8be6\u5c3d\u7684\u8bf4\u660e\u3002<\/p>\n<p>If you\u2019re not hosting your application using IIS, you\u2019ll likely need to set the URL that your ASP.NET Core app is using when you deploy your application. In section 27.4 I show two approaches: using the special ASPNETCORE_URLS environment variable and using command-line arguments. Although this task generally is not a problem during development, setting the correct URLs for your app is critical when you need to deploy it.<br \/>\n\u5982\u679c\u4e0d\u4f7f\u7528 IIS \u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\uff0c\u5219\u53ef\u80fd\u9700\u8981\u8bbe\u7f6e ASP.NET Core \u5e94\u7528\u5728\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u65f6\u4f7f\u7528\u7684 URL\u3002\u5728 Section 27.4 \u4e2d\uff0c\u6211\u5c55\u793a\u4e86\u4e24\u79cd\u65b9\u6cd5\uff1a\u4f7f\u7528\u7279\u6b8a\u7684 ASPNETCORE_URLS \u73af\u5883\u53d8\u91cf\u548c\u4f7f\u7528\u547d\u4ee4\u884c\u53c2\u6570\u3002\u5c3d\u7ba1\u6b64\u4efb\u52a1\u5728\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u901a\u5e38\u4e0d\u662f\u95ee\u9898\uff0c\u4f46\u5f53\u60a8\u9700\u8981\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e\u6b63\u786e\u7684 URL \u81f3\u5173\u91cd\u8981\u3002<\/p>\n<p>This chapter covers a relatively wide array of topics, all related to deploying your app. But before we get into the nitty-gritty, I\u2019ll go over the hosting model for ASP.NET Core so that we\u2019re on the same page. This is significantly different from the hosting model of the legacy version of ASP.NET, so if you\u2019re coming from that background, it\u2019s best to try to forget what you know!<br \/>\n\u672c\u7ae0\u6db5\u76d6\u4e86\u76f8\u5bf9\u5e7f\u6cdb\u7684\u4e3b\u9898\uff0c\u6240\u6709\u4e3b\u9898\u90fd\u4e0e\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u6709\u5173\u3002\u4f46\u5728\u6211\u4eec\u8fdb\u5165\u7ec6\u8282\u4e4b\u524d\uff0c\u6211\u5c06\u4ecb\u7ecd ASP.NET Core \u7684\u6258\u7ba1\u6a21\u578b\uff0c\u4ee5\u4fbf\u6211\u4eec\u8fbe\u6210\u5171\u8bc6\u3002\u8fd9\u4e0e\u65e7\u7248 ASP.NET \u7684\u6258\u7ba1\u6a21\u5f0f\u6709\u5f88\u5927\u4e0d\u540c\uff0c\u56e0\u6b64\u5982\u679c\u60a8\u6765\u81ea\u8be5\u80cc\u666f\uff0c\u6700\u597d\u5c1d\u8bd5\u5fd8\u8bb0\u60a8\u6240\u77e5\u9053\u7684\uff01<\/p>\n<h2>27.1 Understanding the ASP.NET Core hosting model<\/h2>\n<p>27.1 \u4e86\u89e3 ASP.NET Core \u6258\u7ba1\u6a21\u578b<\/p>\n<p>If you think back to part 1 of this book, you may remember that we discussed the hosting model of ASP.NET Core. ASP.NET Core applications are, essentially, console applications. They have a static void Main function that is the entry point for the application, as a standard .NET console app would.<br \/>\n\u5982\u679c\u60a8\u56de\u60f3\u4e00\u4e0b\u672c\u4e66\u7684\u7b2c 1 \u90e8\u5206\uff0c\u60a8\u53ef\u80fd\u8fd8\u8bb0\u5f97\u6211\u4eec\u8ba8\u8bba\u4e86 ASP.NET Core \u7684\u6258\u7ba1\u6a21\u578b\u3002ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u672c\u8d28\u4e0a\u662f\u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u3002\u5b83\u4eec\u5177\u6709\u4e00\u4e2a\u9759\u6001 void Main \u51fd\u6570\uff0c\u8be5\u51fd\u6570\u662f\u5e94\u7528\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\uff0c\u5c31\u50cf\u6807\u51c6 .NET \u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u4e00\u6837\u3002<\/p>\n<p><b>NOTE<\/b> The entry point for programs using top-level statements is automatically generated by the compiler. It\u2019s not called Main (it typically has an \u201cinvalid\u201d name, such as <code> &lt;Main&gt;$ <\/code>), but otherwise it has the same signature as the classic static void Main function you would write by hand.<br \/>\n\u6ce8\u610f\u4f7f\u7528 top-level \u8bed\u53e5\u7684\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u7531\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u3002\u5b83\u4e0d\u79f0\u4e3a Main \uff08\u5b83\u901a\u5e38\u5177\u6709\u201c\u65e0\u6548\u201d\u540d\u79f0\uff0c\u4f8b\u5982<code> &lt;Main&gt;$ <\/code>\uff09\uff0c\u4f46\u9664\u6b64\u4e4b\u5916\uff0c\u5b83\u4e0e\u4f60\u624b\u52a8\u7f16\u5199\u7684\u7ecf\u5178\u9759\u6001 void Main \u51fd\u6570\u5177\u6709\u76f8\u540c\u7684\u7b7e\u540d\u3002<\/p>\n<p>What makes a .NET app an ASP.NET Core app is that it runs a web server, typically Kestrel, inside the console app process. Kestrel provides the HTTP functionality to receive requests and return responses to clients. Kestrel passes any requests it receives to the body of your application and generates a response, as shown in figure 27.1. This hosting model decouples the server and reverse proxy from the application itself so that the same application can run unchanged in multiple environments.<br \/>\n\u4f7f .NET \u5e94\u7528\u7a0b\u5e8f\u6210\u4e3a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u539f\u56e0\u662f\u5b83\u5728\u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u8fdb\u7a0b\u4e2d\u8fd0\u884c Web \u670d\u52a1\u5668\uff0c\u901a\u5e38\u662f Kestrel\u3002Kestrel \u63d0\u4f9b HTTP \u529f\u80fd\u6765\u63a5\u6536\u8bf7\u6c42\u5e76\u5c06\u54cd\u5e94\u8fd4\u56de\u7ed9\u5ba2\u6237\u7aef\u3002Kestrel \u5c06\u5176\u6536\u5230\u7684\u4efb\u4f55\u8bf7\u6c42\u4f20\u9012\u5230\u5e94\u7528\u7a0b\u5e8f\u7684\u4e3b\u4f53\u5e76\u751f\u6210\u54cd\u5e94\uff0c\u5982\u56fe 27.1 \u6240\u793a\u3002\u6b64\u6258\u7ba1\u6a21\u578b\u5c06\u670d\u52a1\u5668\u548c\u53cd\u5411\u4ee3\u7406\u4e0e\u5e94\u7528\u7a0b\u5e8f\u672c\u8eab\u5206\u79bb\uff0c\u4ee5\u4fbf\u540c\u4e00\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u591a\u4e2a\u73af\u5883\u4e2d\u4fdd\u6301\u4e0d\u53d8\u5730\u8fd0\u884c\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2701.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.1 The hosting model for ASP.NET Core gives flexibility. The same application can run exposed directly to the network, behind various reverse proxies without modification, and even inside the IIS process.<br \/>\n\u56fe 27.1 ASP.NET Core \u7684\u6258\u7ba1\u6a21\u578b\u63d0\u4f9b\u4e86\u7075\u6d3b\u6027\u3002\u540c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u76f4\u63a5\u66b4\u9732\u5728\u7f51\u7edc\u4e2d\uff0c\u65e0\u9700\u4fee\u6539\u5373\u53ef\u5728\u5404\u79cd\u53cd\u5411\u4ee3\u7406\u540e\u9762\u8fd0\u884c\uff0c\u751a\u81f3\u53ef\u4ee5\u5728 IIS \u8fdb\u7a0b\u5185\u90e8\u8fd0\u884c\u3002<\/p>\n<p>In this book we\u2019ve focused on the \u201capplication\u201d part of figure 27.1\u2014the ASP.NET Core application itself\u2014but the reality is that sometimes you\u2019ll want to place your ASP.NET Core apps behind a reverse proxy, such as IIS in Windows or NGINX or Apache in Linux. The reverse proxy is the program that listens for HTTP requests from the internet and then makes requests to your app as though the request came from the internet directly.<br \/>\n\u5728\u672c\u4e66\u4e2d\uff0c\u6211\u4eec\u91cd\u70b9\u4ecb\u7ecd\u4e86\u56fe 27.1 \u7684 \u201c\u5e94\u7528\u7a0b\u5e8f\u201d \u90e8\u5206 \u2014 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u672c\u8eab \u2014 \u4f46\u73b0\u5b9e\u60c5\u51b5\u662f\uff0c\u6709\u65f6\u60a8\u5e0c\u671b\u5c06 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u653e\u5728\u53cd\u5411\u4ee3\u7406\u540e\u9762\uff0c\u4f8b\u5982 Windows \u4e2d\u7684 IIS\uff0cLinux \u4e2d\u7684 NGINX \u6216 Apache\u3002\u53cd\u5411\u4ee3\u7406\u662f\u4fa6\u542c\u6765\u81ea Internet \u7684 HTTP \u8bf7\u6c42\uff0c\u7136\u540e\u5411\u5e94\u7528\u7a0b\u5e8f\u53d1\u51fa\u8bf7\u6c42\u7684\u7a0b\u5e8f\uff0c\u5c31\u50cf\u8bf7\u6c42\u76f4\u63a5\u6765\u81ea Internet \u4e00\u6837\u3002<\/p>\n<p><b>DEFINITION<\/b> A reverse proxy is software that\u2019s responsible for receiving requests and forwarding them to the appropriate web server. The reverse proxy is exposed directly to the internet, whereas the underlying web server is exposed only to the proxy.<br \/>\n\u5b9a\u4e49:\u53cd\u5411\u4ee3\u7406\u662f\u8d1f\u8d23\u63a5\u6536\u8bf7\u6c42\u5e76\u5c06\u5176\u8f6c\u53d1\u5230\u9002\u5f53\u7684 Web \u670d\u52a1\u5668\u7684\u8f6f\u4ef6\u3002\u53cd\u5411\u4ee3\u7406\u76f4\u63a5\u5411 Internet \u516c\u5f00\uff0c\u800c\u5e95\u5c42 Web \u670d\u52a1\u5668\u4ec5\u5411\u4ee3\u7406\u516c\u5f00\u3002<\/p>\n<p>If you\u2019re running your application using a Platform as a Service (PaaS) offering such as Azure App Service, you\u2019re using a reverse proxy there too\u2014one that is managed by Azure. Using a reverse proxy has many benefits:<br \/>\n\u5982\u679c\u4f7f\u7528\u5e73\u53f0\u5373\u670d\u52a1 \uff08PaaS\uff09 \u4ea7\u54c1\uff08\u5982 Azure \u5e94\u7528\u670d\u52a1\uff09\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u5219\u4e5f\u4f1a\u4f7f\u7528\u7531 Azure \u7ba1\u7406\u7684\u53cd\u5411\u4ee3\u7406\u3002\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\u6709\u5f88\u591a\u597d\u5904\uff1a<\/p>\n<p>\u2022  Security\u2014Reverse proxies are specifically designed to be exposed to malicious internet traffic, so they\u2019re typically extremely well-tested and battle-hardened.<br \/>\n\u5b89\u5168\u6027 - \u53cd\u5411\u4ee3\u7406\u4e13\u95e8\u8bbe\u8ba1\u7528\u4e8e\u66b4\u9732\u4e8e\u6076\u610f Internet \u6d41\u91cf\uff0c\u56e0\u6b64\u5b83\u4eec\u901a\u5e38\u7ecf\u8fc7\u6781\u5176\u4e25\u683c\u7684\u6d4b\u8bd5\u548c\u6218\u6597\u3002<\/p>\n<p>\u2022  Performance\u2014You can configure reverse proxies to provide performance improvements by aggressively caching responses to requests.<br \/>\n\u6027\u80fd - \u60a8\u53ef\u4ee5\u914d\u7f6e\u53cd\u5411\u4ee3\u7406\uff0c\u901a\u8fc7\u4e3b\u52a8\u7f13\u5b58\u5bf9\u8bf7\u6c42\u7684\u54cd\u5e94\u6765\u63d0\u9ad8\u6027\u80fd\u3002<\/p>\n<p>\u2022  Process management\u2014An unfortunate reality is that apps sometimes crash. Some reverse proxies can act as monitors\/schedulers to ensure that if an app crashes, the proxy can automatically restart it.<br \/>\n\u8fdb\u7a0b\u7ba1\u7406 - \u4e00\u4e2a\u4e0d\u5e78\u7684\u73b0\u5b9e\u662f\uff0c\u5e94\u7528\u7a0b\u5e8f\u6709\u65f6\u4f1a\u5d29\u6e83\u3002\u4e00\u4e9b\u53cd\u5411\u4ee3\u7406\u53ef\u4ee5\u5145\u5f53\u76d1\u89c6\u5668\/\u8c03\u5ea6\u7a0b\u5e8f\uff0c\u4ee5\u786e\u4fdd\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff0c\u4ee3\u7406\u53ef\u4ee5\u81ea\u52a8\u91cd\u65b0\u542f\u52a8\u5b83\u3002<\/p>\n<p>\u2022  Support for multiple apps\u2014It\u2019s common to have multiple apps running on a single server. Using a reverse proxy makes it easier to support this scenario by using the host name of a request to decide which app should receive the request.<br \/>\n\u652f\u6301\u591a\u4e2a\u5e94\u7528\u7a0b\u5e8f - \u5728\u5355\u4e2a\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u591a\u4e2a\u5e94\u7528\u7a0b\u5e8f\u662f\u5f88\u5e38\u89c1\u7684\u3002\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\u53ef\u4ee5\u66f4\u8f7b\u677e\u5730\u652f\u6301\u6b64\u65b9\u6848\uff0c\u65b9\u6cd5\u662f\u4f7f\u7528\u8bf7\u6c42\u7684\u4e3b\u673a\u540d\u6765\u51b3\u5b9a\u54ea\u4e2a\u5e94\u7528\u5e94\u63a5\u6536\u8bf7\u6c42\u3002<\/p>\n<p>I don\u2019t want to make it seem like using a reverse proxy is all sunshine and roses. There are some downsides:<br \/>\n\u6211\u4e0d\u60f3\u8ba9\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\u770b\u8d77\u6765\u5168\u662f\u9633\u5149\u548c\u73ab\u7470\u3002\u6709\u4e00\u4e9b\u7f3a\u70b9\uff1a<\/p>\n<p>\u2022  Complexity\u2014One of the biggest complaints is how complex reverse proxies can be. If you\u2019re managing the proxy yourself (as opposed to relying on a PaaS implementation), there can be lots of proxy-specific pitfalls to look out for.<br \/>\n\u590d\u6742\u6027 - \u6700\u5927\u7684\u62b1\u6028\u4e4b\u4e00\u662f\u53cd\u5411\u4ee3\u7406\u7684\u590d\u6742\u7a0b\u5ea6\u3002\u5982\u679c\u60a8\u81ea\u5df1\u7ba1\u7406\u4ee3\u7406\uff08\u800c\u4e0d\u662f\u4f9d\u8d56 PaaS \u5b9e\u73b0\uff09\uff0c\u5219\u53ef\u80fd\u4f1a\u6709\u8bb8\u591a\u7279\u5b9a\u4e8e\u4ee3\u7406\u7684\u9677\u9631\u9700\u8981\u6ce8\u610f\u3002<\/p>\n<p>\u2022  Inter-process communication\u2014Most reverse proxies require two processes: a reverse proxy and your web app. Communicating between the two is often slower than if you directly exposed your web app to requests from the internet.<br \/>\n\u8fdb\u7a0b\u95f4\u901a\u4fe1 - \u5927\u591a\u6570\u53cd\u5411\u4ee3\u7406\u9700\u8981\u4e24\u4e2a\u8fdb\u7a0b\uff1a\u53cd\u5411\u4ee3\u7406\u548c Web \u5e94\u7528\u7a0b\u5e8f\u3002\u4e24\u8005\u4e4b\u95f4\u7684\u901a\u4fe1\u901a\u5e38\u6bd4\u76f4\u63a5\u5c06 Web \u5e94\u7528\u7a0b\u5e8f\u516c\u5f00\u7ed9\u6765\u81ea Internet \u7684\u8bf7\u6c42\u8981\u6162\u3002<\/p>\n<p>\u2022  Restricted features\u2014Not all reverse proxies support all the same features as an ASP.NET Core app. For example, Kestrel supports HTTP\/2, but if your reverse proxy doesn\u2019t, you won\u2019t see the benefits.<br \/>\n\u53d7\u9650\u529f\u80fd - \u5e76\u975e\u6240\u6709\u53cd\u5411\u4ee3\u7406\u90fd\u652f\u6301\u4e0e ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u76f8\u540c\u7684\u6240\u6709\u529f\u80fd\u3002\u4f8b\u5982\uff0cKestrel \u652f\u6301 HTTP\/2\uff0c\u4f46\u5982\u679c\u60a8\u7684\u53cd\u5411\u4ee3\u7406\u4e0d\u652f\u6301\uff0c\u60a8\u5c06\u770b\u4e0d\u5230\u597d\u5904\u3002<\/p>\n<p>Whether you choose to use a reverse proxy or not, when the time comes to host your app, you can\u2019t copy your code files directly to the server. First, you need to publish your ASP.NET Core app to optimize it for production. In section 27.1.1 we\u2019ll look at building an ASP.NET Core app so that it can be run on your development machine, compared with publishing it so that it can be run on a server.<br \/>\n\u65e0\u8bba\u60a8\u662f\u5426\u9009\u62e9\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\uff0c\u5f53\u9700\u8981\u6258\u7ba1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u60a8\u90fd\u65e0\u6cd5\u5c06\u4ee3\u7801\u6587\u4ef6\u76f4\u63a5\u590d\u5236\u5230\u670d\u52a1\u5668\u3002\u9996\u5148\uff0c\u60a8\u9700\u8981\u53d1\u5e03 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4ee5\u9488\u5bf9\u751f\u4ea7\u73af\u5883\u8fdb\u884c\u4f18\u5316\u3002\u5728 Section 27.1.1 \u4e2d\uff0c\u6211\u4eec\u5c06\u4ecb\u7ecd\u5982\u4f55\u6784\u5efa ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u5728\u5f00\u53d1\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\uff0c\u800c\u4e0d\u662f\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\uff0c\u4f7f\u5176\u53ef\u4ee5\u5728\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u3002<\/p>\n<h3>27.1.1 Running vs. publishing an ASP.NET Core app<\/h3>\n<p>27.1.1 \u8fd0\u884c\u4e0e\u53d1\u5e03 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>One of the key changes in ASP.NET Core from previous versions of ASP.NET is making it easy to build apps using your favorite code editors and integrated development environments (IDEs). Previously, Visual Studio was required for ASP.NET development, but with the .NET command-line interface (CLI), you can build apps with the tools you\u2019re comfortable with on any platform.<br \/>\nASP.NET Core \u4e0e\u4ee5\u524d\u7684 ASP.NET \u7248\u672c\u76f8\u6bd4\uff0c\u5176\u4e2d\u4e00\u9879\u5173\u952e\u53d8\u5316\u662f\uff0c\u4f7f\u7528\u60a8\u6700\u559c\u6b22\u7684\u4ee3\u7801\u7f16\u8f91\u5668\u548c\u96c6\u6210\u5f00\u53d1\u73af\u5883 \uff08IDE\uff09 \u53ef\u4ee5\u8f7b\u677e\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u3002\u4ee5\u524d\uff0cASP.NET \u5f00\u53d1\u9700\u8981 Visual Studio\uff0c\u4f46\u501f\u52a9 .NET \u547d\u4ee4\u884c\u754c\u9762 \uff08CLI\uff09\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u719f\u6089\u7684\u5de5\u5177\u5728\u4efb\u4f55\u5e73\u53f0\u4e0a\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>As a result, whether you build using Visual Studio or the .NET CLI, the same tools are being used under the hood. Visual Studio provides an additional graphical user interface (GUI), functionality, and wrappers for building your app, but it (mostly) executes the same commands as the .NET CLI behind the scenes.<br \/>\n\u56e0\u6b64\uff0c\u65e0\u8bba\u60a8\u662f\u4f7f\u7528 Visual Studio \u8fd8\u662f .NET CLI \u8fdb\u884c\u6784\u5efa\uff0c\u90fd\u5728\u540e\u53f0\u4f7f\u7528\u76f8\u540c\u7684\u5de5\u5177\u3002Visual Studio \u63d0\u4f9b\u4e86\u7528\u4e8e\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u989d\u5916\u56fe\u5f62\u7528\u6237\u754c\u9762 \uff08GUI\uff09\u3001\u529f\u80fd\u548c\u5305\u88c5\u5668\uff0c\u4f46\u5b83\uff08\u4e3b\u8981\uff09\u5728\u540e\u53f0\u6267\u884c\u4e0e .NET CLI \u76f8\u540c\u7684\u547d\u4ee4\u3002<\/p>\n<p>As a refresher, you\u2019ve used four main .NET CLI commands so far to build your apps:<br \/>\n\u4f5c\u4e3a\u590d\u4e60\uff0c\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u60a8\u5df2\u7ecf\u4f7f\u7528\u4e86\u56db\u4e2a\u4e3b\u8981\u7684 .NET CLI \u547d\u4ee4\u6765\u6784\u5efa\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff1a<\/p>\n<p>\u2022  dotnet new\u2014Creates an ASP.NET Core application from a template<br \/>\ndotnet new - \u4ece\u6a21\u677f\u521b\u5efa ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<br \/>\n\u2022  dotnet restore\u2014Downloads and installs any referenced NuGet packages for your project<br \/>\ndotnet restore - \u4e0b\u8f7d\u5e76\u5b89\u88c5\u9879\u76ee\u7684\u4efb\u4f55\u5f15\u7528\u7684 NuGet \u5305<br \/>\n\u2022  dotnet build\u2014Compiles and builds your project<br \/>\ndotnet build - \u7f16\u8bd1\u548c\u751f\u6210\u9879\u76ee<br \/>\n\u2022  dotnet run\u2014Executes your app so you can send requests to it<br \/>\ndotnet run - \u6267\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u4fbf\u60a8\u53ef\u4ee5\u5411\u5176\u53d1\u9001\u8bf7\u6c42<\/p>\n<p>If you\u2019ve ever built a .NET application, whether it\u2019s a legacy ASP.NET app or a .NET Framework console app, you\u2019ll know that the output of the build process is written to the bin folder by default. The same is true for ASP.NET Core applications.<br \/>\n\u5982\u679c\u60a8\u66fe\u7ecf\u6784\u5efa\u8fc7 .NET \u5e94\u7528\u7a0b\u5e8f\uff0c\u65e0\u8bba\u662f\u65e7\u7248 ASP.NET \u5e94\u7528\u7a0b\u5e8f\u8fd8\u662f .NET Framework \u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u90fd\u4f1a\u77e5\u9053\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6784\u5efa\u8fc7\u7a0b\u7684\u8f93\u51fa\u4f1a\u5199\u5165 bin \u6587\u4ef6\u5939\u3002ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e5f\u662f\u5982\u6b64\u3002<\/p>\n<p>If your project compiles successfully when you call dotnet build, the .NET CLI writes the artifacts to a bin folder in your project\u2019s directory. Inside this bin folder are several files required to run your app, including a .dll file that contains the code for your application. Figure 27.2 shows the output of the bin folder for a basic ASP.NET Core application.<br \/>\n\u5982\u679c\u5728\u8c03\u7528 dotnet build \u65f6\u9879\u76ee\u7f16\u8bd1\u6210\u529f\uff0c\u5219 .NET CLI \u4f1a\u5c06\u9879\u76ee\u5199\u5165\u9879\u76ee\u76ee\u5f55\u4e2d\u7684 bin \u6587\u4ef6\u5939\u3002\u6b64 bin \u6587\u4ef6\u5939\u4e2d\u5305\u542b\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u591a\u4e2a\u6587\u4ef6\uff0c\u5305\u62ec\u4e00\u4e2a\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\u7684 .dll \u6587\u4ef6\u3002\u56fe 27.2 \u663e\u793a\u4e86\u57fa\u672c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684 bin \u6587\u4ef6\u5939\u7684\u8f93\u51fa\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2702.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.2 The bin folder for an ASP.NET Core app after running dotnet build. The application is compiled into a single .dll file, ExampleApp.dll.<br \/>\n\u56fe 27.2 \u8fd0\u884c dotnet build \u540e ASP.NET Core \u5e94\u7528\u7684 bin \u6587\u4ef6\u5939\u3002\u8be5\u5e94\u7528\u7a0b\u5e8f\u88ab\u7f16\u8bd1\u6210\u4e00\u4e2a .dll \u6587\u4ef6 ExampleApp.dll\u3002<\/p>\n<p><b>NOTE<\/b> In Windows you also have an executable .exe file, ExampleApp.exe. This is a simple wrapper file for convenience that makes it easier to run the application contained in ExampleApp.dll.<br \/>\n\u6ce8\u610f:\u5728 Windows \u4e2d\uff0c\u60a8\u8fd8\u6709\u4e00\u4e2a\u53ef\u6267\u884c\u7684 .exe \u6587\u4ef6 ExampleApp.exe\u3002\u4e3a\u65b9\u4fbf\u8d77\u89c1\uff0c\u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u5305\u88c5\u6587\u4ef6\uff0c\u53ef\u4ee5\u66f4\u8f7b\u677e\u5730\u8fd0\u884c ExampleApp.dll \u4e2d\u5305\u542b\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>When you call dotnet run in your project folder (or run your application using Visual Studio), the .NET CLI uses the .dll to run your application. But this file doesn\u2019t contain everything you need to deploy your app.<br \/>\n\u5728\u9879\u76ee\u6587\u4ef6\u5939\u4e2d\u8c03\u7528 dotnet run \uff08\u6216\u4f7f\u7528 Visual Studio \u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff09 \u65f6\uff0c.NET CLI \u4f1a\u4f7f\u7528.dll\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3002\u4f46\u6b64\u6587\u4ef6\u5e76\u4e0d\u5305\u542b\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u4e00\u5207\u3002<\/p>\n<p>To host and deploy your app on a server, you first need to publish it. You can publish your ASP.NET Core app from the command line using the dotnet publish command, which builds and packages everything your app needs to run. The following command packages the app from the current directory and builds it to a subfolder called publish. I\u2019ve used the Release configuration instead of the default Debug configuration so that the output will be fully optimized for running in production:<br \/>\n\u8981\u5728\u670d\u52a1\u5668\u4e0a\u6258\u7ba1\u548c\u90e8\u7f72\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u9996\u5148\u9700\u8981\u53d1\u5e03\u5b83\u3002\u53ef\u4ee5\u4f7f\u7528 dotnet publish \u547d\u4ee4\u4ece\u547d\u4ee4\u884c\u53d1\u5e03 ASP.NET Core \u5e94\u7528\uff0c\u8be5\u547d\u4ee4\u5c06\u751f\u6210\u548c\u6253\u5305\u5e94\u7528\u8fd0\u884c\u6240\u9700\u7684\u4e00\u5207\u3002\u4ee5\u4e0b\u547d\u4ee4\u5c06\u5f53\u524d\u76ee\u5f55\u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5305\uff0c\u5e76\u5c06\u5176\u6784\u5efa\u5230\u540d\u4e3a publish \u7684\u5b50\u6587\u4ef6\u5939\u4e2d\u3002\u6211\u4f7f\u7528\u4e86 Release \u914d\u7f6e\u800c\u4e0d\u662f\u9ed8\u8ba4\u7684 Debug \u914d\u7f6e\uff0c\u4ee5\u4fbf\u8f93\u51fa\u5c06\u5f97\u5230\u5168\u9762\u4f18\u5316\uff0c\u4ee5\u4fbf\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c\uff1a<\/p>\n<pre><code>dotnet publish --output publish --configuration Release<\/code><\/pre>\n<p><b>TIP<\/b>  Always use the Release configuration when publishing your app for deployment. This ensures that the compiler generates optimized code for your app.<br \/>\n\u63d0\u793a:\u5728\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u8fdb\u884c\u90e8\u7f72\u65f6\uff0c\u8bf7\u59cb\u7ec8\u4f7f\u7528 Release \uff08\u53d1\u5e03\uff09 \u914d\u7f6e\u3002\u8fd9\u53ef\u786e\u4fdd\u7f16\u8bd1\u5668\u4e3a\u60a8\u7684\u5e94\u7528\u751f\u6210\u4f18\u5316\u7684\u4ee3\u7801\u3002<\/p>\n<p>Once the command completes, you\u2019ll find your published application in the publish folder, as shown in figure 27.3.<br \/>\n\u547d\u4ee4\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u5728 publish \u6587\u4ef6\u5939\u4e2d\u627e\u5230\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u5982\u56fe 27.3 \u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2703.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.3 The publish folder for the app after running dotnet publish. The app is still compiled into a single .dll file, but all the additional files, such as wwwroot, are also copied to the output.<br \/>\n\u56fe 27.3 \u8fd0\u884c dotnet publish \u540e\u5e94\u7528\u7a0b\u5e8f\u7684 publish \u6587\u4ef6\u5939\u3002\u8be5\u5e94\u7528\u7a0b\u5e8f\u4ecd\u7f16\u8bd1\u4e3a\u5355\u4e2a .dll \u6587\u4ef6\uff0c\u4f46\u6240\u6709\u5176\u4ed6\u6587\u4ef6\uff08\u5982 wwwroot\uff09\u4e5f\u4f1a\u590d\u5236\u5230\u8f93\u51fa\u4e2d\u3002<\/p>\n<p>As you can see, the ExampleApp.dll file is still there, along with some additional files. Most notably, the publish process has copied across the wwwroot folder of static files. When running your application locally with dotnet run, the .NET CLI uses these files from your application\u2019s project folder directly. Running dotnet publish copies the files to the output directory, so they\u2019re included when you deploy your app to a server.<br \/>\n\u5982\u60a8\u6240\u89c1\uff0cExampleApp.dll \u6587\u4ef6\u4ecd\u7136\u5b58\u5728\uff0c\u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u6587\u4ef6\u3002\u6700\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u53d1\u5e03\u8fc7\u7a0b\u5df2\u590d\u5236\u9759\u6001\u6587\u4ef6\u7684 wwwroot \u6587\u4ef6\u5939\u3002\u4f7f\u7528 dotnet run \u5728\u672c\u5730\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c.NET CLI \u4f1a\u76f4\u63a5\u4f7f\u7528\u5e94\u7528\u7a0b\u5e8f\u9879\u76ee\u6587\u4ef6\u5939\u4e2d\u7684\u8fd9\u4e9b\u6587\u4ef6\u3002\u8fd0\u884c dotnet publish \u4f1a\u5c06\u6587\u4ef6\u590d\u5236\u5230\u8f93\u51fa\u76ee\u5f55\uff0c\u4ee5\u4fbf\u5728\u5c06\u5e94\u7528\u90e8\u7f72\u5230\u670d\u52a1\u5668\u65f6\u5305\u542b\u8fd9\u4e9b\u6587\u4ef6\u3002<\/p>\n<p>If your first instinct is to try running the application in the publish folder using the dotnet run command you already know and love, you\u2019ll be disappointed. Instead of seeing the application starting up, you\u2019ll see a somewhat confusing message: Couldn\u2019t find a project to run.<br \/>\n\u5982\u679c\u60a8\u7684\u7b2c\u4e00\u53cd\u5e94\u662f\u5c1d\u8bd5\u4f7f\u7528\u60a8\u5df2\u7ecf\u719f\u6089\u548c\u559c\u7231\u7684 dotnet run \u547d\u4ee4\u5728 publish \u6587\u4ef6\u5939\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u90a3\u4e48\u60a8\u4f1a\u611f\u5230\u5931\u671b\u3002\u60a8\u5c06\u770b\u5230\u4e00\u6761\u6709\u70b9\u4ee4\u4eba\u56f0\u60d1\u7684\u6d88\u606f\uff0c\u800c\u4e0d\u662f\u770b\u5230\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\uff1aCouldn't find a project to run\u3002<\/p>\n<p>To run a published application, you need to use a slightly different command. Instead of calling dotnet run, you must pass the path to your application\u2019s .dll file to the dotnet command. If you\u2019re running the command from the publish folder, for the example app in figure 27.3, it would look something like<br \/>\n\u8981\u8fd0\u884c\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u9700\u8981\u4f7f\u7528\u7565\u6709\u4e0d\u540c\u7684\u547d\u4ee4\u3002\u5fc5\u987b\u5c06\u5e94\u7528\u7a0b\u5e8f\u7684 .dll \u6587\u4ef6\u7684\u8def\u5f84\u4f20\u9012\u7ed9 dotnet \u547d\u4ee4\uff0c\u800c\u4e0d\u662f\u8c03\u7528 dotnet run\u3002\u5982\u679c\u60a8\u4ece publish \u6587\u4ef6\u5939\u8fd0\u884c\u547d\u4ee4\uff0c\u5bf9\u4e8e\u56fe 27.3 \u4e2d\u7684\u793a\u4f8b\u5e94\u7528\u7a0b\u5e8f\uff0c\u5b83\u770b\u8d77\u6765\u7c7b\u4f3c\u4e8e<\/p>\n<pre><code>dotnet ExampleApp.dll<\/code><\/pre>\n<p>This is the command that your server will run when running your application in production.<br \/>\n\u8fd9\u662f\u60a8\u7684\u670d\u52a1\u5668\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u65f6\u5c06\u8fd0\u884c\u7684\u547d\u4ee4\u3002<\/p>\n<p><b>TIP<\/b> You can also use the dotnet exec command to achieve the same thing, such as dotnet exec ExampleApp.dll. This makes some advanced runtime options available, as described in the docs at <a href=\"http:\/\/mng.bz\/x4d8\">http:\/\/mng.bz\/x4d8<\/a>.<br \/>\n\u63d0\u793a:\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528 dotnet exec \u547d\u4ee4\u6765\u5b9e\u73b0\u76f8\u540c\u7684\u4f5c\uff0c\u4f8b\u5982 dotnet exec ExampleApp.dll\u3002\u8fd9\u4f7f\u5f97\u4e00\u4e9b\u9ad8\u7ea7\u8fd0\u884c\u65f6\u9009\u9879\u53ef\u7528\uff0c\u5982 <a href=\"http:\/\/mng.bz\/x4d8\">http:\/\/mng.bz\/x4d8<\/a> \u4e2d\u7684\u6587\u6863\u4e2d\u6240\u8ff0\u3002<\/p>\n<p>When you\u2019re developing, the dotnet run command does a whole load of work to make things easier on you. It makes sure that your application is built, looks for a project file in the current folder, works out where the corresponding .dlls will be (in the bin folder), and finally runs your app.<br \/>\n\u5728\u5f00\u53d1\u65f6\uff0cdotnet run \u547d\u4ee4\u4f1a\u6267\u884c\u5927\u91cf\u5de5\u4f5c\uff0c\u4ee5\u7b80\u5316\u60a8\u7684\u4f5c\u3002\u5b83\u786e\u4fdd\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5df2\u6784\u5efa\uff0c\u5728\u5f53\u524d\u6587\u4ef6\u5939\u4e2d\u67e5\u627e\u9879\u76ee\u6587\u4ef6\uff0c\u8ba1\u7b97\u51fa\u76f8\u5e94\u7684 .dll \u5c06\u4f4d\u4e8e\u4f55\u5904\uff08\u5728 bin \u6587\u4ef6\u5939\u4e2d\uff09\uff0c\u6700\u540e\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>In production, you don\u2019t need any of this extra work. Your app is already built; it only needs to be run. The dotnet <code>&lt;dll&gt;<\/code> syntax does this alone, so your app starts much faster.<br \/>\n\u5728\u751f\u4ea7\u73af\u5883\u4e2d\uff0c\u60a8\u4e0d\u9700\u8981\u4efb\u4f55\u989d\u5916\u7684\u5de5\u4f5c\u3002\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5df2\u6784\u5efa\u5b8c\u6bd5;\u5b83\u53ea\u9700\u8981\u8fd0\u884c\u3002dotnet <code>&lt;dll&gt;<\/code>\u8bed\u6cd5\u5355\u72ec\u6267\u884c\u6b64\u4f5c\uff0c\u56e0\u6b64\u60a8\u7684\u5e94\u7528\u542f\u52a8\u901f\u5ea6\u8981\u5feb\u5f97\u591a\u3002<\/p>\n<p><b>NOTE<\/b> The dotnet command used to run your published application is part of the .NET Runtime. The (identically named) dotnet command used to build and run your application during development is part of the .NET software development kit (SDK).<br \/>\n\u6ce8\u610f:\u7528\u4e8e\u8fd0\u884c\u5df2\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u7684 dotnet \u547d\u4ee4\u662f .NET \u8fd0\u884c\u65f6\u7684\u4e00\u90e8\u5206\u3002\u5728\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u7528\u4e8e\u751f\u6210\u548c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\uff08\u540c\u540d\uff09dotnet \u547d\u4ee4\u662f .NET \u8f6f\u4ef6\u5f00\u53d1\u5de5\u5177\u5305 \uff08SDK\uff09 \u7684\u4e00\u90e8\u5206\u3002<\/p>\n<blockquote>\n<p>Framework-dependent deployments vs. self-contained deployments<br \/>\n\u4f9d\u8d56\u4e8e\u6846\u67b6\u7684\u90e8\u7f72\u4e0e\u72ec\u7acb\u90e8\u7f72\uff1a<\/p>\n<p>.NET Core applications can be deployed in two ways: runtime-dependent deployments (RDD) and self-contained deployments (SCD).<br \/>\n.NET Core \u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u901a\u8fc7\u4e24\u79cd\u65b9\u5f0f\u8fdb\u884c\u90e8\u7f72\uff1a\u4f9d\u8d56\u4e8e\u8fd0\u884c\u65f6\u7684\u90e8\u7f72 \uff08RDD\uff09 \u548c\u72ec\u7acb\u90e8\u7f72 \uff08SCD\uff09\u3002<\/p>\n<p>By default, you\u2019ll use an RDD. This relies on the .NET 7 runtime being installed on the target machine that runs your published app, but you can run your app on any platform\u2014Windows, Linux, or macOS\u2014without having to recompile.<br \/>\n\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u60a8\u5c06\u4f7f\u7528 RDD\u3002\u8fd9\u4f9d\u8d56\u4e8e\u5728\u8fd0\u884c\u5df2\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u7684\u76ee\u6807\u8ba1\u7b97\u673a\u4e0a\u5b89\u88c5\u7684 .NET 7 \u8fd0\u884c\u65f6\uff0c\u4f46\u60a8\u53ef\u4ee5\u5728\u4efb\u4f55\u5e73\u53f0\uff08Windows\u3001Linux \u6216 macOS\uff09\u4e0a\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u800c\u65e0\u9700\u91cd\u65b0\u7f16\u8bd1\u3002<\/p>\n<p>By contrast, an SCD contains all the code required to run your app, so the target machine doesn\u2019t need to have .NET 7 installed. Instead, publishing your app packages up the .NET 7 runtime with your app\u2019s code and libraries.<br \/>\n\u76f8\u6bd4\u4e4b\u4e0b\uff0cSCD \u5305\u542b\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u6240\u6709\u4ee3\u7801\uff0c\u56e0\u6b64\u76ee\u6807\u8ba1\u7b97\u673a\u4e0d\u9700\u8981\u5b89\u88c5 .NET 7\u3002\u76f8\u53cd\uff0c\u5c06\u5e94\u7528\u4e0e\u5e94\u7528\u7684\u4ee3\u7801\u548c\u5e93\u4e00\u8d77\u53d1\u5e03\u5230 .NET 7 \u8fd0\u884c\u65f6\u4e2d\u3002<\/p>\n<p>Each approach has its pros and cons, but in most cases I tend to create RDDs. The final size of RDDs is much smaller, as they contain only your app code instead of the whole .NET 7 framework, which SCDs contain. Also, you can deploy your RDD apps to any platform, whereas SCDs must be compiled specifically for the target machine\u2019s operating system, such as Windows 10 64-bit or Red Hat Enterprise Linux 64-bit.<br \/>\n\u6bcf\u79cd\u65b9\u6cd5\u90fd\u6709\u5176\u4f18\u70b9\u548c\u7f3a\u70b9\uff0c\u4f46\u5728\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6211\u503e\u5411\u4e8e\u521b\u5efa RDD\u3002RDD \u7684\u6700\u7ec8\u5927\u5c0f\u8981\u5c0f\u5f97\u591a\uff0c\u56e0\u4e3a\u5b83\u4eec\u4ec5\u5305\u542b\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\uff0c\u800c\u4e0d\u662f SCD \u5305\u542b\u7684\u6574\u4e2a .NET 7 \u6846\u67b6\u3002\u6b64\u5916\uff0c\u60a8\u53ef\u4ee5\u5c06 RDD \u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u4efb\u4f55\u5e73\u53f0\uff0c\u800c SCD \u5fc5\u987b\u4e13\u95e8\u4e3a\u76ee\u6807\u8ba1\u7b97\u673a\u7684\u4f5c\u7cfb\u7edf\uff08\u4f8b\u5982 Windows 10 64 \u4f4d\u6216 Red Hat Enterprise Linux 64 \u4f4d\uff09\u8fdb\u884c\u7f16\u8bd1\u3002<\/p>\n<p>That said, SCDs are excellent for isolating your application from dependencies on the hosting machine. SCDs don\u2019t rely on the version of .NET installed on a hosting provider, so you can (for example) use preview versions of .NET in Azure App Service without needing the preview version to be supported.<br \/>\n\u4e5f\u5c31\u662f\u8bf4\uff0cSCD \u975e\u5e38\u9002\u5408\u5c06\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e0e\u4e3b\u673a\u4e0a\u7684\u4f9d\u8d56\u9879\u9694\u79bb\u5f00\u6765\u3002SCD \u4e0d\u4f9d\u8d56\u4e8e\u6258\u7ba1\u63d0\u4f9b\u5546\u4e0a\u5b89\u88c5\u7684 .NET \u7248\u672c\uff0c\u56e0\u6b64\u4f60\u53ef\u4ee5\uff08\u4f8b\u5982\uff09\u5728 Azure \u5e94\u7528\u670d\u52a1\u4e2d\u4f7f\u7528 .NET \u7684\u9884\u89c8\u7248\uff0c\u800c\u65e0\u9700\u652f\u6301\u9884\u89c8\u7248\u3002<\/p>\n<p>Another advantage of SCDs is for regulated industries that require certification or procedure to change applications. In RDDs (such as in Azure App Service) the underlying runtime may be patched at any time without your intervention, potentially leading to noncompliance. With SCDs, your app contains a fixed runtime and can be considered an immutable snapshot of your app. Of course, that means you must make sure to patch the runtime of your SCDs manually, performing regular deployments. Patch versions of the .NET runtime are generally released every month, so make sure to plan for at least monthly releases of your SCD apps.<br \/>\nSCD \u7684\u53e6\u4e00\u4e2a\u4f18\u52bf\u662f\u9002\u7528\u4e8e\u9700\u8981\u8ba4\u8bc1\u6216\u7a0b\u5e8f\u6765\u66f4\u6539\u5e94\u7528\u7a0b\u5e8f\u7684\u53d7\u76d1\u7ba1\u884c\u4e1a\u3002\u5728 RDD \u4e2d\uff08\u4f8b\u5982\u5728 Azure \u5e94\u7528\u670d\u52a1\u4e2d\uff09\uff0c\u53ef\u80fd\u968f\u65f6\u4fee\u8865\u57fa\u7840\u8fd0\u884c\u65f6\uff0c\u800c\u65e0\u9700\u60a8\u7684\u5e72\u9884\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e0d\u5408\u89c4\u3002\u4f7f\u7528 SCD \u65f6\uff0c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5305\u542b\u56fa\u5b9a\u7684\u8fd0\u884c\u65f6\uff0c\u5e76\u4e14\u53ef\u4ee5\u88ab\u89c6\u4e3a\u5e94\u7528\u7a0b\u5e8f\u7684\u4e0d\u53ef\u53d8\u5feb\u7167\u3002\u5f53\u7136\uff0c\u8fd9\u610f\u5473\u7740\u60a8\u5fc5\u987b\u786e\u4fdd\u624b\u52a8\u4fee\u8865 SCD \u7684\u8fd0\u884c\u65f6\uff0c\u5e76\u6267\u884c\u5b9a\u671f\u90e8\u7f72\u3002.NET \u8fd0\u884c\u65f6\u7684\u8865\u4e01\u7248\u672c\u901a\u5e38\u6bcf\u4e2a\u6708\u53d1\u5e03\u4e00\u6b21\uff0c\u56e0\u6b64\u8bf7\u786e\u4fdd\u81f3\u5c11\u6bcf\u6708\u53d1\u5e03\u4e00\u6b21 SCD \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>In this book I discuss RDDs only for simplicity, but if you want to create an SCD, provide a runtime identifier (in this case, Windows 10 64-bit) when you publish your app:<br \/>\n\u5728\u672c\u4e66\u4e2d\uff0c\u6211\u8ba8\u8bba RDD \u53ea\u662f\u4e3a\u4e86\u7b80\u5355\u8d77\u89c1\uff0c\u4f46\u5982\u679c\u60a8\u60f3\u521b\u5efa\u4e00\u4e2a SCD\uff0c\u8bf7\u5728\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u65f6\u63d0\u4f9b\u8fd0\u884c\u65f6\u6807\u8bc6\u7b26\uff08\u5728\u672c\u4f8b\u4e2d\u4e3a Windows 10 64 \u4f4d\uff09\uff1a<\/p>\n<\/blockquote>\n<pre><code>dotnet publish -c Release -r win10-x64 --self-contained -o publish_folder<\/code><\/pre>\n<blockquote>\n<p>The output will contain an .exe file, which is your application, and a ton of .dlls (about 100 MB of .dlls for a default sample app), which are the .NET 7 framework. You need to deploy this whole folder to the target machine to run your app. Note that you need to publish for a specific operating system and architecture. The list of available runtime identifiers is available in the documentation at <a href=\"http:\/\/mng.bz\/Aolp\">http:\/\/mng.bz\/Aolp<\/a>.<br \/>\n\u8f93\u51fa\u5c06\u5305\u542b\u4e00\u4e2a .exe \u6587\u4ef6\uff08\u5373\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff09\u548c\u5927\u91cf .dll\uff08\u9ed8\u8ba4\u793a\u4f8b\u5e94\u7528\u7a0b\u5e8f\u7ea6\u4e3a 100 MB \u7684 .dll\uff09\uff0c\u5373 .NET 7 \u6846\u67b6\u3002\u60a8\u9700\u8981\u5c06\u6574\u4e2a\u6587\u4ef6\u5939\u90e8\u7f72\u5230\u76ee\u6807\u8ba1\u7b97\u673a\u624d\u80fd\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u8bf7\u6ce8\u610f\uff0c\u60a8\u9700\u8981\u9488\u5bf9\u7279\u5b9a\u7684\u4f5c\u7cfb\u7edf\u548c\u67b6\u6784\u8fdb\u884c\u53d1\u5e03\u3002\u53ef\u7528\u8fd0\u884c\u65f6\u6807\u8bc6\u7b26\u7684\u5217\u8868\u53ef\u5728 <a href=\"http:\/\/mng.bz\/Aolp\">http:\/\/mng.bz\/Aolp<\/a> \u7684\u6587\u6863\u4e2d\u627e\u5230\u3002<\/p>\n<p>In .NET 7 it\u2019s possible to trim these assemblies during the publish process, but this comes with risks in some scenarios. You can also bundle this folder into a single file automatically for easier deployments. For more details, see Microsoft\u2019s \u201c.NET application publishing overview\u201d documentation at <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/deploying\">https:\/\/learn.microsoft.com\/dotnet\/core\/deploying<\/a>.<br \/>\n\u5728 .NET 7 \u4e2d\uff0c\u53ef\u4ee5\u5728\u53d1\u5e03\u8fc7\u7a0b\u4e2d\u526a\u88c1\u8fd9\u4e9b\u7a0b\u5e8f\u96c6\uff0c\u4f46\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u8fd9\u4f1a\u5e26\u6765\u98ce\u9669\u3002\u60a8\u8fd8\u53ef\u4ee5\u81ea\u52a8\u5c06\u6b64\u6587\u4ef6\u5939\u6346\u7ed1\u5230\u4e00\u4e2a\u6587\u4ef6\u4e2d\uff0c\u4ee5\u4fbf\u4e8e\u90e8\u7f72\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/deploying\">https:\/\/learn.microsoft.com\/dotnet\/core\/deploying<\/a> Microsoft\u7684\u201c.NET \u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u6982\u8ff0\u201d\u6587\u6863\u3002<\/p>\n<\/blockquote>\n<p>We\u2019ve established that publishing your app is important for preparing it to run in production, but how do you go about deploying it? How do you get the files from your computer onto a server so that people can access your app? You have many, many options, so in the next section I\u2019ll give you a brief list of approaches to consider.<br \/>\n\u6211\u4eec\u5df2\u7ecf\u786e\u5b9a\uff0c\u53d1\u5e03\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5bf9\u4e8e\u51c6\u5907\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c\u975e\u5e38\u91cd\u8981\uff0c\u4f46\u60a8\u5982\u4f55\u90e8\u7f72\u5b83\u5462\uff1f\u5982\u4f55\u5c06\u6587\u4ef6\u4ece\u8ba1\u7b97\u673a\u4f20\u8f93\u5230\u670d\u52a1\u5668\u4e0a\uff0c\u4ee5\u4fbf\u4eba\u4eec\u53ef\u4ee5\u8bbf\u95ee\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff1f\u60a8\u6709\u5f88\u591a\u5f88\u591a\u9009\u62e9\uff0c\u56e0\u6b64\u5728\u4e0b\u4e00\u8282\u4e2d\uff0c\u6211\u5c06\u7b80\u8981\u5217\u51fa\u8981\u8003\u8651\u7684\u65b9\u6cd5\u3002<\/p>\n<h3>27.1.2 Choosing a deployment method for your application<\/h3>\n<p>27.1.2 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u9009\u62e9\u90e8\u7f72\u65b9\u6cd5<\/p>\n<p>To deploy any application to production, you generally have two fundamental requirements:<br \/>\n\u8981\u5c06\u4efb\u4f55\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u751f\u4ea7\u73af\u5883\uff0c\u60a8\u901a\u5e38\u6709\u4e24\u4e2a\u57fa\u672c\u8981\u6c42\uff1a<\/p>\n<p>\u2022  A server that can run your app<br \/>\n\u53ef\u4ee5\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\u670d\u52a1\u5668<br \/>\n\u2022  A means of loading your app onto the server<br \/>\n\u5c06\u5e94\u7528\u7a0b\u5e8f\u52a0\u8f7d\u5230\u670d\u52a1\u5668\u4e0a\u7684\u65b9\u6cd5<\/p>\n<p>Historically, putting an app into production was a laborious and error-prone process. For many people, this is still true. If you\u2019re working at a company that hasn\u2019t changed practices in recent years, you may need to request a server or virtual machine for your app and provide your application to an operations team that will install it for you. If that\u2019s the case, you may have your hands tied regarding how you deploy.<br \/>\n\u4ece\u5386\u53f2\u4e0a\u770b\uff0c\u5c06\u5e94\u7528\u7a0b\u5e8f\u6295\u5165\u751f\u4ea7\u662f\u4e00\u4e2a\u8d39\u529b\u4e14\u5bb9\u6613\u51fa\u9519\u7684\u8fc7\u7a0b\u3002\u5bf9\u8bb8\u591a\u4eba\u6765\u8bf4\uff0c\u8fd9\u4ecd\u7136\u662f\u6b63\u786e\u7684\u3002\u5982\u679c\u4f60\u5728\u4e00\u5bb6\u8fd1\u5e74\u6765\u6ca1\u6709\u6539\u53d8\u505a\u6cd5\u7684\u516c\u53f8\u5de5\u4f5c\uff0c\u4f60\u53ef\u80fd\u9700\u8981\u4e3a\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u8bf7\u6c42\u4e00\u4e2a\u670d\u52a1\u5668\u6216\u865a\u62df\u673a\uff0c\u5e76\u5c06\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u7ed9\u8fd0\u8425\u56e2\u961f\uff0c\u7531\u4ed6\u4eec\u4e3a\u4f60\u5b89\u88c5\u5b83\u3002\u5982\u679c\u662f\u8fd9\u79cd\u60c5\u51b5\uff0c\u60a8\u53ef\u80fd\u4f1a\u5728\u90e8\u7f72\u65b9\u5f0f\u4e0a\u675f\u624b\u65e0\u7b56\u3002<\/p>\n<p>For those who have embraced continuous integration (CI) or continuous delivery\/deployment (CD), there are many more possibilities. CI\/CD is the process of detecting changes in your version control system (for example, Git, SVN, Mercurial, or Team Foundation Version Control) and automatically building, and potentially deploying, your application to a server with little to no human intervention.<br \/>\n\u5bf9\u4e8e\u90a3\u4e9b\u5df2\u7ecf\u63a5\u53d7\u6301\u7eed\u96c6\u6210 \uff08CI\uff09 \u6216\u6301\u7eed\u4ea4\u4ed8\/\u90e8\u7f72 \uff08CD\uff09 \u7684\u4eba\u6765\u8bf4\uff0c\u8fd8\u6709\u66f4\u591a\u7684\u53ef\u80fd\u6027\u3002CI\/CD \u662f\u68c0\u6d4b\u7248\u672c\u63a7\u5236\u7cfb\u7edf\uff08\u4f8b\u5982 Git\u3001SVN\u3001Mercurial \u6216 Team Foundation \u7248\u672c\u63a7\u5236\uff09\u4e2d\u7684\u66f4\u6539\u5e76\u81ea\u52a8\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u5e76\u53ef\u80fd\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u670d\u52a1\u5668\u7684\u8fc7\u7a0b\uff0c\u51e0\u4e4e\u4e0d\u9700\u8981\u4eba\u5de5\u5e72\u9884\u3002<\/p>\n<p><b>NOTE<\/b> There are important but subtle differences between these terms. Atlassian has a good comparison article, \u201cContinuous integration vs. continuous delivery vs. continuous deployment,\u201d at <a href=\"http:\/\/mng.bz\/vzp4\">http:\/\/mng.bz\/vzp4<\/a>.<br \/>\n\u6ce8\u610f:\u8fd9\u4e9b\u672f\u8bed\u4e4b\u95f4\u5b58\u5728\u91cd\u8981\u4f46\u7ec6\u5fae\u7684\u5dee\u5f02\u3002Atlassian \u5728 <a href=\"http:\/\/mng.bz\/vzp4\">http:\/\/mng.bz\/vzp4<\/a> \u4e0a\u6709\u4e00\u7bc7\u5f88\u597d\u7684\u6bd4\u8f83\u6587\u7ae0\u201c\u6301\u7eed\u96c6\u6210\u3001\u6301\u7eed\u4ea4\u4ed8\u4e0e\u6301\u7eed\u90e8\u7f72\u201d\u3002<\/p>\n<p>There are many CI\/CD systems out there\u2014Azure DevOps, GitHub Actions, Jenkins, TeamCity, AppVeyor, Travis, and Octopus Deploy, to name a few. Each can manage some or all of the CI\/CD process and can integrate with many systems.<br \/>\n\u6709\u8bb8\u591a CI\/CD \u7cfb\u7edf\uff0c\u5305\u62ec Azure DevOps\u3001GitHub Actions\u3001Jenkins\u3001TeamCity\u3001AppVeyor\u3001Travis \u548c Octopus Deploy \u7b49\u3002\u6bcf\u4e2a\u7cfb\u7edf\u90fd\u53ef\u4ee5\u7ba1\u7406\u90e8\u5206\u6216\u5168\u90e8 CI\/CD \u6d41\u7a0b\uff0c\u5e76\u4e14\u53ef\u4ee5\u4e0e\u8bb8\u591a\u7cfb\u7edf\u96c6\u6210\u3002<\/p>\n<p>Rather than push any particular system, I suggest trying some of the services available and seeing which works best for you. Some are better suited to open-source projects, and some are better when you\u2019re deploying to cloud services; it all depends on your particular situation.<br \/>\n\u4e0e\u5176\u63a8\u52a8\u4efb\u4f55\u7279\u5b9a\u7684\u7cfb\u7edf\uff0c\u6211\u5efa\u8bae\u5c1d\u8bd5\u4e00\u4e9b\u53ef\u7528\u7684\u670d\u52a1\uff0c\u770b\u770b\u54ea\u79cd\u6700\u9002\u5408\u60a8\u3002\u6709\u4e9b\u66f4\u9002\u5408\u5f00\u6e90\u9879\u76ee\uff0c\u6709\u4e9b\u66f4\u9002\u5408\u90e8\u7f72\u5230\u4e91\u670d\u52a1;\u8fd9\u5b8c\u5168\u53d6\u51b3\u4e8e\u60a8\u7684\u5177\u4f53\u60c5\u51b5\u3002<\/p>\n<p>If you\u2019re getting started with ASP.NET Core and don\u2019t want to have to go through the setup process of getting CI working, you still have lots of options. The easiest way to get started with Visual Studio is to use the built-in deployment options. These are available from Visual Studio via the <code>Build &gt; Publish &lt;AppName&gt;<\/code> command, which presents the screen shown in figure 27.4.<br \/>\n\u5982\u679c\u60a8\u521a\u5f00\u59cb\u4f7f\u7528 ASP.NET Core\uff0c\u5e76\u4e14\u4e0d\u60f3\u5b8c\u6210\u8ba9 CI \u6b63\u5e38\u5de5\u4f5c\u7684\u8bbe\u7f6e\u8fc7\u7a0b\uff0c\u90a3\u4e48\u60a8\u4ecd\u7136\u6709\u5f88\u591a\u9009\u62e9\u3002\u5f00\u59cb\u4f7f\u7528 Visual Studio \u7684\u6700\u7b80\u5355\u65b9\u6cd5\u662f\u4f7f\u7528\u5185\u7f6e\u7684\u90e8\u7f72\u9009\u9879\u3002\u8fd9\u4e9b\u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4\u4ece Visual Studio <code>Build &gt; Publish &lt;AppName&gt;<\/code> \u83b7\u5f97\uff0c\u8be5\u547d\u4ee4\u663e\u793a\u56fe 27.4 \u6240\u793a\u7684\u5c4f\u5e55\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2704.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.4 The Publish application screen in Visual Studio 2022. This provides easy options for publishing your application directly to Azure App Service, to IIS, to an FTP site, or to a folder on the local machine.<br \/>\n\u56fe 27.4 Visual Studio 2022 \u4e2d\u7684 Publish application\uff08\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\uff09\u5c4f\u5e55\u3002\u8fd9\u4e3a\u5c06\u5e94\u7528\u7a0b\u5e8f\u76f4\u63a5\u53d1\u5e03\u5230 Azure \u5e94\u7528\u670d\u52a1\u3001IIS\u3001FTP \u7ad9\u70b9\u6216\u672c\u5730\u8ba1\u7b97\u673a\u4e0a\u7684\u6587\u4ef6\u5939\u63d0\u4f9b\u4e86\u7b80\u5355\u7684\u9009\u9879\u3002<\/p>\n<p>From here, you can publish your application directly from Visual Studio to many locations. This is great when you\u2019re getting started, though I recommend looking at a more automated and controlled approach when you have a larger application or a whole team working on a single app.<br \/>\n\u5728\u8fd9\u91cc\uff0c\u60a8\u53ef\u4ee5\u76f4\u63a5\u4ece Visual Studio \u5c06\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230\u8bb8\u591a\u4f4d\u7f6e\u3002\u8fd9\u5728\u60a8\u5f00\u59cb\u65f6\u975e\u5e38\u6709\u7528\uff0c\u4f46\u5f53\u60a8\u6709\u66f4\u5927\u7684\u5e94\u7528\u7a0b\u5e8f\u6216\u6574\u4e2a\u56e2\u961f\u5728\u5f00\u53d1\u5355\u4e2a\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u6211\u5efa\u8bae\u60a8\u8003\u8651\u4e00\u79cd\u66f4\u52a0\u81ea\u52a8\u5316\u548c\u53ef\u63a7\u7684\u65b9\u6cd5\u3002<\/p>\n<p><b>TIP<\/b> For guidance on choosing your Visual Studio publishing options, see Microsoft\u2019s \u201cDeploy your app to a folder, IIS, Azure, or another destination\u201d documentation at <a href=\"http:\/\/mng.bz\/4Z8j\">http:\/\/mng.bz\/4Z8j<\/a>.<br \/>\n\u63d0\u793a:\u6709\u5173\u9009\u62e9 Visual Studio \u53d1\u5e03\u9009\u9879\u7684\u6307\u5bfc\uff0c\u8bf7\u53c2\u9605 <a href=\"http:\/\/mng.bz\/4Z8j\">http:\/\/mng.bz\/4Z8j<\/a> Microsoft\u7684\u201c\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u6587\u4ef6\u5939\u3001IIS\u3001Azure \u6216\u5176\u4ed6\u76ee\u6807\u201d\u6587\u6863\u3002<\/p>\n<p>Given the number of possibilities available in this space and the speed with which these options change, I\u2019m going to focus on one specific scenario in this chapter: you\u2019ve built an ASP.NET Core application, and you need to deploy it. You have access to a Windows server that\u2019s already serving legacy .NET Framework ASP.NET applications using IIS, and you want to run your ASP.NET Core app alongside them.<br \/>\n\u8003\u8651\u5230\u6b64\u9886\u57df\u4e2d\u53ef\u7528\u7684\u53ef\u80fd\u6027\u6570\u91cf\u4ee5\u53ca\u8fd9\u4e9b\u9009\u9879\u53d8\u5316\u7684\u901f\u5ea6\uff0c\u6211\u5c06\u5728\u672c\u7ae0\u4e2d\u91cd\u70b9\u4ecb\u7ecd\u4e00\u4e2a\u7279\u5b9a\u573a\u666f\uff1a\u60a8\u5df2\u7ecf\u6784\u5efa\u4e86\u4e00\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u4e14\u9700\u8981\u90e8\u7f72\u5b83\u3002\u60a8\u53ef\u4ee5\u8bbf\u95ee\u5df2\u4f7f\u7528 IIS \u4e3a\u65e7\u7248 .NET Framework ASP.NET \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u670d\u52a1\u7684 Windows \u670d\u52a1\u5668\uff0c\u5e76\u4e14\u60a8\u5e0c\u671b\u4e0e\u5b83\u4eec\u4e00\u8d77\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>In the next section you\u2019ll see an overview of the steps required to run an ASP.NET Core application in production, using IIS as a reverse proxy. It won\u2019t be a master class in configuring IIS (there\u2019s so much depth to the 25-year-old product that I wouldn\u2019t know where to start!), but I\u2019ll cover the basics needed to get your application serving requests.<br \/>\n\u5728\u4e0b\u4e00\u90e8\u5206\u4e2d\uff0c\u4f60\u5c06\u770b\u5230\u4f7f\u7528 IIS \u4f5c\u4e3a\u53cd\u5411\u4ee3\u7406\u5728\u751f\u4ea7\u4e2d\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u6b65\u9aa4\u7684\u6982\u8ff0\u3002\u5b83\u4e0d\u4f1a\u662f\u914d\u7f6e IIS \u7684\u5927\u5e08\u8bfe\u7a0b\uff08\u8fd9\u4e2a 25 \u5e74\u524d\u7684\u4ea7\u54c1\u6709\u592a\u591a\u7684\u6df1\u5ea6\uff0c\u6211\u4e0d\u77e5\u9053\u4ece\u54ea\u91cc\u5f00\u59cb\uff01\uff09\uff0c\u4f46\u6211\u5c06\u4ecb\u7ecd\u8ba9\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e3a\u8bf7\u6c42\u63d0\u4f9b\u670d\u52a1\u6240\u9700\u7684\u57fa\u7840\u77e5\u8bc6\u3002<\/p>\n<h2>27.2 Publishing your app to IIS<\/h2>\n<p>27.2 \u5c06\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230 IIS<\/p>\n<p>In this section I briefly show you how to publish your first app to IIS. You\u2019ll add an application pool and website to IIS and ensure that your app has the necessary configuration to work with IIS as a reverse proxy. The deployment itself will be as simple as copying your published app to IIS\u2019s hosting folder.<br \/>\n\u5728\u672c\u8282\u4e2d\uff0c\u6211\u5c06\u7b80\u8981\u4ecb\u7ecd\u5982\u4f55\u5c06\u7b2c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230 IIS\u3002\u4f60\u5c06\u5411 IIS \u6dfb\u52a0\u5e94\u7528\u7a0b\u5e8f\u6c60\u548c\u7f51\u7ad9\uff0c\u5e76\u786e\u4fdd\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u5177\u6709\u5c06 IIS \u7528\u4f5c\u53cd\u5411\u4ee3\u7406\u6240\u9700\u7684\u914d\u7f6e\u3002\u90e8\u7f72\u672c\u8eab\u5c31\u50cf\u5c06\u60a8\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\u590d\u5236\u5230 IIS \u7684\u6258\u7ba1\u6587\u4ef6\u5939\u4e00\u6837\u7b80\u5355\u3002<\/p>\n<p>In section 27.1 you learned about the need to publish an app before you deploy it and the benefits of using a reverse proxy when you run an ASP.NET Core app in production. If you\u2019re deploying your application to Windows, IIS will likely be your reverse proxy and will be responsible for managing your application.<br \/>\n\u5728\u7b2c 27.1 \u8282\u4e2d\uff0c\u60a8\u4e86\u89e3\u4e86\u5728\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u7684\u5fc5\u8981\u6027\uff0c\u4ee5\u53ca\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u65f6\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\u7684\u597d\u5904\u3002\u5982\u679c\u8981\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230 Windows\uff0cIIS \u53ef\u80fd\u662f\u60a8\u7684\u53cd\u5411\u4ee3\u7406\uff0c\u5e76\u8d1f\u8d23\u7ba1\u7406\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>IIS is an old and complex beast, and I can\u2019t possibly cover everything related to configuring it in this book. Neither would you want me to; that discussion would be boring! Instead, in this section I\u2019ll provide an overview of the basic requirements for running ASP.NET Core behind IIS, along with the changes you may need to make to your application to support IIS.<br \/>\nIIS \u662f\u4e00\u4e2a\u53e4\u8001\u800c\u590d\u6742\u7684\u91ce\u517d\uff0c\u6211\u4e0d\u53ef\u80fd\u5728\u672c\u4e66\u4e2d\u6db5\u76d6\u4e0e\u914d\u7f6e\u5b83\u76f8\u5173\u7684\u6240\u6709\u5185\u5bb9\u3002\u4f60\u4e5f\u4e0d\u5e0c\u671b\u6211\u8fd9\u6837\u505a;\u90a3\u4e2a\u8ba8\u8bba\u4f1a\u5f88\u65e0\u804a\uff01\u76f8\u53cd\uff0c\u5728\u672c\u8282\u4e2d\uff0c\u6211\u5c06\u6982\u8ff0\u5728 IIS \u540e\u9762\u8fd0\u884c ASP.NET Core \u7684\u57fa\u672c\u8981\u6c42\uff0c\u4ee5\u53ca\u60a8\u53ef\u80fd\u9700\u8981\u5bf9\u5e94\u7528\u7a0b\u5e8f\u8fdb\u884c\u7684\u66f4\u6539\u4ee5\u652f\u6301 IIS\u3002<\/p>\n<p>If you\u2019re on Windows and want to try these steps locally, you\u2019ll need to enable IIS manually on your development machine. If you\u2019ve done this with older versions of Windows, nothing much has changed. You can find a step-by-step guide to configuring IIS and troubleshooting tips in the ASP.NET Core documentation at <a href=\"http:\/\/mng.bz\/6g2R\">http:\/\/mng.bz\/6g2R<\/a>.<br \/>\n\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f Windows \u5e76\u5e0c\u671b\u5728\u672c\u5730\u5c1d\u8bd5\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u5219\u9700\u8981\u5728\u5f00\u53d1\u8ba1\u7b97\u673a\u4e0a\u624b\u52a8\u542f\u7528 IIS\u3002\u5982\u679c\u4f60\u5728\u65e7\u7248\u672c\u7684 Windows \u4e0a\u8fd9\u6837\u505a\u4e86\uff0c\u90a3\u4e48\u6ca1\u6709\u4ec0\u4e48\u592a\u5927\u7684\u53d8\u5316\u3002\u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/6g2R\">http:\/\/mng.bz\/6g2R<\/a> \u7684 ASP.NET Core \u6587\u6863\u4e2d\u627e\u5230\u914d\u7f6e IIS \u7684\u5206\u6b65\u6307\u5357\u548c\u6545\u969c\u6392\u9664\u63d0\u793a\u3002<\/p>\n<h3>27.2.1 Configuring IIS for ASP.NET Core<\/h3>\n<p>27.2.1 \u4e3a ASP.NET Core \u914d\u7f6e IIS<\/p>\n<p>The first step in preparing IIS to host ASP.NET Core applications is installing the ASP.NET Core Windows Hosting Bundle (<a href=\"http:\/\/mng.bz\/opED\">http:\/\/mng.bz\/opED<\/a>). This includes several components needed to run .NET apps:<br \/>\n\u51c6\u5907 IIS \u4ee5\u6258\u7ba1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u7b2c\u4e00\u6b65\u662f\u5b89\u88c5 ASP.NET Core Windows \u6258\u7ba1\u6346\u7ed1\u5305 \uff08<a href=\"http:\/\/mng.bz\/opED\uff09\u3002\u8fd9\u5305\u62ec\u8fd0\u884c\">http:\/\/mng.bz\/opED\uff09\u3002\u8fd9\u5305\u62ec\u8fd0\u884c<\/a> .NET \u5e94\u7528\u6240\u9700\u7684\u51e0\u4e2a\u7ec4\u4ef6\uff1a<\/p>\n<p>\u2022  The .NET Runtime\u2014Runs your .NET 7 application<br \/>\n.NET \u8fd0\u884c\u65f6 - \u8fd0\u884c .NET 7 \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>\u2022  The ASP.NET Core Runtime\u2014Required to run ASP.NET Core apps<br \/>\nASP.NET Core \u8fd0\u884c\u65f6 - \u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6240\u9700<\/p>\n<p>\u2022  The IIS AspNetCore Module\u2014Provides the link between IIS and your app so that IIS can act as a reverse proxy<br \/>\nIIS AspNetCore \u6a21\u5757 - \u63d0\u4f9b IIS \u548c\u5e94\u7528\u7a0b\u5e8f\u4e4b\u95f4\u7684\u94fe\u63a5\uff0c\u4ee5\u4fbf IIS \u53ef\u4ee5\u5145\u5f53\u53cd\u5411\u4ee3\u7406<\/p>\n<p>If you\u2019re going to be running IIS on your development machine, make sure that you install the bundle as well; otherwise, you\u2019ll get strange errors from IIS.<br \/>\n\u5982\u679c\u8981\u5728\u5f00\u53d1\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c IIS\uff0c\u8bf7\u786e\u4fdd\u540c\u65f6\u5b89\u88c5\u6346\u7ed1\u5305;\u5426\u5219\uff0c\u60a8\u5c06\u4ece IIS \u6536\u5230\u5947\u602a\u7684\u9519\u8bef\u3002<\/p>\n<p><b>TIP<\/b> The Windows Hosting Bundle provides everything you need for running ASP.NET Core behind IIS in Windows. If you\u2019re hosting your application in Linux or Mac, or aren\u2019t using IIS in Windows, you need to install only the .NET Runtime and ASP.NET Core Runtime to run runtime-dependent ASP.NET Core apps. Note that you need to install the IIS AspNetCore Module even if you are using SCDs.<br \/>\n\u63d0\u793a:Windows \u6258\u7ba1\u6346\u7ed1\u5305\u63d0\u4f9b\u4e86\u5728 Windows \u4e2d\u5728 IIS \u540e\u9762\u8fd0\u884c ASP.NET Core \u6240\u9700\u7684\u4e00\u5207\u3002\u5982\u679c\u60a8\u5728 Linux \u6216 Mac \u4e2d\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\uff0c\u6216\u8005\u4e0d\u5728 Windows \u4e2d\u4f7f\u7528 IIS\uff0c\u5219\u53ea\u9700\u5b89\u88c5 .NET \u8fd0\u884c\u65f6\u548c ASP.NET Core \u8fd0\u884c\u65f6\u5373\u53ef\u8fd0\u884c\u4f9d\u8d56\u4e8e\u8fd0\u884c\u65f6\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u3002\u8bf7\u6ce8\u610f\uff0c\u5373\u4f7f\u60a8\u4f7f\u7528\u7684\u662f SCD\uff0c\u4e5f\u9700\u8981\u5b89\u88c5 IIS AspNetCore \u6a21\u5757\u3002<\/p>\n<p>Once you\u2019ve installed the bundle, you need to configure an application pool in IIS for your ASP.NET Core apps. Previous versions of ASP.NET would run in a managed app pool that used .NET Framework, but for ASP.NET Core you should create a No Managed Code pool. The native ASP.NET Core Module runs inside the pool, which boots the .NET 7 Runtime itself.<br \/>\n\u5b89\u88c5\u6346\u7ed1\u5305\u540e\uff0c\u60a8\u9700\u8981\u5728 IIS \u4e2d\u4e3a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u6c60\u3002\u65e9\u671f\u7248\u672c\u7684 ASP.NET \u5c06\u5728\u4f7f\u7528 .NET Framework \u7684\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\u6c60\u4e2d\u8fd0\u884c\uff0c\u4f46\u5bf9\u4e8e ASP.NET Core\uff0c\u60a8\u5e94\u8be5\u521b\u5efa\u4e00\u4e2a\u65e0\u6258\u7ba1\u4ee3\u7801\u6c60\u3002\u672c\u673a ASP.NET Core Module \u5728\u6c60\u5185\u8fd0\u884c\uff0c\u8be5\u6c60\u542f\u52a8 .NET 7 \u8fd0\u884c\u65f6\u672c\u8eab\u3002<\/p>\n<p><b>DEFINITION<\/b> An application pool in IIS represents an application process. You can run each app in IIS in a separate application pool to keep the apps isolated from one another.<br \/>\n\u5b9a\u4e49:IIS \u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u6c60\u8868\u793a\u5e94\u7528\u7a0b\u5e8f\u8fdb\u7a0b\u3002\u60a8\u53ef\u4ee5\u5728 IIS \u4e2d\u7684\u5355\u72ec\u5e94\u7528\u7a0b\u5e8f\u6c60\u4e2d\u8fd0\u884c\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u4f7f\u5e94\u7528\u7a0b\u5e8f\u5f7c\u6b64\u9694\u79bb\u3002<\/p>\n<p>To create an unmanaged application pool, right-click Application Pools in IIS and choose Add Application Pool from the contextual menu. Provide a name for the app pool in the resulting dialog box, such as dotnet7, and set the .NET CLR version to No Managed Code, as shown in figure 27.5.<br \/>\n\u8981\u521b\u5efa\u975e\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\u6c60\uff0c\u8bf7\u53f3\u952e\u5355\u51fb IIS \u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u6c60\uff0c\u7136\u540e\u4ece\u4e0a\u4e0b\u6587\u83dc\u5355\u4e2d\u9009\u62e9\u6dfb\u52a0\u5e94\u7528\u7a0b\u5e8f\u6c60\u3002\u5728\u751f\u6210\u7684\u5bf9\u8bdd\u6846\u4e2d\u4e3a\u5e94\u7528\u7a0b\u5e8f\u6c60\u63d0\u4f9b\u4e00\u4e2a\u540d\u79f0\uff0c\u4f8b\u5982 dotnet7\uff0c\u5e76\u5c06 .NET CLR \u7248\u672c\u8bbe\u7f6e\u4e3a\u201c\u65e0\u6258\u7ba1\u4ee3\u7801\u201d\uff0c\u5982\u56fe 27.5 \u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2705.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.5 Creating an app pool in IIS for your ASP.NET Core app. The .NET CLR version should be set to No Managed Code.<br \/>\n\u56fe 27.5 \u5728 IIS \u4e2d\u4e3a\u60a8\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\u6c60\u3002.NET CLR \u7248\u672c\u5e94\u8bbe\u7f6e\u4e3a\u65e0\u6258\u7ba1\u4ee3\u7801\u3002<\/p>\n<p>Now that you have an app pool, you can add a new website to IIS. Right-click the Sites node, and choose Add Website from the contextual menu. In the Add Website dialog box, shown in figure 27.6, you provide a name for the website and the path to the folder where you\u2019ll publish your website. I created a folder that I\u2019ll use to deploy the Recipe app from previous chapters. It\u2019s important to change the Application Pool for the app to the new dotnet7 app pool you created. In production, you\u2019d also provide a hostname for the application, but I\u2019ve left it blank for now in this example and changed the port to 81 so the application will bind to the URL <a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a>.<br \/>\n\u73b0\u5728\uff0c\u60a8\u5df2\u62e5\u6709\u5e94\u7528\u7a0b\u5e8f\u6c60\uff0c\u53ef\u4ee5\u5411 IIS \u6dfb\u52a0\u65b0\u7f51\u7ad9\u3002\u53f3\u952e\u5355\u51fb Sites \u8282\u70b9\uff0c\u7136\u540e\u4ece\u4e0a\u4e0b\u6587\u83dc\u5355\u4e2d\u9009\u62e9 Add Website\u3002\u5728 Add Website \u5bf9\u8bdd\u6846\u4e2d\uff08\u5982\u56fe 27.6 \u6240\u793a\uff09\uff0c\u60a8\u9700\u8981\u63d0\u4f9b\u7f51\u7ad9\u7684\u540d\u79f0\u4ee5\u53ca\u8981\u53d1\u5e03\u7f51\u7ad9\u7684\u6587\u4ef6\u5939\u7684\u8def\u5f84\u3002\u6211\u521b\u5efa\u4e86\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u6211\u5c06\u4f7f\u7528\u5b83\u6765\u90e8\u7f72\u524d\u9762\u7ae0\u8282\u4e2d\u7684 Recipe \u5e94\u7528\u7a0b\u5e8f\u3002\u8bf7\u52a1\u5fc5\u5c06\u5e94\u7528\u7684 Application Pool\uff08\u5e94\u7528\u7a0b\u5e8f\u6c60\uff09\u66f4\u6539\u4e3a\u60a8\u521b\u5efa\u7684\u65b0 dotnet7 \u5e94\u7528\u7a0b\u5e8f\u6c60\u3002\u5728\u751f\u4ea7\u73af\u5883\u4e2d\uff0c\u60a8\u8fd8\u9700\u8981\u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e3b\u673a\u540d\uff0c\u4f46\u5728\u6b64\u793a\u4f8b\u4e2d\uff0c\u6211\u6682\u65f6\u5c06\u5176\u7559\u7a7a\uff0c\u5e76\u5c06\u7aef\u53e3\u66f4\u6539\u4e3a 81\uff0c\u4ee5\u4fbf\u5e94\u7528\u7a0b\u5e8f\u5c06\u7ed1\u5b9a\u5230 URL <a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a>\u3002<\/p>\n<p><b>NOTE<\/b> When you deploy an application to production, you need to register a hostname with a domain registrar so that your site is accessible by people on the internet. Use that hostname when configuring your application in IIS, as shown in figure 27.6.<br \/>\n\u6ce8\u610f:\u5f53\u60a8\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u751f\u4ea7\u73af\u5883\u65f6\uff0c\u60a8\u9700\u8981\u5411\u57df\u6ce8\u518c\u5546\u6ce8\u518c\u4e3b\u673a\u540d\uff0c\u4ee5\u4fbf Internet \u4e0a\u7684\u7528\u6237\u53ef\u4ee5\u8bbf\u95ee\u60a8\u7684\u7ad9\u70b9\u3002\u5728 IIS \u4e2d\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u8bf7\u4f7f\u7528\u8be5\u4e3b\u673a\u540d\uff0c\u5982\u56fe 27.6 \u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2706.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.6 Adding a new website to IIS for your app. Be sure to change the Application Pool to the No Managed Code pool created in the previous step. You also provide a name, the path where you\u2019ll publish your app files, and the URL that IIS will use for your app.<br \/>\n\u56fe 27.6 \u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5411 IIS \u6dfb\u52a0\u65b0\u7f51\u7ad9\u3002\u8bf7\u52a1\u5fc5\u5c06 Application Pool\uff08\u5e94\u7528\u7a0b\u5e8f\u6c60\uff09\u66f4\u6539\u4e3a\u5728\u4e0a\u4e00\u6b65\u4e2d\u521b\u5efa\u7684 No Managed Code \uff08\u65e0\u6258\u7ba1\u4ee3\u7801\uff09 \u6c60\u3002\u60a8\u8fd8\u63d0\u4f9b\u540d\u79f0\u3001\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u6587\u4ef6\u7684\u8def\u5f84\u4ee5\u53ca IIS \u5c06\u7528\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684 URL\u3002<\/p>\n<p>Once you click OK, IIS creates the application and attempts to start it. But you haven\u2019t published your app to the folder, so you won\u2019t be able to view it in a browser yet.<br \/>\n\u5355\u51fb\u201c\u786e\u5b9a\u201d\u540e\uff0cIIS \u5c06\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\u5e76\u5c1d\u8bd5\u542f\u52a8\u5b83\u3002\u4f46\u662f\u60a8\u5c1a\u672a\u5c06\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230\u8be5\u6587\u4ef6\u5939\uff0c\u56e0\u6b64\u60a8\u5c1a\u65e0\u6cd5\u5728\u6d4f\u89c8\u5668\u4e2d\u67e5\u770b\u5b83\u3002<\/p>\n<p>You need to carry out one more critical setup step before you can publish and run your app: grant permissions for the dotnet7 app pool to access the path where you\u2019ll publish your app. To do this, right-click the folder that will host your app in Windows File Explorer, and choose Properties from the contextual menu. In the Properties dialog box, choose <code>Security &gt; Edit &gt; Add<\/code>. Enter IIS AppPool\\dotnet7 in the text box, as shown in figure 27.7, where dotnet7 is the name of your app pool; then choose OK. Close all the dialog boxes by choosing OK, and you\u2019re all set.<br \/>\n\u5728\u53d1\u5e03\u548c\u8fd0\u884c\u5e94\u7528\u4e4b\u524d\uff0c\u8fd8\u9700\u8981\u6267\u884c\u4e00\u4e2a\u5173\u952e\u7684\u8bbe\u7f6e\u6b65\u9aa4\uff1a\u4e3a dotnet7 \u5e94\u7528\u6c60\u6388\u4e88\u8bbf\u95ee\u5c06\u53d1\u5e03\u5e94\u7528\u7684\u8def\u5f84\u7684\u6743\u9650\u3002\u4e3a\u6b64\uff0c\u8bf7\u53f3\u952e\u5355\u51fb\u5c06\u5728 Windows \u6587\u4ef6\u8d44\u6e90\u7ba1\u7406\u5668\u4e2d\u6258\u7ba1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u5939\uff0c\u7136\u540e\u4ece\u4e0a\u4e0b\u6587\u83dc\u5355\u4e2d\u9009\u62e9 Properties \uff08\u5c5e\u6027\uff09\u3002\u5728 Properties \uff08\u5c5e\u6027\uff09 \u5bf9\u8bdd\u6846\u4e2d\uff0c\u9009\u62e9 <code>Security &gt; Edit &gt; Add<\/code>\u3002\u5728\u6587\u672c\u6846\u4e2d\u8f93\u5165 IIS AppPool\\dotnet7\uff0c\u5982\u56fe 27.7 \u6240\u793a\uff0c\u5176\u4e2d dotnet7 \u662f\u5e94\u7528\u7a0b\u5e8f\u6c60\u7684\u540d\u79f0;\u7136\u540e\u9009\u62e9 OK \uff08\u786e\u5b9a\uff09\u3002\u9009\u62e9 OK \uff08\u786e\u5b9a\uff09 \u5173\u95ed\u6240\u6709\u5bf9\u8bdd\u6846\uff0c\u4e00\u5207\u5c31\u7eea\u3002Security &gt; Edit &gt; Add<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2707.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.7 Adding permission for the dotnet7 app pool to the website\u2019s publish folder<br \/>\n\u56fe 27.7 \u5c06 dotnet7 \u5e94\u7528\u6c60\u7684\u6743\u9650\u6dfb\u52a0\u5230\u7f51\u7ad9\u7684\u53d1\u5e03\u6587\u4ef6\u5939<\/p>\n<p>Out of the box, the ASP.NET Core templates are configured to work seamlessly with IIS, but if you\u2019ve created an app from scratch, you may need to make a couple of changes. In the next section I\u2019ll briefly show the changes you need to make and explain why they\u2019re necessary.<br \/>\n\u5f00\u7bb1\u5373\u7528\u7684 ASP.NET Core \u6a21\u677f\u914d\u7f6e\u4e3a\u4e0e IIS \u65e0\u7f1d\u534f\u4f5c\uff0c\u4f46\u5982\u679c\u60a8\u4ece\u5934\u5f00\u59cb\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\uff0c\u5219\u53ef\u80fd\u9700\u8981\u8fdb\u884c\u4e00\u4e9b\u66f4\u6539\u3002\u5728\u4e0b\u4e00\u8282\u4e2d\uff0c\u6211\u5c06\u7b80\u8981\u4ecb\u7ecd\u60a8\u9700\u8981\u8fdb\u884c\u7684\u66f4\u6539\uff0c\u5e76\u89e3\u91ca\u4e3a\u4ec0\u4e48\u8fd9\u4e9b\u66f4\u6539\u662f\u5fc5\u9700\u7684\u3002<\/p>\n<h3>27.2.2 Preparing and publishing your application to IIS<\/h3>\n<p>27.2.2 \u51c6\u5907\u5e94\u7528\u7a0b\u5e8f\u5e76\u5c06\u5176\u53d1\u5e03\u5230 IIS<\/p>\n<p>As I discussed in section 27.1, IIS acts as a reverse proxy for your ASP.NET Core app. That means IIS needs to be able to communicate directly with your app to forward incoming requests to and outgoing responses from your app.<br \/>\n\u6b63\u5982\u6211\u5728 Section 27.1 \u4e2d\u6240\u8ba8\u8bba\u7684\uff0cIIS \u5145\u5f53 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u53cd\u5411\u4ee3\u7406\u3002\u8fd9\u610f\u5473\u7740 IIS \u9700\u8981\u80fd\u591f\u76f4\u63a5\u4e0e\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u901a\u4fe1\uff0c\u4ee5\u5c06\u4f20\u5165\u8bf7\u6c42\u8f6c\u53d1\u5230\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u4ee5\u53ca\u4ece\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u8f6c\u53d1\u4f20\u51fa\u54cd\u5e94\u3002<\/p>\n<p>IIS handles this with the ASP.NET Core Module, but a certain degree of negotiation is required between IIS and your app. For this to work correctly, you need to configure your app to use IIS integration.<br \/>\nIIS \u4f7f\u7528 ASP.NET \u6838\u5fc3\u6a21\u5757\u5904\u7406\u6b64\u95ee\u9898\uff0c\u4f46 IIS \u548c\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u4e4b\u95f4\u9700\u8981\u4e00\u5b9a\u7a0b\u5ea6\u7684\u534f\u5546\u3002\u8981\u4f7f\u5176\u6b63\u5e38\u5de5\u4f5c\uff0c\u60a8\u9700\u8981\u5c06\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e3a\u4f7f\u7528 IIS \u96c6\u6210\u3002<\/p>\n<p>IIS integration is added automatically when you use WebApplicationBuilder, so there\u2019s typically nothing more to do. However, in chapter 30 you\u2019ll learn about the generic host and how to create custom application builders using HostBuilder. If your app uses a customer application builder and you want to use IIS, you need to ensure that you add IIS integration with the UseIIS() or UseIISIntegration() extension methods:<br \/>\n\u5f53\u60a8\u4f7f\u7528 WebApplicationBuilder \u65f6\uff0c\u4f1a\u81ea\u52a8\u6dfb\u52a0 IIS \u96c6\u6210\uff0c\u56e0\u6b64\u901a\u5e38\u65e0\u9700\u6267\u884c\u66f4\u591a\u4f5c\u3002\u4f46\u662f\uff0c\u5728\u7b2c 30 \u7ae0\u4e2d\uff0c\u60a8\u5c06\u4e86\u89e3\u901a\u7528\u4e3b\u673a\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528 HostBuilder \u521b\u5efa\u81ea\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u6784\u5efa\u5668\u3002\u5982\u679c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u5ba2\u6237\u5e94\u7528\u7a0b\u5e8f\u6784\u5efa\u5668\uff0c\u5e76\u4e14\u60a8\u60f3\u8981\u4f7f\u7528 IIS\uff0c\u5219\u9700\u8981\u786e\u4fdd\u6dfb\u52a0\u4e0e UseIIS\uff08\uff09 \u6216 UseIISIntegration\uff08\uff09 \u6269\u5c55\u65b9\u6cd5\u7684 IIS \u96c6\u6210\uff1a<\/p>\n<p>\u2022  UseIIS() configures your application to support IIS with an in-process hosting model.<br \/>\nUseIIS\uff08\uff09 \u5c06\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e3a\u4f7f\u7528\u8fdb\u7a0b\u5185\u6258\u7ba1\u6a21\u578b\u652f\u6301 IIS\u3002<\/p>\n<p>\u2022  UseIISIntegration() configures your application to support IIS with an out-of-process hosting model.<br \/>\nUseIISIntegration\uff08\uff09 \u5c06\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e3a\u4f7f\u7528\u8fdb\u7a0b\u5916\u6258\u7ba1\u6a21\u578b\u652f\u6301 IIS\u3002<\/p>\n<p>These methods are automatically called by WebApplicationBuilder, but if you\u2019re not using your application with IIS, the UseIIS() and UseIISIntegration() methods will have no effect on your app, so it\u2019s safe to include them anyway.<br \/>\n\u8fd9\u4e9b\u65b9\u6cd5\u7531 WebApplicationBuilder \u81ea\u52a8\u8c03\u7528\uff0c\u4f46\u5982\u679c\u60a8\u672a\u5c06\u5e94\u7528\u7a0b\u5e8f\u4e0e IIS \u4e00\u8d77\u4f7f\u7528\uff0c\u5219 UseIIS\uff08\uff09 \u548c UseIISIntegration\uff08\uff09 \u65b9\u6cd5\u5c06\u5bf9\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u6ca1\u6709\u5f71\u54cd\uff0c\u56e0\u6b64\u65e0\u8bba\u5982\u4f55\u90fd\u5305\u542b\u5b83\u4eec\u662f\u5b89\u5168\u7684\u3002<\/p>\n<blockquote>\n<p>In-process vs. out-of-process hosting in IIS<br \/>\nIIS\u4e2d\u7684\u8fdb\u7a0b\u5185\u6258\u7ba1\u4e0e\u8fdb\u7a0b\u5916\u6258\u7ba1<\/p>\n<p>The common reverse-proxy description assumes that your application is running in a separate process from the reverse proxy itself. That is the case if you\u2019re running on Linux and was the default for IIS up until ASP.NET Core 3.0.<br \/>\n\u5e38\u89c1\u7684\u53cd\u5411\u4ee3\u7406\u63cf\u8ff0\u5047\u5b9a\u5e94\u7528\u7a0b\u5e8f\u5728\u4e0e\u53cd\u5411\u4ee3\u7406\u672c\u8eab\u4e0d\u540c\u7684\u8fdb\u7a0b\u4e2d\u8fd0\u884c\u3002\u5982\u679c\u60a8\u5728 Linux \u4e0a\u8fd0\u884c\uff0c\u5e76\u4e14\u5728 ASP.NET Core 3.0 \u4e4b\u524d\u662f IIS \u7684\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u5219\u4f1a\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u3002<\/p>\n<p>In ASP.NET Core 3.0, ASP.NET Core switched to using an in-process hosting model by default for applications deployed to IIS. In this model, IIS hosts your application directly inside the IIS process, reducing interprocess communication and boosting performance.<br \/>\n\u5728 ASP.NET Core 3.0 \u4e2d\uff0cASP.NET Core \u9ed8\u8ba4\u5207\u6362\u5230\u5bf9\u90e8\u7f72\u5230 IIS \u7684\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u8fdb\u7a0b\u5185\u6258\u7ba1\u6a21\u578b\u3002\u5728\u6b64\u6a21\u578b\u4e2d\uff0cIIS \u76f4\u63a5\u5728 IIS \u8fdb\u7a0b\u5185\u6258\u7ba1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ece\u800c\u51cf\u5c11\u8fdb\u7a0b\u95f4\u901a\u4fe1\u5e76\u63d0\u9ad8\u6027\u80fd\u3002<\/p>\n<p>You can switch to the out-of-process hosting model with IIS if you wish, which can sometimes be useful for troubleshooting problems. Rick Strahl has an excellent post on the differences between the hosting models, how to switch between them, and the advantages of each: \u201cASP.NET Core In Process Hosting on IIS with ASP.NET Core\u201d at <a href=\"http:\/\/mng.bz\/QmEv\">http:\/\/mng.bz\/QmEv<\/a>.<br \/>\n\u5982\u679c\u9700\u8981\uff0c\u53ef\u4ee5\u4f7f\u7528 IIS \u5207\u6362\u5230\u8fdb\u7a0b\u5916\u6258\u7ba1\u6a21\u578b\uff0c\u8fd9\u6709\u65f6\u53ef\u7528\u4e8e\u89e3\u51b3\u95ee\u9898\u3002Rick Strahl \u6709\u4e00\u7bc7\u5173\u4e8e\u6258\u7ba1\u6a21\u578b\u4e4b\u95f4\u7684\u5dee\u5f02\u3001\u5982\u4f55\u5728\u5b83\u4eec\u4e4b\u95f4\u5207\u6362\u4ee5\u53ca\u6bcf\u79cd\u6a21\u578b\u7684\u4f18\u70b9\u7684\u4f18\u79c0\u6587\u7ae0\uff1a<a href=\"http:\/\/mng.bz\/QmEv\">http:\/\/mng.bz\/QmEv<\/a> \u4e0a\u7684\u201c\u4f7f\u7528 ASP.NET Core \u5728 IIS \u4e0a\u8fdb\u884c ASP.NET Core In Process \u6258\u7ba1\u201d\u3002<\/p>\n<p>In general, you shouldn\u2019t need to worry about the differences between the hosting models, but it\u2019s something to be aware of if you\u2019re deploying to IIS. If you choose to use the out-of-process hosting model, you should use the UseIISIntegration() extension method. If you use the in-process model, use UseIIS(). Alternatively, play it safe and use both; the correct extension method is activated based on the hosting model used in production. Neither extension does anything if you don\u2019t use IIS.<br \/>\n\u901a\u5e38\uff0c\u60a8\u4e0d\u9700\u8981\u62c5\u5fc3\u6258\u7ba1\u6a21\u578b\u4e4b\u95f4\u7684\u5dee\u5f02\uff0c\u4f46\u5982\u679c\u60a8\u8981\u90e8\u7f72\u5230 IIS\uff0c\u5219\u9700\u8981\u6ce8\u610f\u8fd9\u4e00\u70b9\u3002\u5982\u679c\u60a8\u9009\u62e9\u4f7f\u7528\u8fdb\u7a0b\u5916\u6258\u7ba1\u6a21\u578b\uff0c\u5219\u5e94\u4f7f\u7528 UseIISIntegration\uff08\uff09 \u6269\u5c55\u65b9\u6cd5\u3002\u5982\u679c\u4f7f\u7528\u8fdb\u7a0b\u5185\u6a21\u578b\uff0c\u8bf7\u4f7f\u7528 UseIIS\uff08\uff09\u3002\u6216\u8005\uff0c\u5b89\u5168\u8d77\u89c1\uff0c\u4e24\u8005\u517c\u800c\u6709\u4e4b;\u6839\u636e\u751f\u4ea7\u4e2d\u4f7f\u7528\u7684\u6258\u7ba1\u6a21\u578b\u6fc0\u6d3b\u6b63\u786e\u7684\u6269\u5c55\u65b9\u6cd5\u3002\u5982\u679c\u60a8\u4e0d\u4f7f\u7528 IIS\uff0c\u5219\u4e24\u4e2a\u6269\u5c55\u90fd\u4e0d\u4f1a\u6267\u884c\u4efb\u4f55\u4f5c\u3002<\/p>\n<\/blockquote>\n<p>When running behind IIS, these extension methods configure your app to pair with IIS so that it can seamlessly accept requests. Among other things, the extensions do the following:<br \/>\n\u5728 IIS \u540e\u9762\u8fd0\u884c\u65f6\uff0c\u8fd9\u4e9b\u6269\u5c55\u65b9\u6cd5\u5c06\u4f60\u7684\u5e94\u7528\u914d\u7f6e\u4e3a\u4e0e IIS \u914d\u5bf9\uff0c\u4ee5\u4fbf\u5b83\u53ef\u4ee5\u65e0\u7f1d\u63a5\u53d7\u8bf7\u6c42\u3002\u6b64\u5916\uff0c\u6269\u5c55\u8fd8\u6267\u884c\u4ee5\u4e0b\u4f5c\uff1a<\/p>\n<p>\u2022  Define the URL that IIS uses to forward requests to your app and configures your app to listen on this URL<br \/>\n\u5b9a\u4e49 IIS \u7528\u4e8e\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u5e94\u7528\u7a0b\u5e8f\u7684 URL\uff0c\u5e76\u5c06\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e3a\u4fa6\u542c\u6b64 URL<\/p>\n<p>\u2022  Configure your app to interpret requests coming from IIS as coming from the client by setting up header forwarding<br \/>\n\u901a\u8fc7\u8bbe\u7f6e\u6807\u5934\u8f6c\u53d1\uff0c\u5c06\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e3a\u5c06\u6765\u81ea IIS \u7684\u8bf7\u6c42\u89e3\u91ca\u4e3a\u6765\u81ea\u5ba2\u6237\u7aef\u7684\u8bf7\u6c42<\/p>\n<p>\u2022  Enable Windows authentication if required<br \/>\n\u6839\u636e\u9700\u8981\u542f\u7528 Windows \u8eab\u4efd\u9a8c\u8bc1<\/p>\n<p>Adding the IIS extension methods is the only change you need to make to your application to host in IIS (and even then, only when using a custom application builder). But there\u2019s one additional aspect to be aware of when you publish your app. As with legacy .NET Framework ASP.NET, IIS relies on a web.config file to configure the applications it runs. It\u2019s important that your application include a web.config file when it\u2019s published to IIS; otherwise you could get broken behavior or even expose files that shouldn\u2019t be exposed.<br \/>\n\u6dfb\u52a0 IIS \u6269\u5c55\u65b9\u6cd5\u662f\u60a8\u9700\u8981\u5bf9\u8981\u5728 IIS \u4e2d\u6258\u7ba1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fdb\u884c\u7684\u552f\u4e00\u66f4\u6539\uff08\u5373\u4f7f\u8fd9\u6837\uff0c\u4e5f\u4ec5\u5728\u4f7f\u7528\u81ea\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u6784\u5efa\u5668\u65f6\uff09\u3002\u4f46\u662f\uff0c\u5728\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u8fd8\u6709\u4e00\u4e2a\u65b9\u9762\u9700\u8981\u6ce8\u610f\u3002\u4e0e\u65e7\u7248 .NET Framework ASP.NET \u4e00\u6837\uff0cIIS \u4f9d\u8d56\u4e8e web.config \u6587\u4ef6\u6765\u914d\u7f6e\u5b83\u8fd0\u884c\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u5e94\u7528\u7a0b\u5e8f\u5728\u53d1\u5e03\u5230 IIS \u65f6\u5fc5\u987b\u5305\u542b web.config \u6587\u4ef6;\u5426\u5219\uff0c\u60a8\u53ef\u80fd\u4f1a\u7834\u574f\u884c\u4e3a\uff0c\u751a\u81f3\u66b4\u9732\u4e0d\u5e94\u516c\u5f00\u7684\u6587\u4ef6\u3002<\/p>\n<p><b>TIP<\/b> For details on using web.config to customize the IIS AspNetCore Module, see Microsoft\u2019s \u201cASP.NET Core Module\u201d documentation: <a href=\"http:\/\/mng.bz\/Xdna\">http:\/\/mng.bz\/Xdna<\/a>.<br \/>\n\u63d0\u793a:\u6709\u5173\u4f7f\u7528 web.config \u81ea\u5b9a\u4e49 IIS AspNetCore \u6a21\u5757\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Microsoft \u7684\u201cASP.NET Core Module\u201d\u6587\u6863\uff1a<a href=\"http:\/\/mng.bz\/Xdna\">http:\/\/mng.bz\/Xdna<\/a>\u3002<\/p>\n<p>If your ASP.NET Core project already includes a web.config file, the .NET CLI or Visual Studio copies it to the publish directory when you publish your app. If your app doesn\u2019t include a web.config file, the publish command creates the correct one for you. If you don\u2019t need to customize the web.config file, it\u2019s generally best not to include one in your project and let the CLI create the correct file for you.<br \/>\n\u5982\u679c\u60a8\u7684 ASP.NET Core \u9879\u76ee\u5df2\u5305\u542b web.config \u6587\u4ef6\uff0c\u5219 .NET CLI \u6216 Visual Studio \u4f1a\u5728\u60a8\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u65f6\u5c06\u5176\u590d\u5236\u5230\u53d1\u5e03\u76ee\u5f55\u3002\u5982\u679c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e0d\u5305\u542b web.config \u6587\u4ef6\uff0c\u5219 publish \u547d\u4ee4\u5c06\u4e3a\u60a8\u521b\u5efa\u6b63\u786e\u7684\u6587\u4ef6\u3002\u5982\u679c\u60a8\u4e0d\u9700\u8981\u81ea\u5b9a\u4e49 web.config \u6587\u4ef6\uff0c\u901a\u5e38\u6700\u597d\u4e0d\u8981\u5728\u9879\u76ee\u4e2d\u5305\u542b\u4e00\u4e2a\u6587\u4ef6\uff0c\u5e76\u8ba9 CLI \u4e3a\u60a8\u521b\u5efa\u6b63\u786e\u7684\u6587\u4ef6\u3002<\/p>\n<p>With these changes, you\u2019re finally in a position to publish your application to IIS. Publish your ASP.NET Core app to a folder, either from Visual Studio or with the .NET CLI, by running<br \/>\n\u901a\u8fc7\u8fd9\u4e9b\u66f4\u6539\uff0c\u60a8\u7ec8\u4e8e\u53ef\u4ee5\u5c06\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230 IIS\u3002\u901a\u8fc7\u8fd0\u884c Visual Studio \u6216\u4f7f\u7528 .NET CLI \u5c06 ASP.NET Core \u5e94\u7528\u53d1\u5e03\u5230\u6587\u4ef6\u5939<\/p>\n<pre><code>dotnet publish --output publish_folder --configuration Release<\/code><\/pre>\n<p>This will publish your application to the publish_folder folder. You can then copy your application to the path specified in IIS, as shown in figure 27.6. At this point, if all has gone smoothly, you should be able to navigate to the URL you specified for your app (<a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a>, in my case) and see it running, as shown in figure 27.8.<br \/>\n\u8fd9\u4f1a\u5c06\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u53d1\u5e03\u5230 publish_folder \u6587\u4ef6\u5939\u3002\u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u5c06\u5e94\u7528\u7a0b\u5e8f\u590d\u5236\u5230 IIS \u4e2d\u6307\u5b9a\u7684\u8def\u5f84\uff0c\u5982\u56fe 27.6 \u6240\u793a\u3002\u6b64\u65f6\uff0c\u5982\u679c\u4e00\u5207\u987a\u5229\uff0c\u60a8\u5e94\u8be5\u80fd\u591f\u5bfc\u822a\u5230\u60a8\u4e3a\u5e94\u7528\u7a0b\u5e8f\u6307\u5b9a\u7684 URL\uff08\u5728\u672c\u4f8b\u4e2d\u4e3a <a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a> URL\uff09\u5e76\u770b\u5230\u5b83\u6b63\u5728\u8fd0\u884c\uff0c\u5982\u56fe 27.8 \u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2708.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.8 The published application, using IIS as a reverse proxy listening at the URL <a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a><br \/>\n\u56fe 27.8 \u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u4f7f\u7528 IIS \u4f5c\u4e3a\u53cd\u5411\u4ee3\u7406\u4fa6\u542c URL <a href=\"http:\/\/localhost:81\">http:\/\/localhost:81<\/a><\/p>\n<p>And there you have it\u2014your first application running behind a reverse proxy. Even though ASP.NET Core uses a different hosting model from previous versions of ASP.NET, the process of configuring IIS is similar.<br \/>\n\u8fd9\u5c31\u662f - \u5728\u53cd\u5411\u4ee3\u7406\u540e\u9762\u8fd0\u884c\u7684\u7b2c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u3002\u5c3d\u7ba1 ASP.NET Core \u4f7f\u7528\u7684\u6258\u7ba1\u6a21\u578b\u4e0e\u4ee5\u524d\u7248\u672c\u7684 ASP.NET \u4e0d\u540c\uff0c\u4f46\u914d\u7f6e IIS \u7684\u8fc7\u7a0b\u662f\u76f8\u4f3c\u7684\u3002<\/p>\n<p>As is often the case when it comes to deployment, the success you have is highly dependent on your precise environment and your app itself. If, after following these steps, you find that you can\u2019t get your application to start, I highly recommend checking out the documentation at <a href=\"http:\/\/mng.bz\/Zqom\">http:\/\/mng.bz\/Zqom<\/a>. This contains many troubleshooting steps to get you back on track if IIS decides to throw a hissy fit.<br \/>\n\u4e0e\u90e8\u7f72\u65f6\u7684\u60c5\u51b5\u4e00\u6837\uff0c\u60a8\u83b7\u5f97\u7684\u6210\u529f\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u53d6\u51b3\u4e8e\u60a8\u7684\u7cbe\u786e\u73af\u5883\u548c\u5e94\u7528\u7a0b\u5e8f\u672c\u8eab\u3002\u5982\u679c\u5728\u6267\u884c\u8fd9\u4e9b\u6b65\u9aa4\u540e\uff0c\u60a8\u53d1\u73b0\u65e0\u6cd5\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\uff0c\u6211\u5f3a\u70c8\u5efa\u8bae\u60a8\u67e5\u770b <a href=\"http:\/\/mng.bz\/Zqom\">http:\/\/mng.bz\/Zqom<\/a> \u4e0a\u7684\u6587\u6863\u3002\u8fd9\u5305\u542b\u8bb8\u591a\u6545\u969c\u6392\u9664\u6b65\u9aa4\uff0c\u4ee5\u4fbf\u5728 IIS \u51b3\u5b9a\u53d1\u51fa\u5636\u5636\u58f0\u65f6\u8ba9\u60a8\u56de\u5230\u6b63\u8f68\u3002<\/p>\n<p>This section was deliberately tailored to deploying to IIS, as it provides a great segue for developers who are used to deploying legacy ASP.NET apps and want to deploy their first ASP.NET Core app. But that\u2019s not to say that IIS is the only, or best, place to host your application.<br \/>\n\u672c\u90e8\u5206\u4e13\u4e3a\u90e8\u7f72\u5230 IIS \u800c\u5b9a\u5236\uff0c\u56e0\u4e3a\u5b83\u4e3a\u4e60\u60ef\u4e8e\u90e8\u7f72\u65e7\u7248 ASP.NET \u5e94\u7528\u5e76\u5e0c\u671b\u90e8\u7f72\u5176\u7b2c\u4e00\u4e2a ASP.NET Core \u5e94\u7528\u7684\u5f00\u53d1\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f88\u597d\u7684 segue\u3002\u4f46\u8fd9\u5e76\u4e0d\u662f\u8bf4 IIS \u662f\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f\u7684\u552f\u4e00\u6216\u6700\u4f73\u4f4d\u7f6e\u3002<\/p>\n<p>In the next section I provide a brief introduction to hosting your app on Linux, behind a reverse proxy like NGINX or Apache. I won\u2019t go into configuration of the reverse proxy itself, but I will provide an overview of things to consider and resources you can use to run your applications on Linux.<br \/>\n\u5728\u4e0b\u4e00\u8282\u4e2d\uff0c\u6211\u5c06\u7b80\u8981\u4ecb\u7ecd\u5982\u4f55\u5728 Linux \u4e0a\u6258\u7ba1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u5728 NGINX \u6216 Apache \u7b49\u53cd\u5411\u4ee3\u7406\u540e\u9762\u3002\u6211\u4e0d\u4f1a\u4ecb\u7ecd\u53cd\u5411\u4ee3\u7406\u672c\u8eab\u7684\u914d\u7f6e\uff0c\u4f46\u6211\u5c06\u6982\u8ff0\u9700\u8981\u8003\u8651\u7684\u4e8b\u9879\u4ee5\u53ca\u53ef\u7528\u4e8e\u5728 Linux \u4e0a\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\u8d44\u6e90\u3002<\/p>\n<h2>27.3 Hosting an application in Linux<\/h2>\n<p>27.3 \u5728 Linux \u4e2d\u6258\u7ba1\u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>One of the great new features in ASP.NET Core is the ability to develop and deploy applications cross-platform, whether on Windows, Linux, or macOS. The ability to run on Linux in particular opens the possibility of cheaper deployments to cloud hosting, deploying to small devices like a Raspberry Pi or to Docker containers.<br \/>\nASP.NET Core \u4e2d\u7684\u4e00\u9879\u51fa\u8272\u7684\u65b0\u529f\u80fd\u662f\u80fd\u591f\u8de8\u5e73\u53f0\u5f00\u53d1\u548c\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\uff0c\u65e0\u8bba\u662f\u5728 Windows\u3001Linux \u8fd8\u662f macOS \u4e0a\u3002\u7279\u522b\u662f\u5728 Linux \u4e0a\u8fd0\u884c\u7684\u80fd\u529b\u4e3a\u4ee5\u66f4\u4fbf\u5b9c\u7684\u4ef7\u683c\u90e8\u7f72\u5230\u4e91\u6258\u7ba1\u3001\u90e8\u7f72\u5230 Raspberry Pi \u7b49\u5c0f\u578b\u8bbe\u5907\u6216 Docker \u5bb9\u5668\u63d0\u4f9b\u4e86\u53ef\u80fd\u6027\u3002<\/p>\n<p>One of the characteristics of Linux is that it\u2019s almost infinitely configurable. Although that\u2019s definitely a feature, it can also be extremely daunting, especially if you\u2019re coming from the Windows world of wizards and GUIs. This section provides an overview of what it takes to run an application on Linux. It focuses on the broad steps you need to take rather than the somewhat-tedious details of the configuration itself. Instead, I point to resources you can refer to as necessary.<br \/>\nLinux \u7684\u4e00\u4e2a\u7279\u70b9\u662f\u5b83\u51e0\u4e4e\u53ef\u4ee5\u65e0\u9650\u914d\u7f6e\u3002\u867d\u7136\u8fd9\u7edd\u5bf9\u662f\u4e00\u4e2a\u529f\u80fd\uff0c\u4f46\u5b83\u4e5f\u53ef\u80fd\u975e\u5e38\u4ee4\u4eba\u751f\u754f\uff0c\u7279\u522b\u662f\u5982\u679c\u60a8\u6765\u81ea\u5411\u5bfc\u548c GUI \u7684 Windows \u4e16\u754c\u3002\u672c\u8282\u6982\u8ff0\u4e86\u5728 Linux \u4e0a\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u6761\u4ef6\u3002\u5b83\u4fa7\u91cd\u4e8e\u60a8\u9700\u8981\u91c7\u53d6\u7684\u5e7f\u6cdb\u6b65\u9aa4\uff0c\u800c\u4e0d\u662f\u914d\u7f6e\u672c\u8eab\u7684\u6709\u70b9\u4e4f\u5473\u7684\u7ec6\u8282\u3002\u76f8\u53cd\uff0c\u6211\u6307\u51fa\u4e86\u60a8\u53ef\u4ee5\u6839\u636e\u9700\u8981\u53c2\u8003\u7684\u8d44\u6e90\u3002<\/p>\n<h3>27.3.1 Running an ASP.NET Core app behind a reverse proxy in Linux<\/h3>\n<p>27.3.1 \u5728 Linux \u4e2d\u7684\u53cd\u5411\u4ee3\u7406\u540e\u9762\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>You\u2019ll be glad to hear that running your application on Linux is broadly the same as running your application on Windows with IIS:<br \/>\n\u60a8\u4f1a\u5f88\u9ad8\u5174\u5730\u542c\u5230\uff0c\u5728 Linux \u4e0a\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u4e0e\u4f7f\u7528 IIS \u5728 Windows \u4e0a\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u5927\u81f4\u76f8\u540c\uff1a<\/p>\n<ol>\n<li>\n<p>Publish your app using dotnet publish. If you\u2019re creating an RDD, the output is the same as you\u2019d use with IIS. For an SCD, you must provide the runtime identifier, as described in section 27.1.1.<br \/>\n\u4f7f\u7528 dotnet publish \u53d1\u5e03\u5e94\u7528\u3002\u5982\u679c\u8981\u521b\u5efa RDD\uff0c\u5219\u8f93\u51fa\u4e0e\u7528\u4e8e IIS \u7684\u8f93\u51fa\u76f8\u540c\u3002\u5bf9\u4e8e SCD\uff0c\u60a8\u5fc5\u987b\u63d0\u4f9b\u8fd0\u884c\u65f6\u6807\u8bc6\u7b26\uff0c\u5982\u7b2c 27.1.1 \u8282\u4e2d\u6240\u8ff0\u3002<\/p>\n<\/li>\n<li>\n<p>Install the necessary prerequisites on the server. For an RDD deployment, you must install the .NET 7 Runtime and the necessary prerequisites. You can find details on this in Microsoft\u2019s \u201cInstall .NET on Linux\u201d documentation at <a href=\"http:\/\/mng.bz\/Rxlj\">http:\/\/mng.bz\/Rxlj<\/a>.<br \/>\n\u5728\u670d\u52a1\u5668\u4e0a\u5b89\u88c5\u5fc5\u8981\u7684\u5148\u51b3\u6761\u4ef6\u3002\u5bf9\u4e8e RDD \u90e8\u7f72\uff0c\u60a8\u5fc5\u987b\u5b89\u88c5 .NET 7 \u8fd0\u884c\u65f6\u548c\u5fc5\u8981\u7684\u5148\u51b3\u6761\u4ef6\u3002\u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/Rxlj\">http:\/\/mng.bz\/Rxlj<\/a> \u7684 Microsoft \u7684\u201c\u5728 Linux \u4e0a\u5b89\u88c5 .NET\u201d\u6587\u6863\u4e2d\u627e\u5230\u6709\u5173\u6b64\u5185\u5bb9\u7684\u8be6\u7ec6\u4fe1\u606f\u3002<\/p>\n<\/li>\n<li>\n<p>Copy your app to the server. You can use any mechanism you like: FTP, USB stick, or whatever you need to get your files onto the server!<br \/>\n\u5c06\u60a8\u7684\u5e94\u7528\u590d\u5236\u5230\u670d\u52a1\u5668\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528\u4efb\u4f55\u60a8\u559c\u6b22\u7684\u673a\u5236\uff1aFTP\u3001U \u76d8\u6216\u4efb\u4f55\u60a8\u9700\u8981\u5c06\u6587\u4ef6\u653e\u5230\u670d\u52a1\u5668\u4e0a\u7684\u673a\u5236\uff01<\/p>\n<\/li>\n<li>\n<p>Configure a reverse proxy, and point it to your app. As you know by now, you may want to run your app behind a reverse proxy, for the reasons described in section 27.1. In Windows you\u2019d use IIS, but in Linux you have more options. NGINX, Apache, and HAProxy are commonly used options. The ASP.NET Core-based YARP is also an option (<a href=\"https:\/\/microsoft.github.io\/reverse-proxy\">https:\/\/microsoft.github.io\/reverse-proxy<\/a>). Alternatively, go without, and expose your app directly to the network.<br \/>\n\u914d\u7f6e\u53cd\u5411\u4ee3\u7406\uff0c\u5e76\u5c06\u5176\u6307\u5411\u60a8\u7684\u5e94\u7528\u3002\u6b63\u5982\u60a8\u73b0\u5728\u6240\u77e5\uff0c\u51fa\u4e8e\u7b2c 27.1 \u8282\u4e2d\u63cf\u8ff0\u7684\u539f\u56e0\uff0c\u60a8\u53ef\u80fd\u5e0c\u671b\u5728\u53cd\u5411\u4ee3\u7406\u540e\u9762\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u5728 Windows \u4e2d\uff0c\u60a8\u5c06\u4f7f\u7528 IIS\uff0c\u4f46\u5728 Linux \u4e2d\uff0c\u60a8\u6709\u66f4\u591a\u9009\u62e9\u3002NGINX\u3001Apache \u548c HAProxy \u662f\u5e38\u7528\u7684\u9009\u9879\u3002\u57fa\u4e8e ASP.NET Core \u7684 YARP \u4e5f\u662f\u4e00\u4e2a\u9009\u9879 \uff08<a href=\"https:\/\/microsoft.github.io\/reverse-proxy\uff09\u3002\u6216\u8005\uff0c\u4e0d\u8fd9\u6837\u505a\uff0c\u76f4\u63a5\u5c06\u4f60\u7684\u5e94\u7528\u516c\u5f00\u7ed9\u7f51\u7edc\">https:\/\/microsoft.github.io\/reverse-proxy\uff09\u3002\u6216\u8005\uff0c\u4e0d\u8fd9\u6837\u505a\uff0c\u76f4\u63a5\u5c06\u4f60\u7684\u5e94\u7528\u516c\u5f00\u7ed9\u7f51\u7edc<\/a>\u3002<\/p>\n<\/li>\n<li>\n<p>Configure a process-management tool for your app. In Windows, IIS acts as both a reverse proxy and a process manager, restarting your app if it crashes or stops responding. In Linux, you typically need to configure a separate process manager to handle these duties; the reverse proxies won\u2019t do them for you.<br \/>\n\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u8fdb\u7a0b\u7ba1\u7406\u5de5\u5177\u3002\u5728 Windows \u4e2d\uff0cIIS \u65e2\u5145\u5f53\u53cd\u5411\u4ee3\u7406\u53c8\u5145\u5f53\u8fdb\u7a0b\u7ba1\u7406\u5668\uff0c\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\u6216\u505c\u6b62\u54cd\u5e94\uff0c\u5219\u4f1a\u91cd\u65b0\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002\u5728 Linux \u4e2d\uff0c\u901a\u5e38\u9700\u8981\u914d\u7f6e\u5355\u72ec\u7684\u8fdb\u7a0b\u7ba1\u7406\u5668\u6765\u5904\u7406\u8fd9\u4e9b\u4efb\u52a1;\u53cd\u5411\u4ee3\u7406\u4e0d\u4f1a\u4e3a\u60a8\u505a\u8fd9\u4e9b\u4e8b\u60c5\u3002<\/p>\n<\/li>\n<\/ol>\n<p>The first three steps are generally the same, whether you\u2019re running in Windows with IIS or in Linux, but the last two steps are more interesting. By contrast with the monolithic IIS, Linux has a philosophy of small applications, each with a single responsibility.<br \/>\n\u65e0\u8bba\u60a8\u662f\u5728\u5e26\u6709 IIS \u7684 Windows \u4e2d\u8fd0\u884c\uff0c\u8fd8\u662f\u5728 Linux \u4e2d\u8fd0\u884c\uff0c\u524d\u4e09\u4e2a\u6b65\u9aa4\u901a\u5e38\u662f\u76f8\u540c\u7684\uff0c\u4f46\u6700\u540e\u4e24\u4e2a\u6b65\u9aa4\u66f4\u6709\u8da3\u3002\u4e0e\u6574\u4f53\u5f0f IIS \u76f8\u6bd4\uff0cLinux \u7684\u7406\u5ff5\u662f\u5c0f\u578b\u5e94\u7528\u7a0b\u5e8f\uff0c\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u90fd\u6709\u5355\u4e00\u7684\u8d23\u4efb\u3002<\/p>\n<p>IIS runs on the same server as your app and takes on multiple duties\u2014proxying traffic from the internet to your app, but also monitoring the app process itself. If your app crashes or stops responding, IIS restarts the process to ensure that you can keep handling requests.<br \/>\nIIS \u4e0e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c\u5728\u540c\u4e00\u53f0\u670d\u52a1\u5668\u4e0a\uff0c\u5e76\u627f\u62c5\u591a\u9879\u4efb\u52a1 \u2014 \u5c06\u6d41\u91cf\u4ece Internet \u4ee3\u7406\u5230\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u540c\u65f6\u8fd8\u8981\u76d1\u63a7\u5e94\u7528\u7a0b\u5e8f\u8fdb\u7a0b\u672c\u8eab\u3002\u5982\u679c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\u6216\u505c\u6b62\u54cd\u5e94\uff0cIIS \u5c06\u91cd\u65b0\u542f\u52a8\u8be5\u8fc7\u7a0b\u4ee5\u786e\u4fdd\u60a8\u53ef\u4ee5\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42\u3002<\/p>\n<p>In Linux, the reverse proxy might be running on the same server as your app, but it\u2019s also common for it to be running on a different server, as shown in figure 27.9. This is similarly true if you choose to deploy your app to Docker; your app would typically be deployed in a container without a reverse proxy, and a reverse proxy on a server would point to your Docker container.<br \/>\n\u5728 Linux \u4e2d\uff0c\u53cd\u5411\u4ee3\u7406\u53ef\u80fd\u4e0e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c\u5728\u540c\u4e00\u53f0\u670d\u52a1\u5668\u4e0a\uff0c\u4f46\u5b83\u5728\u4e0d\u540c\u7684\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u4e5f\u5f88\u5e38\u89c1\uff0c\u5982\u56fe 27.9 \u6240\u793a\u3002\u5982\u679c\u60a8\u9009\u62e9\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230 Docker\uff0c\u5219\u60c5\u51b5\u7c7b\u4f3c;\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u901a\u5e38\u4f1a\u90e8\u7f72\u5728\u6ca1\u6709\u53cd\u5411\u4ee3\u7406\u7684\u5bb9\u5668\u4e2d\uff0c\u800c\u670d\u52a1\u5668\u4e0a\u7684\u53cd\u5411\u4ee3\u7406\u5c06\u6307\u5411\u60a8\u7684 Docker \u5bb9\u5668\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2709.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.9 In Linux, it\u2019s common for a reverse proxy to be on a different server from your app. The reverse proxy forwards incoming requests to your app, while a process manager, such as systemd, monitors your apps for crashes and restarts it as appropriate.<br \/>\n\u56fe 27.9 \u5728 Linux \u4e2d\uff0c\u53cd\u5411\u4ee3\u7406\u4e0e\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u4f4d\u4e8e\u4e0d\u540c\u7684\u670d\u52a1\u5668\u4e0a\u662f\u5f88\u5e38\u89c1\u7684\u3002\u53cd\u5411\u4ee3\u7406\u5c06\u4f20\u5165\u8bf7\u6c42\u8f6c\u53d1\u5230\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u800c\u8fdb\u7a0b\u7ba1\u7406\u5668\uff08\u5982 systemd\uff09\u4f1a\u76d1\u63a7\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u662f\u5426\u5d29\u6e83\u5e76\u6839\u636e\u9700\u8981\u91cd\u65b0\u542f\u52a8\u5b83\u3002<\/p>\n<p>As the reverse proxies aren\u2019t necessarily on the same server as your app, they can\u2019t be used to restart your app if it crashes. Instead, you need to use a process manager such as systemd to monitor your app. If you\u2019re using Docker, you typically use a container orchestrator such as Kubernetes (<a href=\"https:\/\/kubernetes.io\">https:\/\/kubernetes.io<\/a>) to monitor the health of your containers.<br \/>\n\u7531\u4e8e\u53cd\u5411\u4ee3\u7406\u4e0d\u4e00\u5b9a\u4e0e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4f4d\u4e8e\u540c\u4e00\u670d\u52a1\u5668\u4e0a\uff0c\u56e0\u6b64\u5982\u679c\u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff0c\u5b83\u4eec\u4e0d\u80fd\u7528\u4e8e\u91cd\u65b0\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002\u76f8\u53cd\uff0c\u60a8\u9700\u8981\u4f7f\u7528\u8fdb\u7a0b\u7ba1\u7406\u5668\uff08\u5982 systemd\uff09\u6765\u76d1\u63a7\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f Docker\uff0c\u5219\u901a\u5e38\u4f7f\u7528 Kubernetes \uff08<a href=\"https:\/\/kubernetes.io\">https:\/\/kubernetes.io<\/a>\uff09 \u7b49\u5bb9\u5668\u7f16\u6392\u5668\u6765\u76d1\u63a7\u5bb9\u5668\u7684\u8fd0\u884c\u72b6\u51b5\u3002<\/p>\n<blockquote>\n<p>Running ASP.NET Core applications in Docker<br \/>\n\u5728 Docker\u4e2d\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/p>\n<p>Docker is the most commonly used engine for containerizing your applications. A container is like a small, lightweight virtual machine, specific to your app. It contains an operating system, your app, and any dependencies for your app. This container can then be run on any machine that runs Docker, and your app will run exactly the same, regardless of the host operating system and what\u2019s installed on it. This makes deployments highly repeatable: you can be confident that if the container runs on your machine, it will run on the server too.<br \/>\nDocker \u662f\u5bb9\u5668\u5316\u5e94\u7528\u7a0b\u5e8f\u6700\u5e38\u7528\u7684\u5f15\u64ce\u3002\u5bb9\u5668\u7c7b\u4f3c\u4e8e\u7279\u5b9a\u4e8e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5c0f\u578b\u8f7b\u91cf\u7ea7\u865a\u62df\u673a\u3002\u5b83\u5305\u542b\u4f5c\u7cfb\u7edf\u3001\u5e94\u7528\u7a0b\u5e8f\u4ee5\u53ca\u5e94\u7528\u7a0b\u5e8f\u7684\u4efb\u4f55\u4f9d\u8d56\u9879\u3002\u7136\u540e\uff0c\u6b64\u5bb9\u5668\u53ef\u4ee5\u5728\u4efb\u4f55\u8fd0\u884c Docker \u7684\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\uff0c\u5e76\u4e14\u65e0\u8bba\u4e3b\u673a\u4f5c\u7cfb\u7edf\u53ca\u5176\u4e0a\u5b89\u88c5\u7684\u5185\u5bb9\u5982\u4f55\uff0c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u90fd\u5c06\u4ee5\u5b8c\u5168\u76f8\u540c\u7684\u65b9\u5f0f\u8fd0\u884c\u3002\u8fd9\u4f7f\u5f97\u90e8\u7f72\u5177\u6709\u9ad8\u5ea6\u7684\u53ef\u91cd\u590d\u6027\uff1a\u60a8\u53ef\u4ee5\u786e\u4fe1\uff0c\u5982\u679c\u5bb9\u5668\u5728\u60a8\u7684\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\uff0c\u5b83\u4e5f\u5c06\u5728\u670d\u52a1\u5668\u4e0a\u8fd0\u884c\u3002<\/p>\n<p>All the major cloud vendors have support for running containers, either standalone or as part of an orchestration service. For example, in Azure, you can run containers in Azure App Service, Azure Container Instances, Azure Container Apps, and Azure Kubernetes Service. One advantage of containers is that you can easily use the same container in all these services or even move to a different cloud provider, and your app will run the same.<br \/>\n\u6240\u6709\u4e3b\u8981\u7684\u4e91\u4f9b\u5e94\u5546\u90fd\u652f\u6301\u8fd0\u884c\u5bb9\u5668\uff0c\u65e0\u8bba\u662f\u72ec\u7acb\u7684\u8fd8\u662f\u4f5c\u4e3a\u7f16\u6392\u670d\u52a1\u7684\u4e00\u90e8\u5206\u3002\u4f8b\u5982\uff0c\u5728 Azure \u4e2d\uff0c\u53ef\u4ee5\u5728 Azure \u5e94\u7528\u670d\u52a1\u3001Azure \u5bb9\u5668\u5b9e\u4f8b\u3001Azure \u5bb9\u5668\u5e94\u7528\u548c Azure Kubernetes \u670d\u52a1\u4e2d\u8fd0\u884c\u5bb9\u5668\u3002\u5bb9\u5668\u7684\u4e00\u4e2a\u4f18\u70b9\u662f\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728\u6240\u6709\u8fd9\u4e9b\u670d\u52a1\u4e2d\u4f7f\u7528\u76f8\u540c\u7684\u5bb9\u5668\uff0c\u751a\u81f3\u53ef\u4ee5\u8fc1\u79fb\u5230\u4e0d\u540c\u7684\u4e91\u63d0\u4f9b\u5546\uff0c\u5e76\u4e14\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5c06\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u8fd0\u884c\u3002<\/p>\n<p>ASP.NET Core is well suited to container deployments, but moving to Docker involves a big shift in your deployment methodology and may or may not be right for you and your apps. If you\u2019re interested in the possibilities afforded by Docker and want to learn more, I suggest checking out the following resources:<br \/>\nASP.NET Core \u975e\u5e38\u9002\u5408\u5bb9\u5668\u90e8\u7f72\uff0c\u4f46\u8fc1\u79fb\u5230 Docker \u6d89\u53ca\u90e8\u7f72\u65b9\u6cd5\u7684\u91cd\u5927\u8f6c\u53d8\uff0c\u5e76\u4e14\u53ef\u80fd\u9002\u5408\u4e5f\u53ef\u80fd\u4e0d\u9002\u5408\u60a8\u548c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u5982\u679c\u60a8\u5bf9 Docker \u63d0\u4f9b\u7684\u53ef\u80fd\u6027\u611f\u5174\u8da3\u5e76\u60f3\u4e86\u89e3\u66f4\u591a\u4fe1\u606f\uff0c\u6211\u5efa\u8bae\u60a8\u67e5\u770b\u4ee5\u4e0b\u8d44\u6e90\uff1a<\/p>\n<\/blockquote>\n<p>\u2022  Docker in Practice, 2nd ed., by Ian Miell and Aidan Hobson Sayers (Manning, 2019) provides a vast array of practical techniques to help you get the most out of Docker (<a href=\"http:\/\/mng.bz\/nM8d\">http:\/\/mng.bz\/nM8d<\/a>).<br \/>\nDocker in Practice\uff0c\u7b2c 2 \u7248\uff0c\u7531 Ian Miell \u548c Aidan Hobson Sayers \u7f16\u5199\uff08Manning\uff0c2019 \u5e74\uff09\uff0c\u63d0\u4f9b\u4e86\u5927\u91cf\u5b9e\u7528\u6280\u672f\u6765\u5e2e\u52a9\u60a8\u5145\u5206\u5229\u7528 Docker \uff08<a href=\"http:\/\/mng.bz\/nM8d\">http:\/\/mng.bz\/nM8d<\/a>\uff09\u3002<\/p>\n<p>\u2022  Even if you\u2019re not deploying to Linux, you can use Docker with Docker for Windows. Check out the free e-book Introduction to Windows Containers, by John McCabe and Michael Friis (Microsoft Press, 2017), at <a href=\"https:\/\/aka.ms\/containersebook\">https:\/\/aka.ms\/containersebook<\/a>.<br \/>\n\u5373\u4f7f\u60a8\u6ca1\u6709\u90e8\u7f72\u5230 Linux\uff0c\u4e5f\u53ef\u4ee5\u5c06 Docker \u4e0e\u9002\u7528\u4e8e Windows \u7684 Docker \u7ed3\u5408\u4f7f\u7528\u3002\u67e5\u770b John McCabe \u548c Michael Friis \u5408\u8457\u7684\u514d\u8d39\u7535\u5b50\u4e66 Introduction to Windows Containers\uff08Microsoft\u51fa\u7248\u793e\uff0c2017 \u5e74\uff09\uff0c\u7f51\u5740\u4e3a <a href=\"https:\/\/aka.ms\/containersebook\">https:\/\/aka.ms\/containersebook<\/a>\u3002<\/p>\n<p>\u2022  You can find a lot of details on building and running your ASP.NET Core applications on Docker in the .NET documentation at <a href=\"http:\/\/mng.bz\/vz5a\">http:\/\/mng.bz\/vz5a<\/a>.<br \/>\n\u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/vz5a\">http:\/\/mng.bz\/vz5a<\/a> \u7684 .NET \u6587\u6863\u4e2d\u627e\u5230\u6709\u5173\u5728 Docker \u4e0a\u6784\u5efa\u548c\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u8bb8\u591a\u8be6\u7ec6\u4fe1\u606f\u3002<\/p>\n<p>\u2022  Steve Gordon has an excellent blog post series on Docker for ASP.NET Core developers at <a href=\"http:\/\/mng.bz\/2Da8\">http:\/\/mng.bz\/2Da8<\/a>.<br \/>\nSteve Gordon \u5728 <a href=\"http:\/\/mng.bz\/2Da8\">http:\/\/mng.bz\/2Da8<\/a> \u4e0a\u4e3a ASP.NET Core \u5f00\u53d1\u4eba\u5458\u64b0\u5199\u4e86\u4e00\u7bc7\u5173\u4e8e Docker \u7684\u4f18\u79c0\u535a\u5ba2\u6587\u7ae0\u7cfb\u5217\u3002<\/p>\n<p>Configuring a reverse proxy and process manager on Linux is a laborious task that makes for dry reading, so I won\u2019t detail it here. Instead, I recommend checking out the ASP.NET Core docs. They have a guide for NGINX and systemd, \u201cHost ASP.NET Core on Linux with Nginx\u201d (<a href=\"http:\/\/mng.bz\/yYGd\">http:\/\/mng.bz\/yYGd<\/a>), and a guide for configuring Apache with systemd, \u201cHost ASP.NET Core on Linux with Apache\u201d (<a href=\"http:\/\/mng.bz\/MXVB\">http:\/\/mng.bz\/MXVB<\/a>).<br \/>\n\u5728 Linux \u4e0a\u914d\u7f6e\u53cd\u5411\u4ee3\u7406\u548c\u8fdb\u7a0b\u7ba1\u7406\u5668\u662f\u4e00\u9879\u8d39\u529b\u7684\u4efb\u52a1\uff0c\u56e0\u6b64\u4f1a\u67af\u71e5\u9605\u8bfb\uff0c\u56e0\u6b64\u6211\u4e0d\u4f1a\u5728\u8fd9\u91cc\u8be6\u7ec6\u8bf4\u660e\u3002\u76f8\u53cd\uff0c\u6211\u5efa\u8bae\u67e5\u770b ASP.NET Core \u6587\u6863\u3002\u4ed6\u4eec\u6709 NGINX \u548c systemd \u6307\u5357\u201c\u4f7f\u7528 Nginx \u5728 Linux \u4e0a\u6258\u7ba1 ASP.NET Core\u201d\uff08<a href=\"http:\/\/mng.bz\/yYGd\uff09\uff0c\u4ee5\u53ca\u4f7f\u7528\">http:\/\/mng.bz\/yYGd\uff09\uff0c\u4ee5\u53ca\u4f7f\u7528<\/a> systemd \u914d\u7f6e Apache \u7684\u6307\u5357\u201c\u4f7f\u7528 Apache \u5728 Linux \u4e0a\u6258\u7ba1 ASP.NET Core\u201d\uff08<a href=\"http:\/\/mng.bz\/MXVB\">http:\/\/mng.bz\/MXVB<\/a>\uff09\u3002<\/p>\n<p>Both guides cover the basic configuration of the respective reverse proxies and systemd supervisors, but more important, they also show how to configure them securely. The reverse proxy sits between your app and the unfettered internet, so it\u2019s important to get it right!<br \/>\n\u8fd9\u4e24\u4e2a\u6307\u5357\u90fd\u6db5\u76d6\u4e86\u76f8\u5e94\u7684\u53cd\u5411\u4ee3\u7406\u548c systemd \u76d1\u63a7\u5668\u7684\u57fa\u672c\u914d\u7f6e\uff0c\u4f46\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u4eec\u8fd8\u5c55\u793a\u4e86\u5982\u4f55\u5b89\u5168\u5730\u914d\u7f6e\u5b83\u4eec\u3002\u53cd\u5411\u4ee3\u7406\u4f4d\u4e8e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u548c\u4e0d\u53d7\u9650\u5236\u7684\u4e92\u8054\u7f51\u4e4b\u95f4\uff0c\u56e0\u6b64\u6b63\u786e\u4f7f\u7528\u5f88\u91cd\u8981\uff01<\/p>\n<p>Configuring the reverse proxy and the process manager is typically the most complex part of deploying to Linux, and that isn\u2019t specific to .NET development: the same would be true if you were deploying a Node.js web app. But you need to consider a few things inside your application when you\u2019re going to be deploying to Linux, as you\u2019ll see in the next section.<br \/>\n\u914d\u7f6e\u53cd\u5411\u4ee3\u7406\u548c\u8fdb\u7a0b\u7ba1\u7406\u5668\u901a\u5e38\u662f\u90e8\u7f72\u5230 Linux \u7684\u6700\u590d\u6742\u7684\u90e8\u5206\uff0c\u8fd9\u5e76\u975e\u7279\u5b9a\u4e8e .NET \u5f00\u53d1\uff1a\u5982\u679c\u8981\u90e8\u7f72 Node.js Web \u5e94\u7528\u7a0b\u5e8f\uff0c\u60c5\u51b5\u4e5f\u662f\u5982\u6b64\u3002\u4f46\u662f\uff0c\u5f53\u60a8\u8981\u90e8\u7f72\u5230 Linux \u65f6\uff0c\u60a8\u9700\u8981\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8003\u8651\u4e00\u4e9b\u4e8b\u9879\uff0c\u60a8\u5c06\u5728\u4e0b\u4e00\u8282\u4e2d\u770b\u5230\u3002<\/p>\n<h3>27.3.2 Preparing your app for deployment to Linux<\/h3>\n<p>27.3.2 \u51c6\u5907\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230 Linux<\/p>\n<p>Generally speaking, your app doesn\u2019t care which reverse proxy it sits behind, whether it\u2019s NGINX, Apache, or IIS; your app receives requests and responds to them without the reverse proxy affecting things. When you\u2019re hosting behind IIS, you need UseIISIntegration() to tell your app about IIS\u2019s configuration; when you\u2019re hosting on Linux, you need a similar method.<br \/>\n\u4e00\u822c\u6765\u8bf4\uff0c\u4f60\u7684\u5e94\u7528\u5e76\u4e0d\u5173\u5fc3\u5b83\u4f4d\u4e8e\u54ea\u4e2a\u53cd\u5411\u4ee3\u7406\u540e\u9762\uff0c\u65e0\u8bba\u662f NGINX\u3001Apache \u8fd8\u662f IIS;\u4f60\u7684\u5e94\u7528\u63a5\u6536\u8bf7\u6c42\u5e76\u54cd\u5e94\u8fd9\u4e9b\u8bf7\u6c42\uff0c\u800c\u53cd\u5411\u4ee3\u7406\u4e0d\u4f1a\u5f71\u54cd\u4e8b\u60c5\u3002\u5f53\u60a8\u5728 IIS \u540e\u9762\u6258\u7ba1\u65f6\uff0c\u60a8\u9700\u8981 UseIISIntegration\uff08\uff09 \u6765\u544a\u77e5\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f IIS \u7684\u914d\u7f6e;\u5f53\u60a8\u5728 Linux \u4e0a\u6258\u7ba1\u65f6\uff0c\u60a8\u9700\u8981\u7c7b\u4f3c\u7684\u65b9\u6cd5\u3002<\/p>\n<p>When a request arrives at the reverse proxy, it contains some information that is lost after the request is forwarded to your app. For example, the original request comes with the IP address of the client\/browser connecting to your app; once the request is forwarded from the reverse proxy, the IP address is that of the reverse proxy, not the browser. Also, if the reverse proxy is used for SSL\/TLS offloading (see chapter 28), then a request that was originally made using HTTPS may arrive at your app as an HTTP request.<br \/>\n\u5f53\u8bf7\u6c42\u5230\u8fbe\u53cd\u5411\u4ee3\u7406\u65f6\uff0c\u5b83\u5305\u542b\u4e00\u4e9b\u5728\u8bf7\u6c42\u8f6c\u53d1\u5230\u60a8\u7684\u5e94\u7528\u540e\u4e22\u5931\u7684\u4fe1\u606f\u3002\u4f8b\u5982\uff0c\u539f\u59cb\u8bf7\u6c42\u9644\u5e26\u8fde\u63a5\u5230\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u5ba2\u6237\u7aef\/\u6d4f\u89c8\u5668\u7684 IP \u5730\u5740;\u4ece\u53cd\u5411\u4ee3\u7406\u8f6c\u53d1\u8bf7\u6c42\u540e\uff0cIP \u5730\u5740\u662f\u53cd\u5411\u4ee3\u7406\u7684 IP \u5730\u5740\uff0c\u800c\u4e0d\u662f\u6d4f\u89c8\u5668\u7684 IP \u5730\u5740\u3002\u6b64\u5916\uff0c\u5982\u679c\u53cd\u5411\u4ee3\u7406\u7528\u4e8e SSL\/TLS \u5378\u8f7d\uff08\u53c2\u89c1\u7b2c 28 \u7ae0\uff09\uff0c\u90a3\u4e48\u6700\u521d\u4f7f\u7528 HTTPS \u53d1\u51fa\u7684\u8bf7\u6c42\u53ef\u80fd\u4f1a\u4f5c\u4e3a HTTP \u8bf7\u6c42\u5230\u8fbe\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>The standard solution to these problems is for the reverse proxy to add more headers before forwarding requests to your app. For example, the X-Forwarded-For header identifies the original client\u2019s IP address, whereas the X-Forwarded-Proto header indicates the original scheme of the request (http or https).<br \/>\n\u8fd9\u4e9b\u95ee\u9898\u7684\u6807\u51c6\u89e3\u51b3\u65b9\u6848\u662f\u8ba9\u53cd\u5411\u4ee3\u7406\u5728\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\u6dfb\u52a0\u66f4\u591a\u6807\u5934\u3002\u4f8b\u5982\uff0cX-Forwarded-For \u6807\u5934\u6807\u8bc6\u539f\u59cb\u5ba2\u6237\u7aef\u7684 IP \u5730\u5740\uff0c\u800c X-Forwarded-Proto \u6807\u5934\u6307\u793a\u8bf7\u6c42\u7684\u539f\u59cb\u65b9\u6848\uff08http \u6216 https\uff09\u3002<\/p>\n<p>For your app to behave correctly, it needs to look for these headers in incoming requests and modify the request as appropriate. A request to <a href=\"http:\/\/localhost\">http:\/\/localhost<\/a> with the X-Forwarded-Proto header set to https should be treated the same as if the request were to <a href=\"https:\/\/localhost\">https:\/\/localhost<\/a>.<br \/>\n\u4e3a\u4e86\u4f7f\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u6b63\u5e38\u8fd0\u884c\uff0c\u5b83\u9700\u8981\u5728\u4f20\u5165\u8bf7\u6c42\u4e2d\u67e5\u627e\u8fd9\u4e9b\u6807\u5934\u5e76\u6839\u636e\u9700\u8981\u4fee\u6539\u8bf7\u6c42\u3002\u5982\u679c X-Forwarded-Proto \u6807\u5934\u8bbe\u7f6e\u4e3a https <a href=\"http:\/\/localhost\uff0c\u5219\u8bf7\u6c42\u7684\u5904\u7406\u65b9\u5f0f\u5e94\u4e0e\u8bf7\u6c42\">http:\/\/localhost\uff0c\u5219\u8bf7\u6c42\u7684\u5904\u7406\u65b9\u5f0f\u5e94\u4e0e\u8bf7\u6c42<\/a> <a href=\"https:\/\/localhost\">https:\/\/localhost<\/a> \u76f8\u540c\u3002<\/p>\n<p>You can use ForwardedHeadersMiddleware in your middleware pipeline to achieve this. This middleware overrides Request.Scheme and other properties on HttpContext to correspond to the forwarded headers. WebApplicationBuilder partially handles this for you; the middleware is automatically added to the pipeline in a disabled state. To enable it, set the environment variable ASPNETCORE_FORWARDEDHEADERS_ENABLED=true.<br \/>\n\u60a8\u53ef\u4ee5\u5728\u4e2d\u95f4\u4ef6\u7ba1\u9053\u4e2d\u4f7f\u7528 ForwardedHeadersMiddleware \u6765\u5b9e\u73b0\u6b64\u76ee\u7684\u3002\u6b64\u4e2d\u95f4\u4ef6\u5c06\u8986\u76d6 HttpContext \u4e0a\u7684 Request.Scheme \u548c\u5176\u4ed6\u5c5e\u6027\uff0c\u4ee5\u5bf9\u5e94\u4e8e\u8f6c\u53d1\u7684\u6807\u5934\u3002WebApplicationBuilder \u4e3a\u60a8\u90e8\u5206\u5904\u7406\u6b64\u95ee\u9898;\u4e2d\u95f4\u4ef6\u4f1a\u81ea\u52a8\u4ee5 Disabled \u72b6\u6001\u6dfb\u52a0\u5230\u7ba1\u9053\u4e2d\u3002\u8981\u542f\u7528\u5b83\uff0c\u8bf7\u5c06\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u4e3a ASPNETCORE_FORWARDEDHEADERS_ENABLED=true\u3002<\/p>\n<p>If you don\u2019t want to use the automatically added middleware for some reason, or if you\u2019re using the generic host (which you\u2019ll learn about in chapter 30), you can add the middleware to the start of your middleware pipeline manually, as shown in listing 27.1, and configure it with the headers to look for.<br \/>\n\u5982\u679c\u7531\u4e8e\u67d0\u79cd\u539f\u56e0\u4e0d\u60f3\u4f7f\u7528\u81ea\u52a8\u6dfb\u52a0\u7684\u4e2d\u95f4\u4ef6\uff0c\u6216\u8005\u6b63\u5728\u4f7f\u7528\u901a\u7528\u4e3b\u673a\uff08\u60a8\u5c06\u5728\u7b2c 30 \u7ae0\u4e2d\u5b66\u4e60\uff09\uff0c\u5219\u53ef\u4ee5\u624b\u52a8\u5c06\u4e2d\u95f4\u4ef6\u6dfb\u52a0\u5230\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u5f00\u5934\uff0c\u5982\u6e05\u5355 27.1 \u6240\u793a\uff0c\u5e76\u4f7f\u7528\u8981\u67e5\u627e\u7684\u6807\u5934\u5bf9\u5176\u8fdb\u884c\u914d\u7f6e\u3002<\/p>\n<p><b>WARNING<\/b> It\u2019s important that ForwardedHeadersMiddleware be placed early in the middleware pipeline to correct Request.Scheme before any middleware that depends on the scheme runs.<br \/>\n\u8b66\u544a:\u8bf7\u52a1\u5fc5\u5c06 ForwardedHeadersMiddleware \u653e\u5728\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u65e9\u671f\uff0c\u4ee5\u4fbf\u5728\u4efb\u4f55\u4f9d\u8d56\u4e8e scheme \u7684\u4e2d\u95f4\u4ef6\u8fd0\u884c\u4e4b\u524d\u66f4\u6b63 Request.Scheme\u3002<\/p>\n<p>Listing 27.1 Configuring an app to use forwarded headers in Startup.cs<br \/>\n\u6e05\u5355 27.1 \u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5728 Startup.cs \u4e2d\u4f7f\u7528\u8f6c\u53d1\u7684 Headers<\/p>\n<pre><code>WebApplicationBuilder builder = WebApplication.CreateBuilder(args);\nWebApplication app = builder.Build();\n\napp.UseForwardedHeaders(new ForwardedHeadersOptions      #A\n{\n    ForwardedHeaders = ForwardedHeaders.XForwardedFor |     #B\n                       ForwardedHeaders.XForwardedProto     #B\n});\napp.UseHttpsRedirection();    #C\napp.UseRouting();             #C\napp.MapGet(&quot;\/&quot;, () =&gt; &quot;Hello world!&quot;);\napp.Run();<\/code><\/pre>\n<p>\u2776 Adds ForwardedHeadersMiddleware early in your pipeline<br \/>\n\u5728\u7ba1\u9053\u7684\u65e9\u671f\u6dfb\u52a0 ForwardedHeadersMiddleware<br \/>\n\u2777 Configures the headers the middleware should look for and use<br \/>\n\u914d\u7f6e\u4e2d\u95f4\u4ef6\u5e94\u8be5\u67e5\u627e\u548c\u4f7f\u7528\u7684\u6807\u5934<br \/>\n\u2778 The forwarded headers middleware must be placed before all other middleware.<br \/>\n\u8f6c\u53d1\u7684\u6807\u5934\u4e2d\u95f4\u4ef6\u5fc5\u987b\u653e\u5728\u6240\u6709\u5176\u4ed6\u4e2d\u95f4\u4ef6\u4e4b\u524d\u3002<\/p>\n<p><b>NOTE<\/b> This behavior isn\u2019t specific to reverse proxies on Linux; the UseIis() extension adds ForwardedHeadersMiddleware under the hood as part of its configuration when your app is running behind IIS.<br \/>\n\u6ce8\u610f:\u6b64\u884c\u4e3a\u5e76\u975e\u7279\u5b9a\u4e8e Linux \u4e0a\u7684\u53cd\u5411\u4ee3\u7406;\u5f53\u5e94\u7528\u5728 IIS \u540e\u9762\u8fd0\u884c\u65f6\uff0cUseIis\uff08\uff09 \u6269\u5c55\u4f1a\u5728\u540e\u53f0\u6dfb\u52a0 ForwardedHeadersMiddleware \u4f5c\u4e3a\u5176\u914d\u7f6e\u7684\u4e00\u90e8\u5206\u3002<\/p>\n<p>Aside from considering the forwarded headers, you need to consider a few minor things when deploying your app to Linux that may trip you up if you\u2019re used to deploying to Windows alone:<br \/>\n\u9664\u4e86\u8003\u8651\u8f6c\u53d1\u7684\u6807\u5934\u4e4b\u5916\uff0c\u5728\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230 Linux \u65f6\uff0c\u8fd8\u9700\u8981\u8003\u8651\u4e00\u4e9b\u5c0f\u4e8b\u9879\uff0c\u5982\u679c\u60a8\u4e60\u60ef\u4e8e\u5355\u72ec\u90e8\u7f72\u5230 Windows\uff0c\u8fd9\u4e9b\u4e8b\u9879\u53ef\u80fd\u4f1a\u8ba9\u60a8\u611f\u5230\u56f0\u60d1\uff1a<\/p>\n<p>\u2022  Line endings (LF in Linux versus CRLF in Windows)\u2014Windows and Linux use different character codes in text to indicate the end of a line. This isn\u2019t often a problem for ASP.NET Core apps, but if you\u2019re writing text files on one platform and reading them on a different platform, it\u2019s something to bear in mind.<br \/>\n\u884c\u5c3e \uff08Linux \u4e2d\u7684 LF \u4e0e Windows \u4e2d\u7684 CRLF\uff09 - Windows \u548c Linux \u5728\u6587\u672c\u4e2d\u4f7f\u7528\u4e0d\u540c\u7684\u5b57\u7b26\u4ee3\u7801\u6765\u6307\u793a\u884c\u5c3e\u3002\u5bf9\u4e8e ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6765\u8bf4\uff0c\u8fd9\u901a\u5e38\u4e0d\u662f\u95ee\u9898\uff0c\u4f46\u5982\u679c\u60a8\u5728\u4e00\u4e2a\u5e73\u53f0\u4e0a\u7f16\u5199\u6587\u672c\u6587\u4ef6\u5e76\u5728\u53e6\u4e00\u4e2a\u5e73\u53f0\u4e0a\u9605\u8bfb\u5b83\u4eec\uff0c\u5219\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e00\u70b9\u3002<\/p>\n<p>\u2022  Path directory separator (&quot;\\&quot; on Windows, &quot;\/&quot; on Linux)\u2014This is one of the most common bugs I see when Windows developers move to Linux. Each platform uses a different separator in file paths, so although loading a file using the &quot;subdir\\myfile.json&quot; path will work fine in Windows, it won\u2019t in Linux. Instead, you should use Path.Combine to create the appropriate separator for the current platform, such as Path.Combine(&quot;subdir&quot;, &quot;myfile.json&quot;).<br \/>\n\u8def\u5f84\u76ee\u5f55\u5206\u9694\u7b26 \uff08Windows \u4e0a\u4e3a \u201c\\\u201d\uff0cLinux \u4e0a\u4e3a \u201c\/\u201d\uff09 - \u8fd9\u662f\u6211\u5728 Windows \u5f00\u53d1\u4eba\u5458\u8fc1\u79fb\u5230 Linux \u65f6\u770b\u5230\u7684\u6700\u5e38\u89c1\u7684\u9519\u8bef\u4e4b\u4e00\u3002\u6bcf\u4e2a\u5e73\u53f0\u5728\u6587\u4ef6\u8def\u5f84\u4e2d\u4f7f\u7528\u4e0d\u540c\u7684\u5206\u9694\u7b26\uff0c\u56e0\u6b64\u5c3d\u7ba1\u4f7f\u7528 \u201csubdir\\myfile.json\u201d \u8def\u5f84\u52a0\u8f7d\u6587\u4ef6\u5728 Windows \u4e2d\u53ef\u4ee5\u6b63\u5e38\u5de5\u4f5c\uff0c\u4f46\u5728 Linux \u4e2d\u5219\u65e0\u6cd5\u3002\u76f8\u53cd\uff0c\u60a8\u5e94\u8be5\u4f7f\u7528 Path.Combine \u4e3a\u5f53\u524d\u5e73\u53f0\u521b\u5efa\u9002\u5f53\u7684\u5206\u9694\u7b26\uff0c\u4f8b\u5982 Path.Combine\uff08\u201csubdir\u201d\uff0c \u201cmyfile.json\u201d\uff09\u3002<\/p>\n<p>\u2022  &quot;:&quot; in environment variables\u2014In some Linux distributions, the colon character (:) isn\u2019t allowed in environment variables. As you saw in chapter 10, this character is typically used to denote different sections in ASP.NET Core configuration, so you often need to use it in environment variables. Instead, you can use a double underscore in your environment variables (<strong>); ASP.NET Core will treat it the same as though you\u2019d used a colon.<br \/>\n\u73af\u5883\u53d8\u91cf\u4e2d\u7684 \u201c\uff1a\u201d - \u5728\u67d0\u4e9b Linux \u53d1\u884c\u7248\u4e2d\uff0c\u73af\u5883\u53d8\u91cf\u4e2d\u4e0d\u5141\u8bb8\u4f7f\u7528\u5192\u53f7\u5b57\u7b26 \uff08:)\u3002\u6b63\u5982\u4f60\u5728\u7b2c 10 \u7ae0\u4e2d\u770b\u5230\u7684\uff0c\u8fd9\u4e2a\u5b57\u7b26\u901a\u5e38\u7528\u4e8e\u8868\u793a ASP.NET Core \u914d\u7f6e\u4e2d\u7684\u4e0d\u540c\u90e8\u5206\uff0c\u56e0\u6b64\u4f60\u7ecf\u5e38\u9700\u8981\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u4f7f\u7528\u5b83\u3002\u76f8\u53cd\uff0c\u60a8\u53ef\u4ee5\u5728\u73af\u5883\u53d8\u91cf \uff08<\/strong>\uff09 \u4e2d\u4f7f\u7528\u53cc\u4e0b\u5212\u7ebf;ASP.NET Core \u4f1a\u50cf\u4f7f\u7528\u5192\u53f7\u4e00\u6837\u5bf9\u5f85\u5b83\u3002<\/p>\n<p>\u2022  Missing time zone and culture data\u2014Linux distributions don\u2019t always come with time zone or culture data, which can cause localization problems and exceptions at runtime. You can install the time zone data using your distribution\u2019s package manager.[1] It also may be organized differently. The hierarchy of Norwegian cultures is different in Linux, for example.<br \/>\n\u7f3a\u5c11\u65f6\u533a\u548c\u6587\u5316\u6570\u636e - Linux \u53d1\u884c\u7248\u5e76\u4e0d\u603b\u662f\u9644\u5e26\u65f6\u533a\u6216\u6587\u5316\u6570\u636e\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5bfc\u81f4\u8fd0\u884c\u65f6\u51fa\u73b0\u672c\u5730\u5316\u95ee\u9898\u548c\u5f02\u5e38\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528\u5206\u914d\u7684\u8f6f\u4ef6\u5305\u7ba1\u7406\u5668\u5b89\u88c5\u65f6\u533a\u6570\u636e\u3002[1] \u5b83\u7684\u7ec4\u7ec7\u65b9\u5f0f\u4e5f\u53ef\u80fd\u4e0d\u540c\u3002\u4f8b\u5982\uff0c\u632a\u5a01\u6587\u5316\u7684\u5c42\u6b21\u7ed3\u6784\u5728 Linux \u4e2d\u662f\u4e0d\u540c\u7684\u3002<\/p>\n<p>\u2022  Different directory structures\u2014Linux distributions use a different folder structure from Windows, so you need to bear that in mind if your app hardcodes paths. In particular, consider differences in temporary\/cache folders.<br \/>\n\u4e0d\u540c\u7684\u76ee\u5f55\u7ed3\u6784 - Linux \u53d1\u884c\u7248\u4f7f\u7528\u4e0e Windows \u4e0d\u540c\u7684\u6587\u4ef6\u5939\u7ed3\u6784\uff0c\u56e0\u6b64\uff0c\u5982\u679c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5bf9\u8def\u5f84\u8fdb\u884c\u786c\u7f16\u7801\uff0c\u5219\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e00\u70b9\u3002\u7279\u522b\u662f\uff0c\u8bf7\u8003\u8651\u4e34\u65f6\/\u7f13\u5b58\u6587\u4ef6\u5939\u7684\u5dee\u5f02\u3002<\/p>\n<p>The preceding list is not exhaustive by any means, but as long as you set up ForwardedHeadersMiddleware and take care to use cross-platform constructs like Path.Combine, you shouldn\u2019t have too many problems running your applications on Linux. But configuring a reverse proxy isn\u2019t the simplest of activities, so wherever you\u2019re planning on hosting your app, I suggest checking the documentation for guidance at <a href=\"http:\/\/mng.bz\/1qM1\">http:\/\/mng.bz\/1qM1<\/a>.<br \/>\n\u524d\u9762\u7684\u5217\u8868\u65e0\u8bba\u5982\u4f55\u90fd\u4e0d\u662f\u8be6\u5c3d\u65e0\u9057\u7684\uff0c\u4f46\u53ea\u8981\u60a8\u8bbe\u7f6e\u4e86 ForwardedHeadersMiddleware \u5e76\u6ce8\u610f\u4f7f\u7528\u50cf Path.Combine \u8fd9\u6837\u7684\u8de8\u5e73\u53f0\u7ed3\u6784\uff0c\u5728 Linux \u4e0a\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u5e94\u8be5\u4e0d\u4f1a\u6709\u592a\u591a\u95ee\u9898\u3002\u4f46\u662f\u914d\u7f6e\u53cd\u5411\u4ee3\u7406\u5e76\u4e0d\u662f\u6700\u7b80\u5355\u7684\u6d3b\u52a8\uff0c\u56e0\u6b64\u65e0\u8bba\u60a8\u6253\u7b97\u5728\u54ea\u91cc\u6258\u7ba1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u6211\u5efa\u8bae\u60a8\u67e5\u770b <a href=\"http:\/\/mng.bz\/1qM1\">http:\/\/mng.bz\/1qM1<\/a> \u4e0a\u7684\u6587\u6863\u4ee5\u83b7\u53d6\u6307\u5bfc\u3002<\/p>\n<h2>27.4 Configuring the URLs for your application<\/h2>\n<p>27.4 \u4e3a\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e URL<\/p>\n<p>At this point, you\u2019ve deployed an application, but there\u2019s one aspect you haven\u2019t configured: the URLs for your application. When you\u2019re using IIS as a reverse proxy, you don\u2019t have to worry about this inside your app. IIS integration with the ASP.NET Core Module works by dynamically creating a URL that\u2019s used to forward requests between IIS and your app. The hostname you configure in IIS (in figure 27.6) is the URL that external users see for your app; the internal URL that IIS uses when forwarding requests is never exposed.<br \/>\n\u6b64\u65f6\uff0c\u60a8\u5df2\u7ecf\u90e8\u7f72\u4e86\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u6709\u4e00\u4e2a\u65b9\u9762\u5c1a\u672a\u914d\u7f6e\uff1a\u5e94\u7528\u7a0b\u5e8f\u7684 URL\u3002\u5f53\u60a8\u4f7f\u7528 IIS \u4f5c\u4e3a\u53cd\u5411\u4ee3\u7406\u65f6\uff0c\u60a8\u4e0d\u5fc5\u62c5\u5fc3\u5e94\u7528\u7a0b\u5e8f\u5185\u90e8\u7684\u8fd9\u4e2a\u95ee\u9898\u3002IIS \u4e0e ASP.NET \u6838\u5fc3\u6a21\u5757\u7684\u96c6\u6210\u7684\u5de5\u4f5c\u539f\u7406\u662f\u52a8\u6001\u521b\u5efa\u4e00\u4e2a URL\uff0c\u8be5 URL \u7528\u4e8e\u5728 IIS \u548c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e4b\u95f4\u8f6c\u53d1\u8bf7\u6c42\u3002\u60a8\u5728 IIS \u4e2d\u914d\u7f6e\u7684\u4e3b\u673a\u540d\uff08\u5982\u56fe 27.6 \u6240\u793a\uff09\u662f\u5916\u90e8\u7528\u6237\u770b\u5230\u7684\u5e94\u7528\u7a0b\u5e8f\u7684 URL;IIS \u5728\u8f6c\u53d1\u8bf7\u6c42\u65f6\u4f7f\u7528\u7684\u5185\u90e8 URL \u6c38\u8fdc\u4e0d\u4f1a\u516c\u5f00\u3002<\/p>\n<p>If you\u2019re not using IIS as a reverse proxy\u2014maybe you\u2019re using NGINX or exposing your app directly to the internet\u2014you may find you need to configure the URLs your application listens to directly.<br \/>\n\u5982\u679c\u60a8\u6ca1\u6709\u5c06 IIS \u7528\u4f5c\u53cd\u5411\u4ee3\u7406\uff08\u4e5f\u8bb8\u60a8\u4f7f\u7528\u7684\u662f NGINX \u6216\u76f4\u63a5\u5411 Internet \u516c\u5f00\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff09\uff0c\u60a8\u53ef\u80fd\u4f1a\u53d1\u73b0\u60a8\u9700\u8981\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u76f4\u63a5\u4fa6\u542c\u7684 URL\u3002<\/p>\n<p>By default, ASP.NET Core listens for requests on the URL <a href=\"http:\/\/localhost:5000\">http:\/\/localhost:5000<\/a>. There are lots of ways to set this URL, but in this section I describe two: using environment variables or using command-line arguments. These are the two most common approaches I see (outside of IIS) for controlling which URLs your app uses.<br \/>\n\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cASP.NET Core \u4fa6\u542c URL <a href=\"http:\/\/localhost:5000\">http:\/\/localhost:5000<\/a> \u4e0a\u7684\u8bf7\u6c42\u3002\u8bbe\u7f6e\u6b64 URL \u7684\u65b9\u6cd5\u6709\u5f88\u591a\u79cd\uff0c\u4f46\u5728\u672c\u8282\u4e2d\uff0c\u6211\u5c06\u4ecb\u7ecd\u4e24\u79cd\u65b9\u6cd5\uff1a\u4f7f\u7528\u73af\u5883\u53d8\u91cf\u6216\u4f7f\u7528\u547d\u4ee4\u884c\u53c2\u6570\u3002\u8fd9\u662f\u6211\u770b\u5230\u7684\u4e24\u79cd\u6700\u5e38\u89c1\u7684\u65b9\u6cd5\uff08\u5728 IIS \u4e4b\u5916\uff09\uff0c\u7528\u4e8e\u63a7\u5236\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684 URL\u3002<\/p>\n<p><b>TIP<\/b> For further ways to set your application\u2019s URL, see my \u201c5 ways to set the URLs for an ASP.NET Core app\u201d blog post: <a href=\"http:\/\/mng.bz\/go0v\">http:\/\/mng.bz\/go0v<\/a>.<br \/>\n\u63d0\u793a:\u6709\u5173\u8bbe\u7f6e\u5e94\u7528\u7a0b\u5e8f URL \u7684\u66f4\u591a\u65b9\u6cd5\uff0c\u8bf7\u53c2\u9605\u6211\u7684\u201c\u4e3a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e URL \u7684 5 \u79cd\u65b9\u6cd5\u201d\u535a\u5ba2\u6587\u7ae0\uff1a<a href=\"http:\/\/mng.bz\/go0v\">http:\/\/mng.bz\/go0v<\/a>\u3002<\/p>\n<p>In chapter 10 you learned about configuration in ASP.NET Core, and in particular about the concept of hosting environments so that you can use different settings when running in development compared with production. You choose the hosting environment by setting an environment variable on your machine called ASPNETCORE_ENVIRONMENT. The ASP.NET Core framework magically picks up this variable when your app starts and uses it to set the hosting environment.<br \/>\n\u5728\u7b2c 10 \u7ae0\u4e2d\uff0c\u60a8\u4e86\u89e3\u4e86 ASP.NET Core \u4e2d\u7684\u914d\u7f6e\uff0c\u7279\u522b\u662f\u6258\u7ba1\u73af\u5883\u7684\u6982\u5ff5\uff0c\u4ee5\u4fbf\u5728\u5f00\u53d1\u73af\u5883\u4e2d\u8fd0\u884c\u65f6\u4e0e\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c\u65f6\u53ef\u4ee5\u4f7f\u7528\u4e0d\u540c\u7684\u8bbe\u7f6e\u3002\u60a8\u53ef\u4ee5\u901a\u8fc7\u5728\u8ba1\u7b97\u673a\u4e0a\u8bbe\u7f6e\u540d\u4e3a ASPNETCORE_ENVIRONMENT \u7684\u73af\u5883\u53d8\u91cf\u6765\u9009\u62e9\u6258\u7ba1\u73af\u5883\u3002ASP.NET Core \u6846\u67b6\u4f1a\u5728\u60a8\u7684\u5e94\u7528\u542f\u52a8\u65f6\u795e\u5947\u5730\u9009\u53d6\u6b64\u53d8\u91cf\uff0c\u5e76\u4f7f\u7528\u5b83\u6765\u8bbe\u7f6e\u6258\u7ba1\u73af\u5883\u3002<\/p>\n<p>You can use a similar special environment variable to specify the URL that your app uses; this variable is called ASPNETCORE_URLS. When your app starts up, it looks for this value and uses it as the application\u2019s URL. By changing this value, you can change the default URL used by all ASP.NET Core apps on the machine. For example, you could set a temporary environment variable in Windows from the command window using<br \/>\n\u60a8\u53ef\u4ee5\u4f7f\u7528\u7c7b\u4f3c\u7684\u7279\u6b8a\u73af\u5883\u53d8\u91cf\u6765\u6307\u5b9a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684 URL;\u6b64\u53d8\u91cf\u79f0\u4e3a ASPNETCORE_URLS\u3002\u5f53\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u5b83\u4f1a\u67e5\u627e\u6b64\u503c\u5e76\u5c06\u5176\u7528\u4f5c\u5e94\u7528\u7a0b\u5e8f\u7684 URL\u3002\u901a\u8fc7\u66f4\u6539\u6b64\u503c\uff0c\u60a8\u53ef\u4ee5\u66f4\u6539\u8ba1\u7b97\u673a\u4e0a\u6240\u6709 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u9ed8\u8ba4 URL\u3002\u4f8b\u5982\uff0c\u60a8\u53ef\u4ee5\u5728\u547d\u4ee4\u7a97\u53e3\u4e2d\u4f7f\u7528<\/p>\n<pre><code>set ASPNETCORE_URLS=http:\/\/localhost:8000<\/code><\/pre>\n<p>Running a published application using dotnet <code>&lt;app.dll&gt;<\/code> within the same command window, as shown in figure 27.10, shows that the app is now listening on the URL provided in the ASPNETCORE_URLS variable.<br \/>\n\u5982\u56fe 27.10 \u6240\u793a\uff0c\u5728\u540c\u4e00\u547d\u4ee4\u7a97\u53e3\u4e2d\u4f7f\u7528 dotnet <code>&lt;app.dll&gt;<\/code> \u8fd0\u884c\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u663e\u793a\u8be5\u5e94\u7528\u7a0b\u5e8f\u73b0\u5728\u6b63\u5728\u4fa6\u542c ASPNETCORE_URLS \u53d8\u91cf\u4e2d\u63d0\u4f9b\u7684 URL\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2710.png\" alt=\"alt text\" \/><br \/>\nFigure 27.10 Change the ASPNETCORE_URLS environment variable to change the URL used by ASP.NET Core apps.<br \/>\n\u56fe 27.10 \u66f4\u6539 ASPNETCORE_URLS \u73af\u5883\u53d8\u91cf\u4ee5\u66f4\u6539 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684 URL\u3002<\/p>\n<p>You can instruct an app to listen on multiple URLs by separating them with a semicolon, or you can listen to a specific port without specifying the localhost hostname. If you set the ASPNETCORE_URLS environment variable to<br \/>\n\u60a8\u53ef\u4ee5\u901a\u8fc7\u7528\u5206\u53f7\u5206\u9694\u591a\u4e2a URL \u6765\u6307\u793a\u5e94\u7528\u7a0b\u5e8f\u4fa6\u542c\u8fd9\u4e9b URL\uff0c\u4e5f\u53ef\u4ee5\u5728\u4e0d\u6307\u5b9a localhost \u4e3b\u673a\u540d\u7684\u60c5\u51b5\u4e0b\u4fa6\u542c\u7279\u5b9a\u7aef\u53e3\u3002\u5982\u679c\u5c06 ASPNETCORE_URLS \u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u4e3a<br \/>\n<a href=\"http:\/\/localhost:5001;http:\/\/*:5002\">http:\/\/localhost:5001;http:\/\/*:5002<\/a><\/p>\n<p>your ASP.NET Core apps will listen for requests sent to the following:<br \/>\n\u60a8\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u5c06\u4fa6\u542c\u53d1\u9001\u5230\u4ee5\u4e0b\u5404\u9879\u7684\u8bf7\u6c42\uff1a<\/p>\n<p>\u2022  <a href=\"http:\/\/localhost:5001\">http:\/\/localhost:5001<\/a> \u2014 This address is accessible only on your local computer, so it will not accept requests from the wider internet.<br \/>\n<a href=\"http:\/\/localhost:5001\">http:\/\/localhost:5001<\/a> - \u6b64\u5730\u5740\u53ea\u80fd\u5728\u60a8\u7684\u672c\u5730\u8ba1\u7b97\u673a\u4e0a\u8bbf\u95ee\uff0c\u56e0\u6b64\u5b83\u4e0d\u4f1a\u63a5\u53d7\u6765\u81ea\u66f4\u5e7f\u6cdb Internet \u7684\u8bf7\u6c42\u3002<\/p>\n<p>\u2022  <a href=\"http:\/\/*:5002\u2014Any\">http:\/\/*:5002\u2014Any<\/a> URL on port 5002. External requests from the internet can access the app on port 5002, using any URL that maps to your computer.<br \/>\n\u2022 http\uff1a\/\/*\uff1a5002 - \u7aef\u53e3 5002 \u4e0a\u7684\u4efb\u4f55 URL\u3002\u6765\u81ea Internet \u7684\u5916\u90e8\u8bf7\u6c42\u53ef\u4ee5\u4f7f\u7528\u6620\u5c04\u5230\u60a8\u8ba1\u7b97\u673a\u7684\u4efb\u4f55 URL \u8bbf\u95ee\u7aef\u53e3 5002 \u4e0a\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>Note that you can\u2019t specify a different hostname, like tastyrecipes.com. ASP.NET Core listens to all requests on a given port; it doesn\u2019t listen for specific domain names. The exception is the localhost hostname, which allows only requests that came from your own computer.<br \/>\n\u8bf7\u6ce8\u610f\uff0c\u60a8\u4e0d\u80fd\u6307\u5b9a\u5176\u4ed6\u4e3b\u673a\u540d\uff0c\u4f8b\u5982 tastyrecipes.com\u3002ASP.NET Core \u4fa6\u542c\u7ed9\u5b9a\u7aef\u53e3\u4e0a\u7684\u6240\u6709\u8bf7\u6c42;\u5b83\u4e0d\u4fa6\u542c\u7279\u5b9a\u7684\u57df\u540d\u3002localhost \u4e3b\u673a\u540d\u4f8b\u5916\uff0c\u5b83\u53ea\u5141\u8bb8\u6765\u81ea\u60a8\u81ea\u5df1\u7684\u8ba1\u7b97\u673a\u7684\u8bf7\u6c42\u3002<\/p>\n<p><b>NOTE<\/b>   If you find the ASPNETCORE_URLS variable isn\u2019t working properly, ensure that you don\u2019t have a launchSettings.json file in the directory. When present, the values in this file take precedence. By default, launchSettings.json isn\u2019t included in the publish output, so this generally won\u2019t be a problem in production.<br \/>\n\u6ce8\u610f:\u5982\u679c\u60a8\u53d1\u73b0 ASPNETCORE_URLS \u53d8\u91cf\u65e0\u6cd5\u6b63\u5e38\u5de5\u4f5c\uff0c\u8bf7\u786e\u4fdd\u76ee\u5f55\u4e2d\u6ca1\u6709 launchSettings.json \u6587\u4ef6\u3002\u5982\u679c\u5b58\u5728\uff0c\u5219\u6b64\u6587\u4ef6\u4e2d\u7684\u503c\u4f18\u5148\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0claunchSettings.json \u4e0d\u5305\u542b\u5728\u53d1\u5e03\u8f93\u51fa\u4e2d\uff0c\u56e0\u6b64\u8fd9\u5728\u751f\u4ea7\u4e2d\u901a\u5e38\u4e0d\u4f1a\u6210\u4e3a\u95ee\u9898\u3002<\/p>\n<p>Setting the URL of an app using a single environment variable works great for some scenarios, most notably when you\u2019re running a single application in a virtual machine, or within a Docker container.<br \/>\n\u4f7f\u7528\u5355\u4e2a\u73af\u5883\u53d8\u91cf\u8bbe\u7f6e\u5e94\u7528\u7a0b\u5e8f\u7684 URL \u9002\u7528\u4e8e\u67d0\u4e9b\u573a\u666f\uff0c\u5c24\u5176\u662f\u5f53\u60a8\u5728\u865a\u62df\u673a\u6216 Docker \u5bb9\u5668\u4e2d\u8fd0\u884c\u5355\u4e2a\u5e94\u7528\u7a0b\u5e8f\u65f6\u3002<\/p>\n<p><b>TIP<\/b> ASP.NET Core is well suited to running in containers but working with containers is a separate book in its own right. For details on hosting and publishing apps using Docker, see Microsoft\u2019s \u201cHost ASP.NET Core in Docker containers\u201d documentation: <a href=\"http:\/\/mng.bz\/e5GV\">http:\/\/mng.bz\/e5GV<\/a>.<br \/>\n\u63d0\u793a\uff1a ASP.NET Core \u975e\u5e38\u9002\u5408\u5728\u5bb9\u5668\u4e2d\u8fd0\u884c\uff0c\u4f46\u4f7f\u7528\u5bb9\u5668\u672c\u8eab\u662f\u4e00\u672c\u5355\u72ec\u7684\u4e66\u3002\u6709\u5173\u4f7f\u7528 Docker \u6258\u7ba1\u548c\u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Microsoft \u7684\u201c\u5728 Docker \u5bb9\u5668\u4e2d\u6258\u7ba1 ASP.NET Core\u201d\u6587\u6863\uff1a<a href=\"http:\/\/mng.bz\/e5GV\">http:\/\/mng.bz\/e5GV<\/a>\u3002<\/p>\n<p>If you\u2019re not using Docker containers or a PaaS offering, chances are that you\u2019re hosting multiple apps side-by-side on the same machine. A single environment variable is no good for setting URLs in this case, as it would change the URL of every app.<br \/>\n\u5982\u679c\u60a8\u6ca1\u6709\u4f7f\u7528 Docker \u5bb9\u5668\u6216 PaaS \u4ea7\u54c1\uff0c\u5219\u5f88\u53ef\u80fd\u5728\u540c\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u5e76\u6392\u6258\u7ba1\u591a\u4e2a\u5e94\u7528\u7a0b\u5e8f\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5355\u4e2a\u73af\u5883\u53d8\u91cf\u4e0d\u9002\u5408\u8bbe\u7f6e URL\uff0c\u56e0\u4e3a\u5b83\u4f1a\u66f4\u6539\u6bcf\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684 URL\u3002<\/p>\n<p>In chapter 10 you saw that you could set the hosting environment using the ASPNETCORE_ENVIRONMENT variable, but you could also set the environment using the --environment flag when calling dotnet run:<br \/>\n\u5728\u7b2c 10 \u7ae0\u4e2d\uff0c\u60a8\u770b\u5230\u53ef\u4ee5\u4f7f\u7528 ASPNETCORE_ENVIRONMENT \u53d8\u91cf\u8bbe\u7f6e\u6258\u7ba1\u73af\u5883\uff0c\u4f46\u4e5f\u53ef\u4ee5\u5728\u8c03\u7528 dotnet run \u65f6\u4f7f\u7528 --environment \u6807\u5fd7\u8bbe\u7f6e\u73af\u5883\uff1a<\/p>\n<pre><code>dotnet run --no-launch-profile --environment Staging<\/code><\/pre>\n<p>You can set the URLs for your application in a similar way, using the --urls parameter. Using command-line arguments enables you to have multiple ASP.NET Core applications running on the same machine, listening to different ports. For example, the following command would run the recipe application, set it to listen on port 8081, and set the environment to staging (figure 27.11):<br \/>\n\u60a8\u53ef\u4ee5\u4f7f\u7528 --urls \u53c2\u6570\u4ee5\u7c7b\u4f3c\u7684\u65b9\u5f0f\u4e3a\u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e URL\u3002\u4f7f\u7528\u547d\u4ee4\u884c\u53c2\u6570\uff0c\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\u591a\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u4fa6\u542c\u4e0d\u540c\u7684\u7aef\u53e3\u3002\u4f8b\u5982\uff0c\u4ee5\u4e0b\u547d\u4ee4\u5c06\u8fd0\u884c recipe \u5e94\u7528\u7a0b\u5e8f\uff0c\u5c06\u5176\u8bbe\u7f6e\u4e3a\u4fa6\u542c\u7aef\u53e3 8081\uff0c\u5e76\u5c06\u73af\u5883\u8bbe\u7f6e\u4e3a staging \uff08\u56fe 27.11\uff09\uff1a<\/p>\n<pre><code>dotnet RecipeApplication.dll --urls &quot;http:\/\/*:8081&quot; --environment Staging<\/code><\/pre>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/2711.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 27.11 Setting the hosting environment and URLs for an application using command-line arguments. The values passed at the command line override values provided from appSettings.json or environment variables.<br \/>\n\u56fe 27.11 \u4f7f\u7528\u547d\u4ee4\u884c\u53c2\u6570\u8bbe\u7f6e\u5e94\u7528\u7a0b\u5e8f\u7684\u6258\u7ba1\u73af\u5883\u548c URL\u3002\u5728\u547d\u4ee4\u884c\u4e2d\u4f20\u9012\u7684\u503c\u5c06\u8986\u76d6appSettings.json\u6216\u73af\u5883\u53d8\u91cf\u63d0\u4f9b\u7684\u503c\u3002<\/p>\n<p>Remember that you don\u2019t need to set your URLs in this way if you\u2019re using IIS as a reverse proxy; IIS integration handles this for you. Setting the URLs is necessary only when you\u2019re manually configuring the URL your app is listening on, such as if you\u2019re using NGINX or are exposing Kestrel directly to clients.<br \/>\n\u8bf7\u8bb0\u4f4f\uff0c\u5982\u679c\u60a8\u4f7f\u7528 IIS \u4f5c\u4e3a\u53cd\u5411\u4ee3\u7406\uff0c\u5219\u65e0\u9700\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8bbe\u7f6e URL;IIS \u96c6\u6210\u4f1a\u4e3a\u60a8\u5904\u7406\u6b64\u95ee\u9898\u3002\u53ea\u6709\u5f53\u60a8\u624b\u52a8\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u6b63\u5728\u4fa6\u542c\u7684 URL \u65f6\uff08\u4f8b\u5982\uff0c\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f NGINX \u6216\u5c06 Kestrel \u76f4\u63a5\u516c\u5f00\u7ed9\u5ba2\u6237\u7aef\uff09\uff0c\u624d\u9700\u8981\u8bbe\u7f6e URL\u3002<\/p>\n<p><b>WARNING<\/b> If you are running your ASP.NET Core application without a reverse proxy, you should use host filtering for security reasons to ensure that your app only responds to requests for hostnames you expect. For more details, see my \u201cAdding host filtering to Kestrel in ASP.NET Core\u201d blog entry: <a href=\"http:\/\/mng.bz\/pVXK\">http:\/\/mng.bz\/pVXK<\/a>.<br \/>\n\u8b66\u544a\uff1a\u5982\u679c\u60a8\u5728\u6ca1\u6709\u53cd\u5411\u4ee3\u7406\u7684\u60c5\u51b5\u4e0b\u8fd0\u884c ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u5219\u51fa\u4e8e\u5b89\u5168\u539f\u56e0\uff0c\u60a8\u5e94\u8be5\u4f7f\u7528\u4e3b\u673a\u7b5b\u9009\uff0c\u4ee5\u786e\u4fdd\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4ec5\u54cd\u5e94\u60a8\u671f\u671b\u7684\u4e3b\u673a\u540d\u8bf7\u6c42\u3002\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605\u6211\u7684\u201c\u5728 ASP.NET Core \u4e2d\u5411 Kestrel \u6dfb\u52a0\u4e3b\u673a\u7b5b\u9009\u201d\u535a\u5ba2\u6587\u7ae0\uff1a<a href=\"http:\/\/mng.bz\/pVXK\">http:\/\/mng.bz\/pVXK<\/a>\u3002<\/p>\n<p>That brings us to the end of this chapter on publishing your app. This last mile of app development\u2014deploying an application to a server where users can access it\u2014is a notoriously thorny problem. Publishing an ASP.NET Core application is easy enough, but the multitude of hosting options available makes providing concise steps for every situation difficult.<br \/>\n\u5230\u6b64\uff0c\u6211\u4eec\u6765\u5230\u4e86\u672c\u7ae0\u5173\u4e8e\u53d1\u5e03\u60a8\u7684\u5e94\u7528\u7684\u7ed3\u5c3e\u3002\u4f17\u6240\u5468\u77e5\uff0c\u5e94\u7528\u7a0b\u5e8f\u5f00\u53d1\u7684\u6700\u540e\u4e00\u82f1\u91cc \u2014 \u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230\u7528\u6237\u53ef\u4ee5\u8bbf\u95ee\u5b83\u7684\u670d\u52a1\u5668\u4e0a \u2014 \u662f\u4e00\u4e2a\u975e\u5e38\u68d8\u624b\u7684\u95ee\u9898\u3002\u53d1\u5e03 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u975e\u5e38\u7b80\u5355\uff0c\u4f46\u53ef\u7528\u7684\u5927\u91cf\u6258\u7ba1\u9009\u9879\u4f7f\u5f97\u4e3a\u6bcf\u79cd\u60c5\u51b5\u63d0\u4f9b\u7b80\u6d01\u7684\u6b65\u9aa4\u53d8\u5f97\u56f0\u96be\u3002<\/p>\n<p>Whichever hosting option you choose, there\u2019s one critical topic that you mustn\u2019t overlook: security. In the next chapter you\u2019ll learn about HTTPS, how to use it when testing locally, and why it\u2019s important your production apps all use HTTPS.<br \/>\n\u65e0\u8bba\u60a8\u9009\u62e9\u54ea\u79cd\u6258\u7ba1\u9009\u9879\uff0c\u90fd\u6709\u4e00\u4e2a\u5173\u952e\u4e3b\u9898\u662f\u60a8\u4e0d\u5bb9\u5ffd\u89c6\u7684\uff1a\u5b89\u5168\u6027\u3002\u5728\u4e0b\u4e00\u7ae0\u4e2d\uff0c\u60a8\u5c06\u4e86\u89e3 HTTPS\uff0c\u5728\u672c\u5730\u6d4b\u8bd5\u65f6\u5982\u4f55\u4f7f\u7528 HTTPS\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u60a8\u7684\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f\u90fd\u4f7f\u7528 HTTPS \u5f88\u91cd\u8981\u3002<\/p>\n<h2>27.5 Summary<\/h2>\n<p>27.5 \u603b\u7ed3<\/p>\n<p>ASP.NET Core apps are console applications that self-host a web server. In production, you may use a reverse proxy, which handles the initial request and passes it to your app. Reverse proxies can provide additional security, operations, and performance benefits, but they can also add complexity to your deployments.<br \/>\nASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u662f\u81ea\u6258\u7ba1 Web \u670d\u52a1\u5668\u7684\u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u3002\u5728\u751f\u4ea7\u73af\u5883\u4e2d\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u53cd\u5411\u4ee3\u7406\u6765\u5904\u7406\u521d\u59cb\u8bf7\u6c42\u5e76\u5c06\u5176\u4f20\u9012\u7ed9\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u53cd\u5411\u4ee3\u7406\u53ef\u4ee5\u63d0\u4f9b\u989d\u5916\u7684\u5b89\u5168\u6027\u3001\u4f5c\u548c\u6027\u80fd\u4f18\u52bf\uff0c\u4f46\u5b83\u4eec\u4e5f\u4f1a\u589e\u52a0\u90e8\u7f72\u7684\u590d\u6742\u6027\u3002<\/p>\n<p>.NET has two parts: the .NET SDK (also known as the .NET CLI) and the .NET Runtime. When you\u2019re developing an application, you use the .NET CLI to restore, build, and run your application. Visual Studio uses the same .NET CLI commands from the IDE.<br \/>\n.NET \u6709\u4e24\u4e2a\u90e8\u5206\uff1a.NET SDK\uff08\u4e5f\u79f0\u4e3a .NET CLI\uff09\u548c .NET \u8fd0\u884c\u65f6\u3002\u5728\u5f00\u53d1\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 .NET CLI \u6765\u8fd8\u539f\u3001\u6784\u5efa\u548c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3002Visual Studio \u4f7f\u7528\u4e0e IDE \u76f8\u540c\u7684 .NET CLI \u547d\u4ee4\u3002<\/p>\n<p>When you want to deploy your app to production, you need to publish your application, using dotnet publish. This creates a folder containing your application as a DLL, along with all its dependencies.<br \/>\n\u5982\u679c\u8981\u5c06\u5e94\u7528\u90e8\u7f72\u5230\u751f\u4ea7\u73af\u5883\uff0c\u5219\u9700\u8981\u4f7f\u7528 dotnet publish \u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u3002\u8fd9\u5c06\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u5176\u4e2d\u5305\u542b\u4f5c\u4e3a DLL \u7684\u5e94\u7528\u7a0b\u5e8f\u53ca\u5176\u6240\u6709\u4f9d\u8d56\u9879\u3002<\/p>\n<p>To run a published application, you don\u2019t need the .NET CLI because you won\u2019t be building the app. You need only the .NET Runtime to run a published app. You can run a published application using the dotnet app.dll command, where app.dll is the application .dll created by the dotnet publish command.<br \/>\n\u8981\u8fd0\u884c\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u4e0d\u9700\u8981 .NET CLI\uff0c\u56e0\u4e3a\u60a8\u4e0d\u4f1a\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u3002\u53ea\u9700 .NET \u8fd0\u884c\u65f6\u5373\u53ef\u8fd0\u884c\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u53ef\u4ee5\u4f7f\u7528 dotnet app.dll \u547d\u4ee4\u8fd0\u884c\u5df2\u53d1\u5e03\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4e2d app.dll \u662f\u7531 dotnet publish \u547d\u4ee4\u521b\u5efa\u7684\u5e94\u7528\u7a0b\u5e8f.dll\u3002<\/p>\n<p>To host ASP.NET Core applications in IIS, you must install the ASP.NET Core Module. This allows IIS to act as a reverse proxy for your ASP.NET Core app. You must also install the .NET Runtime and the ASP.NET Core Runtime, which are installed as part of the ASP.NET Core Windows Hosting Bundle.<br \/>\n\u8981\u5728 IIS \u4e2d\u6258\u7ba1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u5fc5\u987b\u5b89\u88c5 ASP.NET Core Module\u3002\u8fd9\u5141\u8bb8 IIS \u5145\u5f53 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u53cd\u5411\u4ee3\u7406\u3002\u60a8\u8fd8\u5fc5\u987b\u5b89\u88c5 .NET \u8fd0\u884c\u65f6\u548c ASP.NET Core \u8fd0\u884c\u65f6\uff0c\u5b83\u4eec\u4f5c\u4e3a ASP.NET Core Windows \u6258\u7ba1\u6346\u7ed1\u5305\u7684\u4e00\u90e8\u5206\u5b89\u88c5\u3002<\/p>\n<p>IIS can host ASP.NET Core applications using one of two modes: in-process and out-of-process. The out-of-process mode runs your application as a separate process, as is typical for most reverse proxies. The in-process mode runs your application as part of the IIS process. This has performance benefits, as no interprocess communication is required.<br \/>\nIIS \u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u4e24\u79cd\u6a21\u5f0f\u4e4b\u4e00\u6258\u7ba1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff1a\u8fdb\u7a0b\u5185\u548c\u8fdb\u7a0b\u5916\u3002\u8fdb\u7a0b\u5916\u6a21\u5f0f\u5c06\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4f5c\u4e3a\u5355\u72ec\u7684\u8fdb\u7a0b\u8fd0\u884c\uff0c\u8fd9\u662f\u5927\u591a\u6570\u53cd\u5411\u4ee3\u7406\u7684\u5178\u578b\u7279\u5f81\u3002\u8fdb\u7a0b\u5185\u6a21\u5f0f\u5c06\u5e94\u7528\u7a0b\u5e8f\u4f5c\u4e3a IIS \u8fdb\u7a0b\u7684\u4e00\u90e8\u5206\u8fd0\u884c\u3002\u8fd9\u5177\u6709\u6027\u80fd\u4f18\u52bf\uff0c\u56e0\u4e3a\u4e0d\u9700\u8981\u8fdb\u7a0b\u95f4\u901a\u4fe1\u3002<\/p>\n<p>If you are using a custom web application builder with IIS, ensure that you call UseIISIntegration() and UseIIS() so that IIS forwards the request to your app correctly. If you\u2019re using the default WebApplicationBuilder, these methods are called automatically for you.<br \/>\n\u5982\u679c\u5c06\u81ea\u5b9a\u4e49 Web \u5e94\u7528\u7a0b\u5e8f\u751f\u6210\u5668\u4e0e IIS \u4e00\u8d77\u4f7f\u7528\uff0c\u8bf7\u786e\u4fdd\u8c03\u7528 UseIISIntegration\uff08\uff09 \u548c UseIIS\uff08\uff09\uff0c\u4ee5\u4fbf IIS \u5c06\u8bf7\u6c42\u6b63\u786e\u8f6c\u53d1\u5230\u5e94\u7528\u3002\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f\u9ed8\u8ba4\u7684 WebApplicationBuilder\uff0c\u5219\u4f1a\u81ea\u52a8\u4e3a\u60a8\u8c03\u7528\u8fd9\u4e9b\u65b9\u6cd5\u3002<\/p>\n<p>When you publish your application using the .NET CLI, a web.config file is added to the output folder. It\u2019s important that this file be deployed with your application when publishing to IIS, as it defines how your application should run.<br \/>\n\u5f53\u60a8\u4f7f\u7528 .NET CLI \u53d1\u5e03\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0cweb.config \u6587\u4ef6\u5c06\u6dfb\u52a0\u5230\u8f93\u51fa\u6587\u4ef6\u5939\u4e2d\u3002\u5728\u53d1\u5e03\u5230 IIS \u65f6\uff0c\u6b64\u6587\u4ef6\u5fc5\u987b\u4e0e\u5e94\u7528\u7a0b\u5e8f\u4e00\u8d77\u90e8\u7f72\uff0c\u56e0\u4e3a\u5b83\u5b9a\u4e49\u4e86\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u65b9\u5f0f\u3002<\/p>\n<p>The URL that your app listens on is specified by default using the environment variable ASPNETCORE_URLS. Setting this value changes the URL for all the apps on your machine. Alternatively, pass the --urls command-line argument when running your app, as in this example: dotnet app.dll --urls <a href=\"http:\/\/localhost:80\">http:\/\/localhost:80<\/a>.<br \/>\n\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4fa6\u542c\u7684 URL \u662f\u4f7f\u7528\u73af\u5883\u53d8\u91cf ASPNETCORE_URLS \u6307\u5b9a\u7684\u3002\u8bbe\u7f6e\u6b64\u503c\u4f1a\u66f4\u6539\u8ba1\u7b97\u673a\u4e0a\u6240\u6709\u5e94\u7528\u7a0b\u5e8f\u7684 URL\u3002\u6216\u8005\uff0c\u5728\u8fd0\u884c\u5e94\u7528\u65f6\u4f20\u9012 --urls \u547d\u4ee4\u884c\u53c2\u6570\uff0c\u5982\u4ee5\u4e0b\u793a\u4f8b\u6240\u793a\uff1adotnet app.dll --urls <a href=\"http:\/\/localhost:80\">http:\/\/localhost:80<\/a>\u3002<\/p>\n<p>[1] I ran into this problem myself. You can read about it in detail and how I solved it on my blog: <a href=\"http:\/\/mng.bz\/aoem\">http:\/\/mng.bz\/aoem<\/a>.<br \/>\n[1] \u6211\u81ea\u5df1\u4e5f\u9047\u5230\u8fc7\u8fd9\u4e2a\u95ee\u9898\u3002\u60a8\u53ef\u4ee5\u5728\u6211\u7684\u535a\u5ba2\u4e0a\u8be6\u7ec6\u9605\u8bfb\u5b83\u4ee5\u53ca\u6211\u662f\u5982\u4f55\u89e3\u51b3\u7684\uff1a<a href=\"http:\/\/mng.bz\/aoem\">http:\/\/mng.bz\/aoem<\/a>\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>27 Publishing and deploying your application 27 \u53d1\u5e03\u548c\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f This chapter covers \u672c\u7ae0\u6db5\u76d6 \u2022 Publishing an ASP.NET Core application \u53d1\u5e03 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f \u2022 Hosting an ASP.NET Core application in IIS \u5728 IIS\u4e2d\u6258\u7ba1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f \u2022 Customizing the URLs for an ASP.NET Core app \u81ea\u5b9a\u4e49 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684 URL We\u2019ve covered a vast amount of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-625","post","type-post","status-publish","format-standard","hentry","category-csharp"],"_links":{"self":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=625"}],"version-history":[{"count":0,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/625\/revisions"}],"wp:attachment":[{"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}