{"id":572,"date":"2025-04-05T03:19:05","date_gmt":"2025-04-04T19:19:05","guid":{"rendered":"https:\/\/www.hyy.net\/?p=572"},"modified":"2025-04-05T03:19:05","modified_gmt":"2025-04-04T19:19:05","slug":"asp-net-core-in-action-3-your-%ef%ac%81rst-application","status":"publish","type":"post","link":"https:\/\/diji.net\/?p=572","title":{"rendered":"ASP.NET Core in Action 3 Your \ufb01rst application"},"content":{"rendered":"<p>ASP.NET Core in Action 3 Your first application<\/p>\n<h2>3 Your first application<\/h2>\n<h2>3 \u60a8\u7684\u7b2c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f<\/h2>\n<h3>This chapter covers<\/h3>\n<h3>\u672c\u7ae0\u6db5\u76d6<\/h3>\n<ul>\n<li>Creating your first ASP.NET Core web application Running your application<br \/>\n\u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a ASP.NET Core Web \u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f<\/li>\n<\/ul>\n<p>*Understanding the components of your application<br \/>\n\u4e86\u89e3\u5e94\u7528\u7a0b\u5e8f\u7684\u7ec4\u4ef6<\/p>\n<p>In the previous chapters, I gave you an overview of how ASP.NET Core applications work and when you should use them. Now you should set up a development environment to use for building applications.<\/p>\n<p>\u5728\u524d\u9762\u7684\u7ae0\u8282\u4e2d\uff0c\u6211\u6982\u8ff0\u4e86 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u5de5\u4f5c\u539f\u7406\u4ee5\u53ca\u4f55\u65f6\u5e94\u8be5\u4f7f\u7528\u5b83\u4eec\u3002\u73b0\u5728\uff0c\u60a8\u5e94\u8be5\u8bbe\u7f6e\u4e00\u4e2a\u7528\u4e8e\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u5f00\u53d1\u73af\u5883\u3002<\/p>\n<p><strong>TIP<\/strong> See appendix A for guidance on installing the .NET 7 software development kit (SDK) and choosing an editor\/integrated development environment (IDE) for building ASP.NET Core apps.<br \/>\n<strong>\u63d0\u793a\uff1a<\/strong>\u6709\u5173\u5b89\u88c5 .NET 7 \u8f6f\u4ef6\u5f00\u53d1\u5de5\u5177\u5305 \uff08SDK\uff09 \u548c\u9009\u62e9\u7f16\u8f91\u5668\/\u96c6\u6210\u5f00\u53d1\u73af\u5883 \uff08IDE\uff09 \u4ee5\u6784\u5efa ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u6307\u5bfc\uff0c\u8bf7\u53c2\u9605\u9644\u5f55 A\u3002<\/p>\n<p>In this chapter, you'll dive right in by creating your \ufb01rst web app. You'll get to kick the tires and poke around a little to get a feel for how it works. In later chapters, I\u2019ll show you how to go about customizing and building your own applications.<\/p>\n<p>\u5728\u672c\u7ae0\u4e2d\uff0c\u60a8\u5c06\u901a\u8fc7\u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a Web \u5e94\u7528\u7a0b\u5e8f\u6765\u6df1\u5165\u4e86\u89e3\u3002\u60a8\u5c06\u53ef\u4ee5\u8e22\u8f6e\u80ce\u5e76\u56db\u5904\u63a2\u67e5\uff0c\u4ee5\u4e86\u89e3\u5b83\u7684\u5de5\u4f5c\u539f\u7406\u3002\u5728\u540e\u9762\u7684\u7ae0\u8282\u4e2d\uff0c\u6211\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u81ea\u5b9a\u4e49\u548c\u6784\u5efa\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>As you work through this chapter, you should begin to get a grasp of the various components that make up an ASP.NET Core application, as well as an understanding of the general application-building process. Most applications you create will start from a similar template, so it\u2019s a good idea to get familiar with the setup as soon as possible.<\/p>\n<p>\u5728\u5b66\u4e60\u672c\u7ae0\u65f6\uff0c\u60a8\u5e94\u8be5\u5f00\u59cb\u638c\u63e1\u6784\u6210 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u5404\u79cd\u7ec4\u4ef6\uff0c\u5e76\u4e86\u89e3\u4e00\u822c\u7684\u5e94\u7528\u7a0b\u5e8f\u6784\u5efa\u8fc7\u7a0b\u3002\u60a8\u521b\u5efa\u7684\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u90fd\u5c06\u4ece\u7c7b\u4f3c\u7684\u6a21\u677f\u5f00\u59cb\uff0c\u56e0\u6b64\u6700\u597d\u5c3d\u5feb\u719f\u6089\u8bbe\u7f6e\u3002<\/p>\n<p><strong>DEFINITION<\/strong> A template provides the basic code required to build an application. You can use a template as the starting point for building your own apps.<br \/>\n<strong>\u5b9a\u4e49<\/strong> \u6a21\u677f\u63d0\u4f9b\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u57fa\u672c\u4ee3\u7801\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528\u6a21\u677f\u4f5c\u4e3a\u8d77\u70b9\u7528\u4e8e\u6784\u5efa\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>I\u2019ll start by showing you how to create a basic ASP.NET Core application using one of the Visual Studio templates. If you\u2019re using other tooling, such as the .NET command-line interface (CLI), you\u2019ll have similar templates available. I use Visual Studio 2022 and ASP.NET Core 7 with .NET 7 in this chapter, but I also provide tips for working with the .NET CLI.<\/p>\n<p>\u9996\u5148\uff0c\u6211\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u4f7f\u7528\u5176\u4e2d\u4e00\u4e2a Visual Studio \u6a21\u677f\u521b\u5efa\u57fa\u672c\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u3002\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f\u5176\u4ed6\u5de5\u5177\uff0c\u4f8b\u5982 .NET \u547d\u4ee4\u884c\u754c\u9762 \uff08CLI\uff09\uff0c\u60a8\u5c06\u6709\u7c7b\u4f3c\u7684\u6a21\u677f\u53ef\u7528\u3002\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u5c06 Visual Studio 2022 \u548c ASP.NET Core 7 \u4e0e .NET 7 \u7ed3\u5408\u4f7f\u7528\uff0c\u4f46\u6211\u4e5f\u63d0\u4f9b\u4e86\u4f7f\u7528 .NET CLI \u7684\u63d0\u793a\u3002<\/p>\n<p><strong>TIP<\/strong> You can view the application code for this chapter in the GitHub repository for the book at <a href=\"http:\/\/mng.bz\/5wj1\">http:\/\/mng.bz\/5wj1<\/a>.<br \/>\n<strong>\u63d0\u793a<\/strong> \u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/5wj1\">http:\/\/mng.bz\/5wj1<\/a> \u672c\u4e66\u7684 GitHub \u5b58\u50a8\u5e93\u4e2d\u67e5\u770b\u672c\u7ae0\u7684\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801\u3002<\/p>\n<p>After you\u2019ve created your application, I\u2019ll show you how to restore all the necessary dependencies, compile your application, and run it to see the output. The application will be simple, containing the bare bones of an ASP.NET Core application that responds with &quot;Hello World!&quot;<\/p>\n<p>\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\u540e\uff0c\u6211\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u6062\u590d\u6240\u6709\u5fc5\u8981\u7684\u4f9d\u8d56\u9879\u3001\u7f16\u8bd1\u5e94\u7528\u7a0b\u5e8f\u5e76\u8fd0\u884c\u5b83\u4ee5\u67e5\u770b\u8f93\u51fa\u3002\u8be5\u5e94\u7528\u7a0b\u5e8f\u5c06\u5f88\u7b80\u5355\uff0c\u5305\u542b ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u57fa\u672c\u6846\u67b6\uff0c\u8be5\u5e94\u7528\u7a0b\u5e8f\u4ee5 \u201cHello World\uff01<\/p>\n<p>Having run your application, your next step is understanding what\u2019s going on! We\u2019ll take a journey through the ASP.NET Core application, looking at each \ufb01le in the template in turn. You\u2019ll get a feel for how an ASP.NET Core application is laid out and see what the C# code for the smallest possible app looks like.<\/p>\n<p>\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u540e\uff0c\u4e0b\u4e00\u6b65\u662f\u4e86\u89e3\u53d1\u751f\u4e86\u4ec0\u4e48\uff01\u6211\u4eec\u5c06\u6d4f\u89c8 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f9d\u6b21\u67e5\u770b\u6a21\u677f\u4e2d\u7684\u6bcf\u4e2a\u6587\u4ef6\u3002\u60a8\u5c06\u4e86\u89e3 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u5e03\u5c40\u65b9\u5f0f\uff0c\u5e76\u4e86\u89e3\u5c3d\u53ef\u80fd\u5c0f\u7684\u5e94\u7528\u7a0b\u5e8f\u7684 C# \u4ee3\u7801\u662f\u4ec0\u4e48\u6837\u5b50\u7684\u3002<\/p>\n<p>As a \ufb01nal twist, you\u2019ll see how to extend your application to handle requests for static \ufb01les, as well as how to create a simple API that returns data in standard JavaScript Object Notation (JSON) format.<\/p>\n<p>\u6700\u540e\uff0c\u60a8\u5c06\u4e86\u89e3\u5982\u4f55\u6269\u5c55\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5904\u7406\u5bf9\u9759\u6001\u6587\u4ef6\u7684\u8bf7\u6c42\uff0c\u4ee5\u53ca\u5982\u4f55\u521b\u5efa\u4ee5\u6807\u51c6 JavaScript \u5bf9\u8c61\u8868\u793a\u6cd5 \uff08JSON\uff09 \u683c\u5f0f\u8fd4\u56de\u6570\u636e\u7684\u7b80\u5355 API\u3002<\/p>\n<p>At this stage, don\u2019t worry if you \ufb01nd parts of the project confusing or complicated; you\u2019ll be exploring each section in detail as you move through the book. By the end of the chapter, you should have a basic understanding of how ASP.NET Core applications are put together, from when your application is \ufb01rst run to when a response is generated. Before we begin, though, we\u2019ll review how ASP.NET Core applications handle requests.<\/p>\n<p>\u5728\u8fd9\u4e2a\u9636\u6bb5\uff0c\u5982\u679c\u60a8\u53d1\u73b0\u9879\u76ee\u7684\u67d0\u4e9b\u90e8\u5206\u4ee4\u4eba\u56f0\u60d1\u6216\u590d\u6742\uff0c\u8bf7\u4e0d\u8981\u62c5\u5fc3;\u5728\u9605\u8bfb\u672c\u4e66\u65f6\uff0c\u60a8\u5c06\u8be6\u7ec6\u63a2\u7d22\u6bcf\u4e2a\u90e8\u5206\u3002\u5728\u672c\u7ae0\u7ed3\u675f\u65f6\uff0c\u60a8\u5e94\u8be5\u5bf9 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u662f\u5982\u4f55\u7ec4\u5408\u5728\u4e00\u8d77\u7684\uff0c\u4ece\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5f00\u59cb\uff0c\u60a8\u5e94\u8be5\u6709\u4e00\u4e2a\u57fa\u672c\u7684\u4e86\u89e3run \u5230\u751f\u6210\u54cd\u5e94\u65f6\u3002\u4e0d\u8fc7\uff0c\u5728\u5f00\u59cb\u4e4b\u524d\uff0c\u6211\u4eec\u5c06\u56de\u987e\u4e00\u4e0b ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u5904\u7406\u8bf7\u6c42\u3002<\/p>\n<h3>3.1 A brief overview of an ASP.NET Core application\u200c<\/h3>\n<h3>3.1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6982\u8ff0<\/h3>\n<p>In chapter 1, I described how a browser makes an HTTP request to a server and receives a response, which it uses to render HTML on the page. ASP.NET Core allows you to generate that HTML dynamically depending on the particulars of the request, so that (for example) you can display di\ufb00erent data depending on the current logged-in user.<\/p>\n<p>\u5728\u7b2c 1 \u7ae0\u4e2d\uff0c\u6211\u4ecb\u7ecd\u4e86\u6d4f\u89c8\u5668\u5982\u4f55\u5411\u670d\u52a1\u5668\u53d1\u51fa HTTP \u8bf7\u6c42\u5e76\u63a5\u6536\u54cd\u5e94\uff0c\u5e76\u4f7f\u7528\u8be5\u54cd\u5e94\u5728\u9875\u9762\u4e0a\u5448\u73b0 HTML\u3002ASP.NET Core \u5141\u8bb8\u60a8\u6839\u636e\u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\u52a8\u6001\u751f\u6210\u8be5 HTML\uff0c\u4ee5\u4fbf\uff08\u4f8b\u5982\uff09\u60a8\u53ef\u4ee5\u6839\u636e\u5f53\u524d\u767b\u5f55\u7684\u7528\u6237\u663e\u793a\u4e0d\u540c\u7684\u6570\u636e\u3002<\/p>\n<p>Suppose that you want to create a web app to display information about your company. You could create a simple ASP.NET Core app to achieve this goal; later, you could add dynamic features to your app. Figure 3.1 shows how the application would handle a request for a page in your application.<\/p>\n<p>\u5047\u8bbe\u60a8\u8981\u521b\u5efa\u4e00\u4e2a Web \u5e94\u7528\u7a0b\u5e8f\u6765\u663e\u793a\u6709\u5173\u60a8\u516c\u53f8\u7684\u4fe1\u606f\u3002\u60a8\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u7b80\u5355\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6765\u5b9e\u73b0\u6b64\u76ee\u6807;\u7a0d\u540e\uff0c\u60a8\u53ef\u4ee5\u5411\u5e94\u7528\u7a0b\u5e8f\u6dfb\u52a0\u52a8\u6001\u529f\u80fd\u3002\u56fe 3.1 \u663e\u793a\u4e86\u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u5904\u7406\u5bf9\u5e94\u7528\u7a0b\u5e8f\u4e2d\u9875\u9762\u7684\u8bf7\u6c42\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0301.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.1 An overview of an ASP.NET Core application. The ASP.NET Core application receives an incoming HTTP request from the browser. Every request passes to the middleware pipeline, which potentially modi\ufb01es it and then passes it to the endpoint middleware at the end of the pipeline to generate a response. The response passes back through the middleware to the server and \ufb01nally out to the browser.<\/p>\n<p>\u56fe 3.1 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6982\u8ff0\u3002ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4ece\u6d4f\u89c8\u5668\u63a5\u6536\u4f20\u5165\u7684 HTTP \u8bf7\u6c42\u3002\u6bcf\u4e2a\u8bf7\u6c42\u90fd\u4f1a\u4f20\u9012\u5230\u4e2d\u95f4\u4ef6\u7ba1\u9053\uff0c\u4e2d\u95f4\u4ef6\u7ba1\u9053\u53ef\u80fd\u4f1a\u5bf9\u5176\u8fdb\u884c\u4fee\u6539\uff0c\u7136\u540e\u5c06\u5176\u4f20\u9012\u5230\u7ba1\u9053\u672b\u5c3e\u7684\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\u4ee5\u751f\u6210\u54cd\u5e94\u3002\u54cd\u5e94\u901a\u8fc7\u4e2d\u95f4\u4ef6\u4f20\u56de\u670d\u52a1\u5668\uff0c\u6700\u540e\u4f20\u56de\u6d4f\u89c8\u5668\u3002<\/p>\n<p>Much of this diagram should be familiar to you from \ufb01gure 1.3 in chapter 1; the request and response and the ASP.NET Core web server are still there. But you\u2019ll notice that I\u2019ve added a reverse proxy to show a common deployment pattern for ASP.NET Core applications. I\u2019ve also expanded the ASP.NET Core application itself to show the middleware pipeline and the endpoint middleware\u2014the main custom part of your app that goes into generating the response from a request.<\/p>\n<p>\u60a8\u5e94\u8be5\u4ece\u7b2c 1 \u7ae0\u7684\u56fe 1.3 \u4e2d\u719f\u6089\u6b64\u56fe\u8868\u7684\u5927\u90e8\u5206\u5185\u5bb9;\u8bf7\u6c42\u548c\u54cd\u5e94\u4ee5\u53ca ASP.NET Core Web \u670d\u52a1\u5668\u4ecd\u7136\u5b58\u5728\u3002\u4f46\u60a8\u4f1a\u6ce8\u610f\u5230\uff0c\u6211\u6dfb\u52a0\u4e86\u4e00\u4e2a\u53cd\u5411\u4ee3\u7406\u6765\u663e\u793a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u5e38\u89c1\u90e8\u7f72\u6a21\u5f0f\u3002\u6211\u8fd8\u6269\u5c55\u4e86 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u672c\u8eab\uff0c\u4ee5\u663e\u793a\u4e2d\u95f4\u4ef6\u7ba1\u9053\u548c\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\uff0c\u540e\u8005\u662f\u5e94\u7528\u7a0b\u5e8f\u7684\u4e3b\u8981\u81ea\u5b9a\u4e49\u90e8\u5206\uff0c\u7528\u4e8e\u4ece\u8bf7\u6c42\u751f\u6210\u54cd\u5e94\u3002<\/p>\n<p>The \ufb01rst port of call after the reverse proxy forwards a request is the ASP.NET Core web server, which is the default cross-platform Kestrel server. Kestrel takes the raw incoming network request and uses it to generate an HttpContext object that the rest of the application can use.<\/p>\n<p>\u53cd\u5411\u4ee3\u7406\u8f6c\u53d1\u8bf7\u6c42\u540e\u7684\u7b2c\u4e00\u4e2a\u8c03\u7528\u7aef\u53e3\u662f ASP.NET Core Web \u670d\u52a1\u5668\uff0c\u5b83\u662f\u9ed8\u8ba4\u7684\u8de8\u5e73\u53f0 Kestrel \u670d\u52a1\u5668\u3002Kestrel \u83b7\u53d6\u539f\u59cb\u4f20\u5165\u7f51\u7edc\u8bf7\u6c42\uff0c\u5e76\u4f7f\u7528\u5b83\u6765\u751f\u6210\u5e94\u7528\u7a0b\u5e8f\u5176\u4f59\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528\u7684 HttpContext \u5bf9\u8c61\u3002<\/p>\n<blockquote>\n<p>The HttpContext object<br \/>\nHttpContext \u5bf9\u8c61<br \/>\nThe HttpContext constructed by the ASP.NET Core web server is used by the application as a sort of storage box for a single request. Anything that\u2019s speci\ufb01c to this particular request and the subsequent response can be associated with it and stored in it, such as properties of the request, request-speci\ufb01c services, data that\u2019s been loaded, or errors that have occurred. The web server \ufb01lls the initial HttpContext with details of the original HTTP request and other con\ufb01guration details and then passes it on to the rest of the application.<br \/>\n\u7531 ASP.NET Core Web \u670d\u52a1\u5668\u6784\u5efa\u7684 HttpContext \u88ab\u5e94\u7528\u7a0b\u5e8f\u7528\u4f5c\u5355\u4e2a\u8bf7\u6c42\u7684\u4e00\u79cd\u5b58\u50a8\u76d2\u3002\u7279\u5b9a\u4e8e\u6b64\u7279\u5b9a\u8bf7\u6c42\u548c\u540e\u7eed\u54cd\u5e94\u7684\u4efb\u4f55\u5185\u5bb9\u90fd\u53ef\u4ee5\u4e0e\u8be5\u8bf7\u6c42\u76f8\u5173\u8054\u5e76\u5b58\u50a8\u5728\u5176\u4e2d\uff0c\u4f8b\u5982\u8bf7\u6c42\u7684\u5c5e\u6027\u3001\u7279\u5b9a\u4e8e\u8bf7\u6c42\u7684\u670d\u52a1\u3001\u5df2\u52a0\u8f7d\u7684\u6570\u636e\u6216\u5df2\u53d1\u751f\u7684\u9519\u8bef\u3002Web \u670d\u52a1\u5668\u4f7f\u7528\u539f\u59cb HTTP \u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\u548c\u5176\u4ed6\u914d\u7f6e\u8be6\u7ec6\u4fe1\u606f\u586b\u5145\u521d\u59cb HttpContext\uff0c\u7136\u540e\u5c06\u5176\u4f20\u9012\u7ed9\u5e94\u7528\u7a0b\u5e8f\u7684\u5176\u4f59\u90e8\u5206\u3002<\/p>\n<\/blockquote>\n<p><strong>NOTE<\/strong> Kestrel isn\u2019t the only HTTP server available in ASP.NET Core, but it\u2019s the most performant and is cross-platform. I\u2019ll refer only to Kestrel throughout the book. A di\ufb00erent web server, IIS HTTP Server, is used when running in-process in Internet Information Services (IIS). The main alternative, HTTP.sys, runs only in Windows and can\u2019t be used with IIS.1<\/p>\n<p><strong>\u6ce8\u610f<\/strong> Kestrel \u5e76\u4e0d\u662f ASP.NET Core \u4e2d\u552f\u4e00\u53ef\u7528\u7684 HTTP \u670d\u52a1\u5668\uff0c\u4f46\u5b83\u662f\u6027\u80fd\u6700\u9ad8\u7684\uff0c\u5e76\u4e14\u662f\u8de8\u5e73\u53f0\u7684\u3002\u6211\u5728\u6574\u672c\u4e66\u4e2d\u53ea\u63d0\u5230\u7ea2\u96bc\u3002\u5728 Internet Information Services \uff08IIS\uff09 \u4e2d\u8fdb\u884c\u8fdb\u7a0b\u5185\u8fd0\u884c\u65f6\uff0c\u4f1a\u4f7f\u7528\u4e0d\u540c\u7684 Web \u670d\u52a1\u5668 IIS HTTP Server\u3002\u4e3b\u8981\u66ff\u4ee3\u65b9\u6848 HTTP.sys \u4ec5\u5728 Windows \u4e2d\u8fd0\u884c\uff0c\u4e0d\u80fd\u4e0e IIS \u4e00\u8d77\u4f7f\u7528\u30021<\/p>\n<p>Kestrel is responsible for receiving the request data and constructing a .NET representation of the request, but it doesn\u2019t attempt to generate a response directly. For that task, Kestrel hands the HttpContext to the middleware pipeline in every ASP.NET Core application. This pipeline is a series of components that process the incoming request to perform common operations such as logging, handling exceptions, and serving static \ufb01les.<\/p>\n<p>Kestrel \u8d1f\u8d23\u63a5\u6536\u8bf7\u6c42\u6570\u636e\u5e76\u6784\u9020\u8bf7\u6c42\u7684 .NET \u8868\u793a\u5f62\u5f0f\uff0c\u4f46\u5b83\u4e0d\u4f1a\u5c1d\u8bd5\u76f4\u63a5\u751f\u6210\u54cd\u5e94\u3002\u5bf9\u4e8e\u8be5\u4efb\u52a1\uff0cKestrel \u5c06 HttpContext \u4ea4\u7ed9\u6bcf\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002\u6b64\u7ba1\u9053\u662f\u4e00\u7cfb\u5217\u7ec4\u4ef6\uff0c\u7528\u4e8e\u5904\u7406\u4f20\u5165\u8bf7\u6c42\u4ee5\u6267\u884c\u5e38\u89c1\u4f5c\uff0c\u4f8b\u5982\u65e5\u5fd7\u8bb0\u5f55\u3001\u5904\u7406\u5f02\u5e38\u548c\u63d0\u4f9b\u9759\u6001\u6587\u4ef6\u3002<\/p>\n<p><strong>NOTE<\/strong> You\u2019ll learn about the middleware pipeline in detail in chapter 4.<br \/>\n<strong>\u6ce8\u610f\uff1a<\/strong>\u60a8\u5c06\u5728\u7b2c 4 \u7ae0\u4e2d\u8be6\u7ec6\u4e86\u89e3\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002<\/p>\n<p>At the end of the middleware pipeline is the endpoint middleware, which is responsible for calling the code that generates the \ufb01nal response. In most applications that code will be a Model-View-Controller (MVC), Razor Pages, or minimal API endpoint.<\/p>\n<p>\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u672b\u7aef\u662f\u7aef\u70b9\u4e2d\u95f4\u4ef6\uff0c\u5b83\u8d1f\u8d23\u8c03\u7528\u751f\u6210\u6700\u7ec8\u54cd\u5e94\u7684\u4ee3\u7801\u3002\u5728\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u8be5\u4ee3\u7801\u5c06\u662f\u6a21\u578b-\u89c6\u56fe-\u63a7\u5236\u5668 \uff08MVC\uff09\u3001Razor Pages \u6216\u6700\u5c0f API \u7ec8\u7ed3\u70b9\u3002<\/p>\n<p>Most ASP.NET Core applications follow this basic architecture, and the example in this chapter is no di\ufb00erent. First, you\u2019ll see how to create and run your application; then you\u2019ll look at how the code corresponds to the outline in \ufb01gure 3.1. Without further ado, let\u2019s create an application!<\/p>\n<p>\u5927\u591a\u6570 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u90fd\u9075\u5faa\u6b64\u57fa\u672c\u4f53\u7cfb\u7ed3\u6784\uff0c\u672c\u7ae0\u4e2d\u7684\u793a\u4f8b\u4e5f\u4e0d\u4f8b\u5916\u3002\u9996\u5148\uff0c\u60a8\u5c06\u4e86\u89e3\u5982\u4f55\u521b\u5efa\u548c\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f;\u7136\u540e\uff0c\u60a8\u5c06\u4e86\u89e3\u4ee3\u7801\u5982\u4f55\u4e0e\u56fe 3.1 \u4e2d\u7684\u5927\u7eb2\u76f8\u5bf9\u5e94\u3002\u4e8b\u4e0d\u5b9c\u8fdf\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\uff01<\/p>\n<h3>3.2 Creating your \ufb01rst ASP.NET Core application\u200c<\/h3>\n<h3>3.2 \u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f<\/h3>\n<p>In this section you\u2019re going to create a minimal API application that returns &quot;Hello World!&quot; when you call the HTTP API. This application is about the simplest ASP.NET Core application you can create, but it demonstrates many of the fundamental concepts of building and running applications with .NET.<\/p>\n<p>\u5728\u672c\u8282\u4e2d\uff0c\u60a8\u5c06\u521b\u5efa\u4e00\u4e2a\u8fd4\u56de \u201cHello World\uff01\u201d \u7684\u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\u3002\u5f53\u60a8\u8c03\u7528 HTTP API \u65f6\u3002\u6b64\u5e94\u7528\u7a0b\u5e8f\u662f\u60a8\u53ef\u4ee5\u521b\u5efa\u7684\u6700\u7b80\u5355\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u5b83\u6f14\u793a\u4e86\u4f7f\u7528 .NET \u6784\u5efa\u548c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\u8bb8\u591a\u57fa\u672c\u6982\u5ff5\u3002<\/p>\n<p>You can start building applications with ASP.NET Core in many ways, depending on the tools and operating system you\u2019re using. Each set of tools has slightly di\ufb00erent templates, but the templates have many similarities. The example used throughout this chapter is based on a Visual Studio 2022 template, but you can easily follow along with templates from the .NET CLI or Visual Studio for Mac.<\/p>\n<p>\u60a8\u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u5f00\u59cb\u4f7f\u7528 ASP.NET Core \u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u60a8\u4f7f\u7528\u7684\u5de5\u5177\u548c\u4f5c\u7cfb\u7edf\u3002\u6bcf\u7ec4\u5de5\u5177\u7684\u6a21\u677f\u7565\u6709\u4e0d\u540c\uff0c\u4f46\u6a21\u677f\u6709\u8bb8\u591a\u76f8\u4f3c\u4e4b\u5904\u3002\u672c\u7ae0\u4e2d\u4f7f\u7528\u7684\u793a\u4f8b\u57fa\u4e8e Visual Studio 2022 \u6a21\u677f\uff0c\u4f46\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u4f7f\u7528 .NET CLI \u6216 Visual Studio for Mac \u4e2d\u7684\u6a21\u677f\u8fdb\u884c\u4f5c\u3002<\/p>\n<p><strong>NOTE<\/strong> As a reminder, I use Visual Studio 2022 and ASP.NET Core with .NET 7 throughout the book.<br \/>\n<strong>\u6ce8\u610f\uff1a<\/strong>\u63d0\u9192\u4e00\u4e0b\uff0c\u6211\u5728\u6574\u672c\u4e66\u4e2d\u4f7f\u7528\u4e86 Visual Studio 2022 \u548c ASP.NET Core \u548c .NET 7\u3002<\/p>\n<p>Getting an application up and running locally typically involves four basic steps, which we\u2019ll work through in this chapter:<\/p>\n<p>\u5728\u672c\u5730\u542f\u52a8\u548c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u901a\u5e38\u6d89\u53ca\u56db\u4e2a\u57fa\u672c\u6b65\u9aa4\uff0c\u6211\u4eec\u5c06\u5728\u672c\u7ae0\u4e2d\u4ecb\u7ecd\u8fd9\u4e9b\u6b65\u9aa4\uff1a<\/p>\n<ol>\n<li>\n<p>Generate\u2014Create the base application from a template to get started.<br \/>\n\u751f\u6210 - \u4ece\u6a21\u677f\u521b\u5efa\u57fa\u672c\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5f00\u59cb\u4f7f\u7528\u3002<\/p>\n<\/li>\n<li>\n<p>Restore\u2014Restore all the packages and dependencies to the local project folder using NuGet.<br \/>\n\u8fd8\u539f - \u4f7f\u7528 NuGet \u5c06\u6240\u6709\u5305\u548c\u4f9d\u8d56\u9879\u8fd8\u539f\u5230\u672c\u5730\u9879\u76ee\u6587\u4ef6\u5939\u3002<\/p>\n<\/li>\n<li>\n<p>Build\u2014Compile the application, and generate all the necessary artifacts.<br \/>\n\u6784\u5efa - \u7f16\u8bd1\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u751f\u6210\u6240\u6709\u5fc5\u8981\u7684\u5de5\u4ef6\u3002<\/p>\n<\/li>\n<li>\n<p>Run\u2014Run the compiled application.<br \/>\n\u8fd0\u884c - \u8fd0\u884c\u7f16\u8bd1\u540e\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<\/li>\n<\/ol>\n<p>Visual Studio and the .NET CLI include many ASP.NET Core templates for building di\ufb00erent types of applications, such as<\/p>\n<p>Visual Studio \u548c .NET CLI \u5305\u542b\u8bb8\u591a ASP.NET Core \u6a21\u677f\uff0c\u7528\u4e8e\u6784\u5efa\u4e0d\u540c\u7c7b\u578b\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u4f8b\u5982<\/p>\n<ul>\n<li>\n<p>Minimal API applications\u2014HTTP API applications that return data in JSON format, which can be consumed by single-page applications (SPAs) and mobile apps.They\u2019re typically used in conjunction with client-side applications such as Angular and React.js or mobile applications.<br \/>\n\u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f \u2014 \u4ee5 JSON \u683c\u5f0f\u8fd4\u56de\u6570\u636e\u7684 HTTP API \u5e94\u7528\u7a0b\u5e8f\uff0c\u53ef\u4f9b\u5355\u9875\u5e94\u7528\u7a0b\u5e8f \uff08SPA\uff09 \u548c\u79fb\u52a8\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u3002\u5b83\u4eec\u901a\u5e38\u4e0e\u5ba2\u6237\u7aef\u5e94\u7528\u7a0b\u5e8f\uff08\u5982 Angular \u548c React.js\uff09\u6216\u79fb\u52a8\u5e94\u7528\u7a0b\u5e8f\u7ed3\u5408\u4f7f\u7528\u3002<\/p>\n<\/li>\n<li>\n<p>Razor Pages web applications\u2014Razor Pages applications generate HTML on the server and are designed to be viewed by users in a web browser directly.<br \/>\nRazor Pages Web \u5e94\u7528\u7a0b\u5e8f - Razor Pages \u5e94\u7528\u7a0b\u5e8f\u5728\u670d\u52a1\u5668\u4e0a\u751f\u6210 HTML\uff0c\u65e8\u5728\u4f9b\u7528\u6237\u5728 Web \u6d4f\u89c8\u5668\u4e2d\u76f4\u63a5\u67e5\u770b\u3002<\/p>\n<\/li>\n<li>\n<p>MVC applications\u2014MVC applications are similar to Razor Pages apps in that they generate HTML on the server and are designed to be viewed by users directly in a web browser. They use traditional MVC controllers instead of Razor Pages.<br \/>\nMVC \u5e94\u7528\u7a0b\u5e8f - MVC \u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e Razor Pages \u5e94\u7528\u7a0b\u5e8f\uff0c\u56e0\u4e3a\u5b83\u4eec\u5728\u670d\u52a1\u5668\u4e0a\u751f\u6210 HTML\uff0c\u5e76\u4e14\u65e8\u5728\u4f9b\u7528\u6237\u76f4\u63a5\u5728 Web \u6d4f\u89c8\u5668\u4e2d\u67e5\u770b\u3002\u5b83\u4eec\u4f7f\u7528\u4f20\u7edf\u7684 MVC \u63a7\u5236\u5668\uff0c\u800c\u4e0d\u662f Razor Pages\u3002<\/p>\n<\/li>\n<li>\n<p>Web API applications\u2014Web API applications are similar to minimal API apps, in that they are typically consumed by SPAs and mobile apps. Web API apps provide additional functionality compared to minimal APIs, at the expense of some performance and convenience.<br \/>\nWeb API \u5e94\u7528\u7a0b\u5e8f - Web API \u5e94\u7528\u7a0b\u5e8f\u7c7b\u4f3c\u4e8e\u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\uff0c\u56e0\u4e3a\u5b83\u4eec\u901a\u5e38\u7531 SPA \u548c\u79fb\u52a8\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u3002\u4e0e\u6700\u5c0f API \u76f8\u6bd4\uff0cWeb API \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u4e86\u989d\u5916\u7684\u529f\u80fd\uff0c\u4f46\u4f1a\u727a\u7272\u4e00\u4e9b\u6027\u80fd\u548c\u4fbf\u5229\u6027\u3002<\/p>\n<\/li>\n<\/ul>\n<p>We\u2019ll look at each of these application types in this book, but in part 1 we focus on minimal APIs, so in section 3.2.1 we start by looking at the simplest ASP.NET Core app you can create.<\/p>\n<p>\u5728\u672c\u4e66\u4e2d\uff0c\u6211\u4eec\u5c06\u4ecb\u7ecd\u8fd9\u4e9b\u5e94\u7528\u7a0b\u5e8f\u7c7b\u578b\u4e2d\u7684\u6bcf\u4e00\u79cd\uff0c\u4f46\u5728\u7b2c 1 \u90e8\u5206\u4e2d\uff0c\u6211\u4eec\u5c06\u91cd\u70b9\u4ecb\u7ecd\u6700\u5c0f\u7684 API\uff0c\u56e0\u6b64\u5728\u7b2c 3.2.1 \u8282\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u4ecb\u7ecd\u60a8\u53ef\u4ee5\u521b\u5efa\u7684\u6700\u7b80\u5355\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<h4>3.2.1 Using a template to get started\u200c<\/h4>\n<h4>3.2.1 \u4f7f\u7528\u6a21\u677f\u5f00\u59cb<\/h4>\n<p>In this section you\u2019ll use a template to create your \ufb01rst ASP.NET Core minimal API application. Using a template can get you up and running with an application quickly, automatically con\ufb01guring many of the fundamental pieces. Both Visual Studio and the .NET CLI come with standard templates for building web applications, console applications, and class libraries.<\/p>\n<p>\u5728\u672c\u90e8\u5206\u4e2d\uff0c\u60a8\u5c06\u4f7f\u7528\u6a21\u677f\u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a ASP.NET Core \u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\u3002\u4f7f\u7528\u6a21\u677f\u53ef\u4ee5\u4f7f\u60a8\u5feb\u901f\u542f\u52a8\u5e76\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u81ea\u52a8\u914d\u7f6e\u8bb8\u591a\u57fa\u672c\u90e8\u5206\u3002Visual Studio \u548c .NET CLI \u90fd\u9644\u5e26\u4e86\u7528\u4e8e\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u548c\u7c7b\u5e93\u7684\u6807\u51c6\u6a21\u677f\u3002<\/p>\n<p><strong>TIP<\/strong> In .NET, a project is a unit of deployment, which will be compiled into a .dll \ufb01le or an executable, for example. Each separate app is a separate project. Multiple projects can be built and developed at the same time in a solution.<br \/>\n<strong>\u63d0\u793a<\/strong> \u5728 .NET \u4e2d\uff0c\u9879\u76ee\u662f\u4e00\u4e2a\u90e8\u7f72\u5355\u5143\uff0c\u4f8b\u5982\uff0c\u5b83\u5c06\u88ab\u7f16\u8bd1\u6210 .dll \u6587\u4ef6\u6216\u53ef\u6267\u884c\u6587\u4ef6\u3002\u6bcf\u4e2a\u5355\u72ec\u7684\u5e94\u7528\u7a0b\u5e8f\u90fd\u662f\u4e00\u4e2a\u5355\u72ec\u7684\u9879\u76ee\u3002\u53ef\u4ee5\u5728\u89e3\u51b3\u65b9\u6848\u4e2d\u540c\u65f6\u751f\u6210\u548c\u5f00\u53d1\u591a\u4e2a\u9879\u76ee\u3002<\/p>\n<p>To create your \ufb01rst web application, open Visual Studio, and perform the following steps:<\/p>\n<p>\u8981\u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a Web \u5e94\u7528\u7a0b\u5e8f\uff0c\u8bf7\u6253\u5f00 Visual Studio\uff0c\u7136\u540e\u6267\u884c\u4ee5\u4e0b\u6b65\u9aa4\uff1a<\/p>\n<ol>\n<li>\n<p>Choose Create a New Project from the splash screen, or choose File &gt; New &gt; Project from the main Visual Studio screen.<br \/>\n\u4ece\u521d\u59cb\u5c4f\u5e55\u4e2d\u9009\u62e9 Create a New Project\uff0c\u6216\u4ece Visual Studio \u4e3b\u5c4f\u5e55\u4e2d\u9009\u62e9 File &gt; New &gt; Project\u3002<\/p>\n<\/li>\n<li>\n<p>From the list of templates, choose ASP.NET Core Empty; select the C# language template, as shown in \ufb01gure 3.2; and then choose Next.<br \/>\n\u4ece\u6a21\u677f\u5217\u8868\u4e2d\uff0c\u9009\u62e9 ASP.NET Core Empty;\u9009\u62e9 C# \u8bed\u8a00\u6a21\u677f\uff0c\u5982\u56fe 3.2 \u6240\u793a;\uff0c\u7136\u540e\u9009\u62e9 Next \uff08\u4e0b\u4e00\u6b65\uff09<\/p>\n<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0302.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.2 The Create a New Project dialog box. Select the C# ASP.NET Core Empty template in the list on the right side. When you next create a new project, you can choose a template from the Recent Project Templates list on the left side.<\/p>\n<p>\u56fe 3.2 \u201c\u521b\u5efa\u65b0\u9879\u76ee\u201d\u5bf9\u8bdd\u6846\u3002\u5728\u53f3\u4fa7\u7684\u5217\u8868\u4e2d\u9009\u62e9 C# ASP.NET Core Empty \u6a21\u677f\u3002\u4e0b\u6b21\u521b\u5efa\u65b0\u9879\u76ee\u65f6\uff0c\u60a8\u53ef\u4ee5\u4ece\u5de6\u4fa7\u7684 Recent Project Templates \uff08\u6700\u8fd1\u7684\u9879\u76ee\u6a21\u677f\uff09 \u5217\u8868\u4e2d\u9009\u62e9\u4e00\u4e2a\u6a21\u677f\u3002<\/p>\n<p>On the next screen, enter a project name, location, and solution name, and choose Create, as shown in \ufb01gure 3.3. You might use WebApplication1 as both the project and solution name, for example.<\/p>\n<p>\u5728\u4e0b\u4e00\u4e2a\u5c4f\u5e55\u4e0a\uff0c\u8f93\u5165\u9879\u76ee\u540d\u79f0\u3001\u4f4d\u7f6e\u548c\u89e3\u51b3\u65b9\u6848\u540d\u79f0\uff0c\u7136\u540e\u9009\u62e9 Create\uff08\u521b\u5efa\uff09\uff0c\u5982\u56fe3.3\u6240\u793a. \u4f8b\u5982\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 WebApplication1 \u4f5c\u4e3a\u9879\u76ee\u548c\u89e3\u51b3\u65b9\u6848\u540d\u79f0\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0303.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.3 The Con\ufb01gure Your New Project dialog box. Enter a project name, location, and solution name, and choose Next.<\/p>\n<p>\u56fe 3.3 \u201cConfigure Your New Project\u201d\uff08\u914d\u7f6e\u65b0\u9879\u76ee\uff09\u5bf9\u8bdd\u6846\u3002\u8f93\u5165\u9879\u76ee\u540d\u79f0\u3001\u4f4d\u7f6e\u548c\u89e3\u51b3\u65b9\u6848\u540d\u79f0\uff0c\u7136\u540e\u9009\u62e9 Next\uff08\u4e0b\u4e00\u6b65\uff09\u3002<\/p>\n<ol start=\"4\">\n<li>On the following screen (\ufb01gure 3.4), do the following:<br \/>\n\u5728\u4ee5\u4e0b\u5c4f\u5e55\uff08\u56fe 3.4\uff09\u4e2d\uff0c\u6267\u884c\u4ee5\u4e0b\u4f5c\uff1a<\/li>\n<\/ol>\n<p>a. Select .NET 7.0. If this option isn\u2019t available, ensure that you have .NET 7 installed. See appendix A for details on con\ufb01guring your environment.<br \/>\na.\u9009\u62e9 .NET 7.0\u3002\u5982\u679c\u6b64\u9009\u9879\u4e0d\u53ef\u7528\uff0c\u8bf7\u786e\u4fdd\u60a8\u5df2\u5b89\u88c5 .NET 7\u3002\u6709\u5173\u914d\u7f6e\u73af\u5883\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605\u9644\u5f55 A\u3002<\/p>\n<p>b. Ensure that Con\ufb01gure for HTTPS is checked.<br \/>\nb.\u786e\u4fdd\u9009\u4e2d Configure for HTTPS \uff08\u4e3a HTTPS \u914d\u7f6e\uff09\u3002<\/p>\n<p>c. Ensure that Enable Docker is not checked.<br \/>\nc.\u786e\u4fdd\u672a\u9009\u4e2d Enable Docker\u3002<\/p>\n<p>d. Ensure that Do not use top-level statements is not checked. (I explain top-level statements in section 3.6.)<br \/>\nd.\u786e\u4fdd Do not use top-level statements \u672a\u9009\u4e2d\u3002\uff08\u6211\u5728 3.6 \u8282\u4e2d\u89e3\u91ca\u4e86\u9876\u7ea7\u8bed\u53e5\uff09\u3002<\/p>\n<p>e. Choose Create.<br \/>\ne.\u9009\u62e9 Create \uff08\u521b\u5efa\uff09\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0304.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.4 The Additional Information dialog box follows the Con\ufb01gure Your New Project dialog box and lets you customize the template that will generate your application. For this starter project, you\u2019ll create an empty .NET 7 application that uses top-level statements.<\/p>\n<p>\u56fe 3.4 \u201c\u5176\u4ed6\u4fe1\u606f\u201d\u5bf9\u8bdd\u6846\u4f4d\u4e8e \u201c\u914d\u7f6e\u65b0\u9879\u76ee\u201d \u5bf9\u8bdd\u6846\u4e4b\u540e\uff0c\u5e76\u4e14\u7528\u4e8e\u81ea\u5b9a\u4e49\u5c06\u751f\u6210\u5e94\u7528\u7a0b\u5e8f\u7684\u6a21\u677f\u3002\u5bf9\u4e8e\u6b64\u521d\u5b66\u8005\u9879\u76ee\uff0c\u60a8\u5c06\u521b\u5efa\u4e00\u4e2a\u4f7f\u7528\u9876\u7ea7\u8bed\u53e5\u7684\u7a7a .NET 7 \u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<ol start=\"5\">\n<li>Wait for Visual Studio to generate the application from the template. When Visual Studio \ufb01nishes, an introductory page about ASP.NET Core appears; you should see that Visual Studio has created and added some \ufb01les to your project, as shown in \ufb01gure 3.5.<br \/>\n\u7b49\u5f85 Visual Studio \u4ece\u6a21\u677f\u751f\u6210\u5e94\u7528\u7a0b\u5e8f\u3002Visual Studio \u5b8c\u6210\u540e\uff0c\u5c06\u663e\u793a\u6709\u5173 ASP.NET Core \u7684\u4ecb\u7ecd\u6027\u9875\u9762;\u60a8\u5e94\u8be5\u770b\u5230 Visual Studio \u5df2\u7ecf\u521b\u5efa\u4e86\u4e00\u4e9b\u6587\u4ef6\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u60a8\u7684\u9879\u76ee\u4e2d\uff0c\u5982\u56fe 3.5 \u6240\u793a\u3002<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0305.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.5 Visual Studio after creating a new ASP.NET Core application from a template. The Solution Explorer shows your newly created project. The introductory page has helpful links for learning about ASP.NET Core.<\/p>\n<p>\u56fe 3.5 \u4ece\u6a21\u677f\u521b\u5efa\u65b0\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u540e\u7684 Visual Studio\u3002Solution Explorer \u5c06\u663e\u793a\u60a8\u65b0\u521b\u5efa\u7684\u9879\u76ee\u3002\u4ecb\u7ecd\u6027\u9875\u9762\u5305\u542b\u7528\u4e8e\u4e86\u89e3 ASP.NET Core \u7684\u6709\u7528\u94fe\u63a5\u3002<\/p>\n<p>If you\u2019re not using Visual Studio, you can create a similar template by using the .NET CLI. Create a folder to hold your new project. Open a PowerShell or cmd prompt in the folder (Windows) or a terminal session (Linux or macOS), and run the commands in the following listing.<\/p>\n<p>\u5982\u679c\u60a8\u4e0d\u4f7f\u7528 Visual Studio\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528 .NET CLI \u521b\u5efa\u7c7b\u4f3c\u7684\u6a21\u677f\u3002\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5939\u6765\u4fdd\u5b58\u60a8\u7684\u65b0\u6587\u4ef6\u5939\u9879\u76ee\u3002\u5728\u6587\u4ef6\u5939 \uff08Windows\uff09 \u6216\u7ec8\u7aef\u4f1a\u8bdd \uff08Linux \u6216 macOS\uff09 \u4e2d\u6253\u5f00 PowerShell \u6216 cmd \u63d0\u793a\u7b26\uff0c\u7136\u540e\u8fd0\u884c\u4ee5\u4e0b\u5217\u8868\u4e2d\u7684\u547d\u4ee4\u3002<\/p>\n<p>Listing 3.1 Creating a new minimal API application with the .NET CLI<br \/>\n\u6e05\u5355 3.1 \u4f7f\u7528 .NET CLI \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f<\/p>\n<pre><code>dotnet new sln -n WebApplication1 \u2776\ndotnet new web -o WebApplication1 \u2777\ndotnet sln add WebApplication1    \u2778<\/code><\/pre>\n<p>\u2776 Creates a solution \ufb01le called WebApplication1 in the current folder<br \/>\n\u5728\u5f53\u524d\u6587\u4ef6\u5939\u4e2d\u521b\u5efa\u540d\u4e3a WebApplication1 \u7684\u89e3\u51b3\u65b9\u6848\u6587\u4ef6<br \/>\n\u2777 Creates an empty ASP.NET Core project in a subfolder, WebApplication1<br \/>\n\u5728\u5b50\u6587\u4ef6\u5939 WebApplication1 \u4e2d\u521b\u5efa\u7a7a\u7684 ASP.NET Core \u9879\u76ee<br \/>\n\u2778 Adds the new project to the solution \ufb01le<br \/>\n\u5c06\u65b0\u9879\u76ee\u6dfb\u52a0\u5230\u89e3\u51b3\u65b9\u6848\u6587\u4ef6\u4e2d<\/p>\n<p><strong>NOTE<\/strong> Visual Studio uses the concept of a solution to work with multiple projects. The example solution consists of a single project, which is listed in the .sln \ufb01le. If you use a CLI template to create your project, you won\u2019t have a .sln \ufb01le unless you generate it explicitly by using additional .NET CLI templates (listing 3.1).<\/p>\n<p><strong>\u6ce8\u610f\uff1a<\/strong>Visual Studio \u4f7f\u7528\u89e3\u51b3\u65b9\u6848\u7684\u6982\u5ff5\u6765\u5904\u7406\u591a\u4e2a\u9879\u76ee\u3002\u793a\u4f8b\u89e3\u51b3\u65b9\u6848\u7531\u4e00\u4e2a\u9879\u76ee\u7ec4\u6210\uff0c\u8be5\u9879\u76ee\u5728 .sln \u6587\u4ef6\u4e2d\u5217\u51fa\u3002\u5982\u679c\u4f7f\u7528 CLI \u6a21\u677f\u521b\u5efa\u9879\u76ee\uff0c\u5219\u4e0d\u4f1a\u6709 .sln \u6587\u4ef6\uff0c\u9664\u975e\u4f7f\u7528\u5176\u4ed6 .NET CLI \u6a21\u677f\uff08\u6e05\u5355 3.1\uff09\u663e\u5f0f\u751f\u6210\u8be5\u6587\u4ef6\u3002<\/p>\n<p>Whether you use Visual Studio or the .NET CLI, now you have the basic \ufb01les required to build and run your \ufb01rst ASP.NET Core application.<\/p>\n<p>\u65e0\u8bba\u60a8\u4f7f\u7528\u7684\u662f Visual Studio \u8fd8\u662f .NET CLI\uff0c\u73b0\u5728\u60a8\u90fd\u62e5\u6709\u6784\u5efa\u548c\u8fd0\u884c\u7b2c\u4e00\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u57fa\u672c\u6587\u4ef6\u3002<\/p>\n<h3>3.2.2 Building the application\u200c<\/h3>\n<h3>3.2.2 \u6784\u5efa\u5e94\u7528\u7a0b\u5e8f<\/h3>\n<p>At this point, you have most of the \ufb01les necessary to run your application, but you\u2019ve got two steps left. First, you need to ensure all the dependencies used by your project are downloaded to your machine, and second, you need to compile your application so that it can be run.<\/p>\n<p>\u6b64\u65f6\uff0c\u60a8\u62e5\u6709\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u5927\u90e8\u5206\u6587\u4ef6\uff0c\u4f46\u8fd8\u5269\u4e0b\u4e24\u4e2a\u6b65\u9aa4\u3002\u9996\u5148\uff0c\u60a8\u9700\u8981\u786e\u4fdd\u9879\u76ee\u4f7f\u7528\u7684\u6240\u6709\u4f9d\u8d56\u9879\u90fd\u5df2\u4e0b\u8f7d\u5230\u60a8\u7684\u8ba1\u7b97\u673a\u4e0a\uff0c\u5176\u6b21\uff0c\u60a8\u9700\u8981\u7f16\u8bd1\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u4fbf\u5b83\u53ef\u4ee5\u8fd0\u884c\u3002<\/p>\n<p>The \ufb01rst step isn\u2019t strictly necessary, as both Visual Studio and the .NET CLI automatically restore packages when they create your project, but it\u2019s good to know what\u2019s going on. In earlier versions of the .NET CLI, before 2.0, you needed to restore packages manually by using dotnet restore.<\/p>\n<p>\u7b2c\u4e00\u6b65\u5e76\u4e0d\u662f\u7edd\u5bf9\u5fc5\u8981\u7684\uff0c\u56e0\u4e3a Visual Studio \u548c .NET CLI \u90fd\u4f1a\u5728\u521b\u5efa\u9879\u76ee\u65f6\u81ea\u52a8\u8fd8\u539f\u5305\uff0c\u4f46\u6700\u597d\u4e86\u89e3\u53d1\u751f\u4e86\u4ec0\u4e48\u3002\u5728\u65e9\u671f\u7248\u672c\u7684 .NET CLI \u4e2d\uff0c\u5728 2.0 \u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4f7f\u7528 dotnet restore \u624b\u52a8\u8fd8\u539f\u5305\u3002<\/p>\n<p>You can compile your application by choosing Build &gt; Build Solution, pressing the shortcut Ctrl-Shift-B, or running dotnet build from the command line. If you build from Visual Studio, the output window shows the progress of the build, and assuming that everything is hunky-dory, Visual Studio compiles your application, ready for running. You can also run the dotnet build console commands from the Package Manager Console in Visual Studio.<\/p>\n<p>\u60a8\u53ef\u4ee5\u901a\u8fc7\u9009\u62e9 Build &gt; Build Solution\uff08\u751f\u6210\u89e3\u51b3\u65b9\u6848\uff09\u3001\u6309\u5feb\u6377\u952e Ctrl-Shift-B \u6216\u4ece\u547d\u4ee4\u884c\u8fd0\u884c dotnet build \u6765\u7f16\u8bd1\u5e94\u7528\u7a0b\u5e8f\u3002\u5982\u679c\u4ece Visual Studio \u8fdb\u884c\u6784\u5efa\uff0c\u5219\u8f93\u51fa\u7a97\u53e3\u4f1a\u663e\u793a\u6784\u5efa\u8fdb\u5ea6\uff0c\u5e76\u5047\u8bbe\u4e00\u5207\u90fd\u662f hunky-dory\uff0c\u5219 Visual Studio \u4f1a\u7f16\u8bd1\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u51c6\u5907\u597d\u8fd0\u884c\u3002\u8fd8\u53ef\u4ee5\u4ece Visual Studio \u4e2d\u7684\u5305\u7ba1\u7406\u5668\u63a7\u5236\u53f0\u8fd0\u884c dotnet build \u63a7\u5236\u53f0\u547d\u4ee4\u3002<\/p>\n<p><strong>TIP<\/strong> Visual Studio and the .NET CLI tools build your application automatically when you run it if they detect that a \ufb01le has changed, so you generally won\u2019t need to perform this step explicitly yourself.<br \/>\n<strong>\u63d0\u793a<\/strong> \u5982\u679c Visual Studio \u548c .NET CLI \u5de5\u5177\u68c0\u6d4b\u5230\u6587\u4ef6\u5df2\u66f4\u6539\uff0c\u5219\u5b83\u4eec\u5728\u8fd0\u884c\u65f6\u4f1a\u81ea\u52a8\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\uff0c\u56e0\u6b64\u60a8\u901a\u5e38\u4e0d\u9700\u8981\u81ea\u5df1\u663e\u5f0f\u6267\u884c\u6b64\u6b65\u9aa4\u3002<\/p>\n<blockquote>\n<p>NuGet packages and the .NET CLI<br \/>\nNuGet \u5305\u548c .NET CLI<\/p>\n<\/blockquote>\n<p>One of the foundational components of .NET 7 cross-platform development is the .NET CLI, which provides several basic commands for creating, building, and running .NET 7 applications. Visual Studio e\ufb00ectively calls these commands automatically, but you can also invoke them directly from the command line if you\u2019re using a di\ufb00erent editor. The most common commands used during development are<br \/>\n.NET 7 \u8de8\u5e73\u53f0\u5f00\u53d1\u7684\u57fa\u7840\u7ec4\u4ef6\u4e4b\u4e00\u662f.NET CLI\uff0c\u5b83\u63d0\u4f9b\u4e86\u51e0\u4e2a\u7528\u4e8e\u521b\u5efa\u3001\u6784\u5efa\u548c\u8fd0\u884c .NET 7 \u5e94\u7528\u7a0b\u5e8f\u7684\u57fa\u672c\u547d\u4ee4\u3002Visual Studio \u53ef\u4ee5\u6709\u6548\u5730\u81ea\u52a8\u8c03\u7528\u8fd9\u4e9b\u547d\u4ee4\uff0c\u4f46\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f\u5176\u4ed6\u7f16\u8f91\u5668\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4ece\u547d\u4ee4\u884c\u8c03\u7528\u5b83\u4eec\u3002\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u6700\u5e38\u7528\u7684\u547d\u4ee4\u662f<\/p>\n<ul>\n<li>dotnet restore <\/li>\n<li>dotnet build <\/li>\n<li>dotnet run\u200c<\/li>\n<\/ul>\n<p>Each of these commands should be run inside your project folder and will act on that project alone. Except where explicitly noted, this is the case for all .NET CLI commands.<br \/>\n\u8fd9\u4e9b\u547d\u4ee4\u4e2d\u7684\u6bcf\u4e00\u4e2a\u90fd\u5e94\u8be5\u5728\u4f60\u7684\u9879\u76ee\u6587\u4ef6\u5939\u4e2d\u8fd0\u884c\uff0c\u5e76\u4e14\u5c06\u5355\u72ec\u4f5c\u7528\u4e8e\u8be5\u9879\u76ee\u3002\u9664\u975e\u660e\u786e\u8bf4\u660e\uff0c\u5426\u5219\u6240\u6709 .NET CLI \u547d\u4ee4\u90fd\u662f\u8fd9\u79cd\u60c5\u51b5\u3002<\/p>\n<p>Most ASP.NET Core applications have dependencies on various external libraries, which are managed through the NuGet package manager. These dependencies are listed in the project, but the \ufb01les of the libraries themselves aren\u2019t included. Before you can build and run your application, you need to ensure that there are local copies of each dependency on your machine. The \ufb01rst command, dotnet restore, ensures that your application\u2019s NuGet dependencies are downloaded and the \ufb01les are referenced correctly by your project.<br \/>\n\u5927\u591a\u6570 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u90fd\u4f9d\u8d56\u4e8e\u5404\u79cd\u5916\u90e8\u5e93\uff0c\u8fd9\u4e9b\u5e93\u901a\u8fc7 NuGet \u5305\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\u3002\u8fd9\u4e9b\u4f9d\u8d56\u9879\u5728\u9879\u76ee\u4e2d\u5217\u51fa\uff0c\u4f46\u4e0d\u5305\u62ec\u5e93\u672c\u8eab\u7684\u6587\u4ef6\u3002\u5728\u6784\u5efa\u548c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u786e\u4fdd\u8ba1\u7b97\u673a\u4e0a\u6709\u6bcf\u4e2a\u4f9d\u8d56\u9879\u7684\u672c\u5730\u526f\u672c\u3002\u7b2c\u4e00\u4e2a\u547d\u4ee4 dotnet restore \u53ef\u786e\u4fdd\u4e0b\u8f7d\u5e94\u7528\u7a0b\u5e8f\u7684 NuGet \u4f9d\u8d56\u9879\uff0c\u5e76\u4e14\u9879\u76ee\u6b63\u786e\u5f15\u7528\u8fd9\u4e9b\u6587\u4ef6\u3002<\/p>\n<p>ASP.NET Core projects list their dependencies in the project\u2019s .csproj \ufb01le, an XML \ufb01le that lists each dependency as a PackageReference node. When you run dotnet restore, it uses this \ufb01le to establish which NuGet packages to download. Any dependencies listed are available for use in your application.<br \/>\nASP.NET Core \u9879\u76ee\u5728\u9879\u76ee\u7684 .csproj \u6587\u4ef6\u4e2d\u5217\u51fa\u5176\u4f9d\u8d56\u9879\uff0c\u8be5\u6587\u4ef6\u662f\u4e00\u4e2a\u5c06\u6bcf\u4e2a\u4f9d\u8d56\u9879\u5217\u4e3a PackageReference \u8282\u70b9\u7684 XML \u6587\u4ef6\u3002\u8fd0\u884c dotnet restore \u65f6\uff0c\u5b83\u4f1a\u4f7f\u7528\u6b64\u6587\u4ef6\u6765\u786e\u5b9a\u8981\u4e0b\u8f7d\u7684 NuGet \u5305\u3002\u5217\u51fa\u7684\u4efb\u4f55\u4f9d\u8d56\u9879\u90fd\u53ef\u7528\u4e8e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>The restore process typically happens implicitly when you build or run your application, as shown in the following \ufb01gure, but it can be useful sometimes to run it explicitly, such as in continuous-integration build pipelines.<br \/>\n\u8fd8\u539f\u8fc7\u7a0b\u901a\u5e38\u5728\u60a8\u6784\u5efa\u6216\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u65f6\u9690\u5f0f\u53d1\u751f\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff0c\u4f46\u6709\u65f6\u663e\u5f0f\u8fd0\u884c\u5b83\u53ef\u80fd\u5f88\u6709\u7528\uff0c\u4f8b\u5982\u5728\u6301\u7eed\u96c6\u6210\u6784\u5efa\u7ba1\u9053\u4e2d\u3002<\/p>\n<p>The dotnet build command runs dotnet restore implicitly. Similarly, dotnet run runs dotnet build and dotnet restore. If you don\u2019t want to run the previous steps automatically, you can use the --no-restore and --no- build flags, as in dotnet build --no-restore.<br \/>\ndotnet build \u547d\u4ee4\u9690\u5f0f\u8fd0\u884c dotnet restore\u3002\u540c\u6837\uff0cdotnet run \u8fd0\u884c dotnet build \u548c dotnet restore\u3002\u5982\u679c\u4e0d\u60f3\u81ea\u52a8\u8fd0\u884c\u524d\u9762\u7684\u6b65\u9aa4\uff0c\u53ef\u4ee5\u4f7f\u7528 --no-restore \u548c --no- build \u6807\u5fd7\uff0c\u5982 dotnet build --no-restore \u4e2d\u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0305-2.png\" alt=\"alt text\" \/><\/p>\n<p>You can compile your application by using dotnet build, which checks for any errors in your application and, if it \ufb01nds no problems, produces output binaries that can be run with dotnet run.<br \/>\n\u53ef\u4ee5\u4f7f\u7528 dotnet build \u7f16\u8bd1\u5e94\u7528\u7a0b\u5e8f\uff0c\u5b83\u4f1a\u68c0\u67e5\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u4efb\u4f55\u9519\u8bef\uff0c\u5982\u679c\u672a\u53d1\u73b0\u95ee\u9898\uff0c\u5219\u751f\u6210\u53ef\u4ee5\u4f7f\u7528 dotnet run \u8fd0\u884c\u7684\u8f93\u51fa\u4e8c\u8fdb\u5236\u6587\u4ef6\u3002<\/p>\n<p>Each command contains switches that can modify its behavior. To see the full list of available commands, run<br \/>\n\u6bcf\u4e2a\u547d\u4ee4\u90fd\u5305\u542b\u53ef\u4ee5\u4fee\u6539\u5176\u884c\u4e3a\u7684\u5f00\u5173\u3002\u8981\u67e5\u770b\u53ef\u7528\u547d\u4ee4\u7684\u5b8c\u6574\u5217\u8868\uff0c\u8bf7\u8fd0\u884c<\/p>\n<p>dotnet --help<\/p>\n<p>To see the options available for a particular command, such as new, run<br \/>\n\u8981\u67e5\u770b\u7279\u5b9a\u547d\u4ee4\u7684\u53ef\u7528\u9009\u9879\uff08\u5982 new\uff09\uff0c\u8bf7\u8fd0\u884c<\/p>\n<p>dotnet new --help<\/p>\n<h3>3.3 Running the web application\u200c<\/h3>\n<h3>3.3 \u8fd0\u884c Web \u5e94\u7528\u7a0b\u5e8f<\/h3>\n<p>You\u2019re ready to run your \ufb01rst application, and you have several ways to go about it. In Visual Studio, you can click the green arrow on the toolbar next to WebApplication1 or press the F5 shortcut. Visual Studio will automatically open a web browser window for you with the appropriate URL, and after a second or two, you should see the basic &quot;Hello World!&quot; response, as shown in \ufb01gure 3.6.<\/p>\n<p>\u60a8\u5df2\u51c6\u5907\u597d\u8fd0\u884c\u60a8\u7684\u7b2c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u4e14\u6709\u51e0\u79cd\u65b9\u6cd5\u53ef\u4ee5\u5f00\u59cb\u8fd0\u884c\u3002\u5728 Visual Studio \u4e2d\uff0c\u60a8\u53ef\u4ee5\u5355\u51fb WebApplication1 \u65c1\u8fb9\u7684\u5de5\u5177\u680f\u4e0a\u7684\u7eff\u8272\u7bad\u5934\u6216\u6309 F5 \u5feb\u6377\u65b9\u5f0f\u3002Visual Studio \u5c06\u81ea\u52a8\u4e3a\u60a8\u6253\u5f00\u4e00\u4e2a\u5305\u542b\u76f8\u5e94 URL \u7684 Web \u6d4f\u89c8\u5668\u7a97\u53e3\uff0c\u4e00\u4e24\u79d2\u949f\u540e\uff0c\u60a8\u5e94\u8be5\u4f1a\u770b\u5230\u57fa\u672c\u7684\u201cHello World\uff01 \u54cd\u5e94\uff0c\u5982\u56fe 3.6 \u6240\u793a\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0306.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.6 The output of your new ASP.NET Core application. The template chooses a random port to use for your application\u2019s URL, which will be opened in the browser automatically when you run from Visual Studio.<\/p>\n<p>\u56fe 3.6 \u65b0\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002\u8be5\u6a21\u677f\u9009\u62e9\u4e00\u4e2a\u968f\u673a\u7aef\u53e3\u7528\u4e8e\u5e94\u7528\u7a0b\u5e8f\u7684 URL\uff0c\u5f53\u60a8\u4ece Visual Studio \u8fd0\u884c\u65f6\uff0c\u8be5\u7aef\u53e3\u5c06\u81ea\u52a8\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00\u3002<\/p>\n<p>Alternatively, instead of using Visual Studio, you can run the application from the command line with the .NET CLI tools by using dotnet run. Then you can open the URL in a web browser manually, using the address provided on the command line.<\/p>\n<p>\u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 dotnet run \u4f7f\u7528 .NET CLI \u5de5\u5177\u4ece\u547d\u4ee4\u884c\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u800c\u4e0d\u662f\u4f7f\u7528 Visual Studio\u3002\u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u547d\u4ee4\u884c\u4e0a\u63d0\u4f9b\u7684\u5730\u5740\u5728 Web \u6d4f\u89c8\u5668\u4e2d\u624b\u52a8\u6253\u5f00 URL\u3002<\/p>\n<p>Depending on whether you created your application with Visual Studio, you may see an http:\/\/ or https:\/\/ URL.<\/p>\n<p>\u6839\u636e\u662f\u5426\u4f7f\u7528 Visual Studio \u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u53ef\u80fd\u4f1a\u770b\u5230 http:\/\/ \u6216 https:\/\/ URL\u3002<\/p>\n<p><strong>TIP<\/strong> The \ufb01rst time you run the application from Visual Studio, you may be prompted to install the development certi\ufb01cate. Doing so ensures that your browser doesn\u2019t display warnings about an invalid certi\ufb01cate.2 See chapter 28 for more about HTTPS certi\ufb01cates.<br \/>\n<strong>\u63d0\u793a<\/strong> \u9996\u6b21\u4ece Visual Studio \u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u7cfb\u7edf\u53ef\u80fd\u4f1a\u63d0\u793a\u60a8\u5b89\u88c5\u5f00\u53d1\u8bc1\u4e66\u3002\u8fd9\u6837\u505a\u53ef\u4ee5\u786e\u4fdd\u60a8\u7684\u6d4f\u89c8\u5668\u4e0d\u4f1a\u663e\u793a\u6709\u5173\u65e0\u6548\u8bc1\u4e66\u7684\u8b66\u544a\u3002 2 \u6709\u5173 HTTPS \u8bc1\u4e66\u7684\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1\u7b2c 28 \u7ae0\u3002<\/p>\n<p>This basic application has a single endpoint that returns the plain-text response when you request the path \/, as you saw in \ufb01gure 3.6. There isn\u2019t anything more you can do with this simple app, so let\u2019s look at some code!<br \/>\n\u6b64\u57fa\u672c\u5e94\u7528\u7a0b\u5e8f\u5177\u6709\u5355\u4e2a\u7ec8\u7aef\u8282\u70b9\uff0c\u5f53\u60a8\u8bf7\u6c42\u8def\u5f84 \/ \u65f6\uff0c\u8be5\u7ec8\u7aef\u8282\u70b9\u5c06\u8fd4\u56de\u7eaf\u6587\u672c\u54cd\u5e94\uff0c\u5982\u56fe 3.6.\u8fd9\u4e2a\u7b80\u5355\u7684\u5e94\u7528\u7a0b\u5e8f\u6ca1\u6709\u66f4\u591a\u7684\u4e8b\u60c5\u53ef\u4ee5\u505a\uff0c\u6240\u4ee5\u8ba9\u6211\u4eec\u770b\u770b\u4e00\u4e9b\u4ee3\u7801\uff01<\/p>\n<h3>3.4 Understanding the project layout\u200c<\/h3>\n<h3>3.4 \u4e86\u89e3\u9879\u76ee\u5e03\u5c40<\/h3>\n<p>When you\u2019re new to a framework, creating an application from a template can be a mixed blessing. On one hand, you can get an application up and running quickly, with little input required on your part. Conversely, the number of \ufb01les can be overwhelming, leaving you scratching your head working out where to start. The basic web application template doesn\u2019t contain a huge number of \ufb01les and folders, as shown in \ufb01gure 3.7, but I\u2019ll run through the major ones to get you oriented.<\/p>\n<p>\u5f53\u60a8\u4e0d\u719f\u6089\u6846\u67b6\u65f6\uff0c\u4ece\u6a21\u677f\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\u53ef\u80fd\u662f\u4e00\u4ef6\u597d\u574f\u53c2\u534a\u7684\u4e8b\u60c5\u3002\u4e00\u65b9\u9762\uff0c\u60a8\u53ef\u4ee5\u5feb\u901f\u542f\u52a8\u5e76\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u51e0\u4e4e\u4e0d\u9700\u8981\u60a8\u8f93\u5165\u3002\u76f8\u53cd\uff0c\u6587\u4ef6\u7684\u6570\u91cf\u53ef\u80fd\u4f1a\u8ba9\u4eba\u4e0d\u77e5\u6240\u63aa\uff0c\u8ba9\u60a8\u6478\u4e0d\u7740\u5934\u8111\uff0c\u4e0d\u77e5\u9053\u4ece\u54ea\u91cc\u5f00\u59cb\u3002\u5982\u56fe 3.7 \u6240\u793a\uff0c\u57fa\u672c\u7684 Web \u5e94\u7528\u7a0b\u5e8f\u6a21\u677f\u4e0d\u5305\u542b\u5927\u91cf\u7684\u6587\u4ef6\u548c\u6587\u4ef6\u5939\uff0c\u4f46\u6211\u5c06\u4ecb\u7ecd\u4e3b\u8981\u7684\u6587\u4ef6\u548c\u6587\u4ef6\u5939\uff0c\u4ee5\u4fbf\u60a8\u4e86\u89e3\u60c5\u51b5\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0307.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.7 Solution Explorer and folder on disk for a new ASP.NET Core application. Solution Explorer also displays the Connected Services and Dependencies nodes, which list NuGet and other dependencies, though the folders themselves don\u2019t exist on disk.<\/p>\n<p>\u56fe 3.7 \u65b0 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u548c\u78c1\u76d8\u4e0a\u7684\u6587\u4ef6\u5939\u3002\u201c\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u201d\u8fd8\u663e\u793a\u201c\u8fde\u63a5\u7684\u670d\u52a1\u201d\u548c\u201c\u4f9d\u8d56\u9879\u201d\u8282\u70b9\uff0c\u5176\u4e2d\u5217\u51fa\u4e86 NuGet \u548c\u5176\u4ed6\u4f9d\u8d56\u9879\uff0c\u4f46\u6587\u4ef6\u5939\u672c\u8eab\u5e76\u4e0d\u5b58\u5728\u4e8e\u78c1\u76d8\u4e0a\u3002<\/p>\n<p>The \ufb01rst thing to notice is that the main project, WebApplication1, is nested in a top-level directory with the name of the solution, which is also WebApplication1 in this case. Within this top-level folder you\u2019ll also \ufb01nd the solution (.sln) \ufb01le used by Visual Studio, though this is hidden in Visual Studio\u2019s Solution Explorer view.<\/p>\n<p>\u9996\u5148\u8981\u6ce8\u610f\u7684\u662f\uff0c\u4e3b\u9879\u76ee WebApplication1 \u5d4c\u5957\u5728\u5177\u6709\u89e3\u51b3\u65b9\u6848\u540d\u79f0\u7684\u9876\u7ea7\u76ee\u5f55\u4e2d\uff0c\u5728\u672c\u4f8b\u4e2d\u4e5f\u662f WebApplication1\u3002\u5728\u6b64\u9876\u7ea7\u6587\u4ef6\u5939\u4e2d\uff0c\u60a8\u8fd8\u53ef\u4ee5\u627e\u5230 Visual Studio \u4f7f\u7528\u7684\u89e3\u51b3\u65b9\u6848 \uff08.sln\uff09 \u6587\u4ef6\uff0c\u5c3d\u7ba1\u8be5\u6587\u4ef6\u9690\u85cf\u5728 Visual Studio \u7684\u201c\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u201d\u89c6\u56fe\u4e2d\u3002<\/p>\n<p>Inside the solution folder you\u2019ll \ufb01nd your project folder, which contains the most important \ufb01le in your project: WebApplication1.csproj. This \ufb01le describes how to build your project and lists any additional NuGet packages that it requires. Visual Studio doesn\u2019t show the .csproj \ufb01le explicitly, but you can edit it if you double-click the project name in Solution Explorer or right-click and choose Properties from the contextual menu. We\u2019ll take a closer look at this project \ufb01le in the next section.<\/p>\n<p>\u5728\u89e3\u51b3\u65b9\u6848\u6587\u4ef6\u5939\u4e2d\uff0c\u60a8\u5c06\u627e\u5230\u60a8\u7684\u9879\u76ee\u6587\u4ef6\u5939\uff0c\u5176\u4e2d\u5305\u542b\u9879\u76ee\u4e2d\u6700\u91cd\u8981\u7684\u6587\u4ef6\uff1aWebApplication1.csproj\u3002\u6b64\u6587\u4ef6\u63cf\u8ff0\u4e86\u5982\u4f55\u6784\u5efaproject \u5e76\u5217\u51fa\u5b83\u6240\u9700\u7684\u4efb\u4f55\u5176\u4ed6 NuGet \u5305\u3002Visual Studio \u4e0d\u4f1a\u663e\u5f0f\u663e\u793a .csproj \u6587\u4ef6\uff0c\u4f46\u5982\u679c\u60a8\u5728\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u4e2d\u53cc\u51fb\u9879\u76ee\u540d\u79f0\uff0c\u6216\u8005\u53f3\u952e\u5355\u51fb\u5e76\u4ece\u4e0a\u4e0b\u6587\u83dc\u5355\u4e2d\u9009\u62e9\u201c\u5c5e\u6027\u201d\uff0c\u5219\u53ef\u4ee5\u5bf9\u5176\u8fdb\u884c\u7f16\u8f91\u3002\u6211\u4eec\u5c06\u5728\u4e0b\u4e00\u8282\u4e2d\u4ed4\u7ec6\u7814\u7a76\u6b64\u9879\u76ee\u6587\u4ef6\u3002<\/p>\n<p>Your project folder contains a subfolder called Properties, which contains a single \ufb01le: launchSettings.json. This \ufb01le controls how Visual Studio will run and debug the application. Visual Studio shows the \ufb01le as a special node in Solution Explorer, out of alphabetical order, near the top of your project. You\u2019ve got two more special nodes in the project, Dependencies and Connected Services, but they don\u2019t have corresponding folders on disk.<\/p>\n<p>\u60a8\u7684\u9879\u76ee\u6587\u4ef6\u5939\u5305\u542b\u4e00\u4e2a\u540d\u4e3a Properties \u7684\u5b50\u6587\u4ef6\u5939\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u6587\u4ef6\uff1alaunchSettings.json\u3002\u6b64\u6587\u4ef6\u63a7\u5236 Visual Studio \u8fd0\u884c\u548c\u8c03\u8bd5\u5e94\u7528\u7a0b\u5e8f\u7684\u65b9\u5f0f\u3002Visual Studio \u5728\u201c\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u201d\u4e2d\u5c06\u6587\u4ef6\u663e\u793a\u4e3a\u4e00\u4e2a\u7279\u6b8a\u8282\u70b9\uff0c\u4e0d\u6309\u5b57\u6bcd\u987a\u5e8f\u663e\u793a\u5728\u9879\u76ee\u9876\u90e8\u9644\u8fd1\u3002\u9879\u76ee\u4e2d\u8fd8\u6709\u4e24\u4e2a\u7279\u6b8a\u8282\u70b9\uff0c\u5373 Dependencies \u548c Connected Services\uff0c\u4f46\u5b83\u4eec\u5728\u78c1\u76d8\u4e0a\u6ca1\u6709\u76f8\u5e94\u7684\u6587\u4ef6\u5939\u3002<\/p>\n<p>Instead, they show a collection of all the dependencies, such as NuGet packages, and remote services that the project relies on.In the root of your project folder, you\u2019ll \ufb01nd two JSON \ufb01les: appsettings.json and appsettings.Development.json. These \ufb01les provide con\ufb01guration settings that are used at runtime to control the behavior of your app.<\/p>\n<p>\u76f8\u53cd\uff0c\u5b83\u4eec\u663e\u793a\u9879\u76ee\u6240\u4f9d\u8d56\u7684\u6240\u6709\u4f9d\u8d56\u9879\uff08\u5982 NuGet \u5305\u548c\u8fdc\u7a0b\u670d\u52a1\uff09\u7684\u96c6\u5408\u3002\u9879\u76ee\u6587\u4ef6\u5939\u7684\u6839\u76ee\u5f55\u4e2d\uff0c\u60a8\u5c06\u627e\u5230\u4e24\u4e2a JSON \u6587\u4ef6\uff1aappsettings.json \u548c appsettings\u3002Development.json. \u8fd9\u4e9b\u6587\u4ef6\u63d0\u4f9b\u5728\u8fd0\u884c\u65f6\u7528\u4e8e\u63a7\u5236\u5e94\u7528\u7a0b\u5e8f\u884c\u4e3a\u7684\u914d\u7f6e\u8bbe\u7f6e\u3002<\/p>\n<p>Finally, Visual Studio shows one C# \ufb01le in the project folder: Program.cs. In section 3.6 you\u2019ll see how this \ufb01le con\ufb01gures and runs your application.<\/p>\n<p>\u6700\u540e\uff0cVisual Studio \u5728\u9879\u76ee\u6587\u4ef6\u5939\u4e2d\u663e\u793a\u4e00\u4e2a C# \u6587\u4ef6\uff1aProgram.cs\u3002\u5728 Section 3.6 \u4e2d\uff0c\u60a8\u5c06\u770b\u5230\u6b64\u6587\u4ef6\u5982\u4f55\u914d\u7f6e\u548c\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<h3>3.5 The .csproj project \ufb01le: Declaring your dependencies\u200c<\/h3>\n<h3>3.5 .csproj \u9879\u76ee\u6587\u4ef6\uff1a\u58f0\u660e\u4f9d\u8d56\u9879<\/h3>\n<p>The .csproj \ufb01le is the project \ufb01le for .NET applications and contains the details required for the .NET tooling to build your project. It de\ufb01nes the type of project being built (web app, console app, or library), which platform the project targets (.NET Core 3.1, .NET 7 and so on), and which NuGet packages the project depends on.<\/p>\n<p>.csproj \u6587\u4ef6\u662f .NET \u5e94\u7528\u7a0b\u5e8f\u7684\u9879\u76ee\u6587\u4ef6\uff0c\u5305\u542b\u7528\u4e8e\u751f\u6210\u9879\u76ee\u7684 .NET \u5de5\u5177\u6240\u9700\u7684\u8be6\u7ec6\u4fe1\u606f\u3002\u5b83\u5b9a\u4e49\u6b63\u5728\u751f\u6210\u7684\u9879\u76ee\u7684\u7c7b\u578b \uff08Web \u5e94\u7528\u7a0b\u5e8f\u3001\u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u6216\u5e93\uff09 \uff0c\u4ee5\u53ca\u9879\u76ee\u9762\u5411\u7684\u5e73\u53f0 \uff08.NET Core 3.1\u3001.NET 7 \u7b49\uff09\u4ee5\u53ca\u9879\u76ee\u6240\u4f9d\u8d56\u7684 NuGet \u5305\u3002<\/p>\n<p>The project \ufb01le has been a mainstay of .NET applications, but in ASP.NET Core it has had a facelift to make it easier to read and edit. These changes include<\/p>\n<p>\u9879\u76ee\u6587\u4ef6\u4e00\u76f4\u662f .NET \u5e94\u7528\u7a0b\u5e8f\u7684\u652f\u67f1\uff0c\u4f46\u5728 ASP.NET Core \u4e2d\uff0c\u5b83\u5df2\u7ecf\u8fdb\u884c\u4e86\u6539\u8fdb\uff0c\u4f7f\u5176\u66f4\u6613\u4e8e\u9605\u8bfb\u548c\u7f16\u8f91\u3002\u8fd9\u4e9b\u66f4\u6539\u5305\u62ec<\/p>\n<ul>\n<li>\n<p>No GUIDs\u2014Previously, globally unique identi\ufb01ers (GUIDs) were used for many things, but now they\u2019re rarely used in the project \ufb01le.<br \/>\n\u65e0 GUID \u2013 \u4ee5\u524d\uff0c\u5168\u5c40\u552f\u4e00\u6807\u8bc6\u7b26 \uff08GUID\uff09 \u7528\u4e8e\u8bb8\u591a\u7528\u9014\uff0c\u4f46\u73b0\u5728\u5b83\u4eec\u5f88\u5c11\u5728\u9879\u76ee\u6587\u4ef6\u4e2d\u4f7f\u7528\u3002<\/p>\n<\/li>\n<li>\n<p>Implicit \ufb01le includes\u2014Previously, every \ufb01le in the project had to be listed in the .csproj \ufb01le to be included in the build. Now \ufb01les are compiled automatically.<br \/>\n\u9690\u5f0f\u6587\u4ef6\u5305\u542b \u2014 \u4ee5\u524d\uff0c\u9879\u76ee\u4e2d\u7684\u6bcf\u4e2a\u6587\u4ef6\u90fd\u5fc5\u987b\u5728 .csproj \u6587\u4ef6\u4e2d\u5217\u51fa\u624d\u80fd\u5305\u542b\u5728\u751f\u6210\u4e2d\u3002\u73b0\u5728\u6587\u4ef6\u4f1a\u81ea\u52a8\u7f16\u8bd1\u3002<\/p>\n<\/li>\n<li>\n<p>No paths to NuGet package .dll \ufb01les\u2014Previously, you had to include the path to the .dll \ufb01les contained in NuGet packages in the .csproj, as well as list the dependencies in a packages.con\ufb01g \ufb01le. Now you can reference the NuGet package directly in your .csproj, and you don\u2019t need to specify the path on disk.<br \/>\n\u6ca1\u6709 NuGet \u5305.dll\u6587\u4ef6\u7684\u8def\u5f84 \u2013 \u4ee5\u524d\uff0c\u5fc5\u987b\u5728 .csproj \u4e2d\u5305\u542b NuGet \u5305\u4e2d\u5305\u542b\u7684 .dll \u6587\u4ef6\u7684\u8def\u5f84\uff0c\u5e76\u5728 packages.config \u6587\u4ef6\u4e2d\u5217\u51fa\u4f9d\u8d56\u9879\u3002\u73b0\u5728\uff0c\u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 .csproj \u4e2d\u5f15\u7528 NuGet \u5305\uff0c\u800c\u65e0\u9700\u6307\u5b9a\u78c1\u76d8\u4e0a\u7684\u8def\u5f84\u3002<\/p>\n<\/li>\n<\/ul>\n<p>All these changes combine to make the project \ufb01le far more compact than you\u2019ll be used to from previous .NET projects. The following listing shows the entire .csproj \ufb01le for your sample app.<br \/>\n\u6240\u6709\u8fd9\u4e9b\u66f4\u6539\u7ed3\u5408\u5728\u4e00\u8d77\uff0c\u4f7f\u9879\u76ee\u6587\u4ef6\u6bd4\u60a8\u4ee5\u524d\u4e60\u60ef\u7684 .NET \u9879\u76ee\u8981\u7d27\u51d1\u5f97\u591a\u3002\u4ee5\u4e0b\u6e05\u5355\u663e\u793a\u4e86\u793a\u4f8b\u5e94\u7528\u7a0b\u5e8f\u7684\u6574\u4e2a .csproj \u6587\u4ef6\u3002<\/p>\n<p>Listing 3.2 The .csproj project \ufb01le, showing SDK, target framework, and references<br \/>\n\u6e05\u5355 3.2 .csproj \u9879\u76ee\u6587\u4ef6\uff0c\u663e\u793a SDK\u3001\u76ee\u6807\u6846\u67b6\u548c\u5f15\u7528<\/p>\n<pre><code>&lt;Project Sdk=&quot;Microsoft.NET.Sdk.Web&quot;&gt;             \u2776\n    &lt;PropertyGroup&gt;\n        &lt;TargetFramework&gt;net7.0&lt;\/TargetFramework&gt; \u2777\n        &lt;Nullable&gt;enable&lt;\/Nullable&gt;               \u2778\n        &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;   \u2779\n    &lt;\/PropertyGroup&gt;\n&lt;\/Project&gt;\n<\/code><\/pre>\n<p>\u2776 The SDK attribute speci\ufb01es the type of project you\u2019re building.<br \/>\nSDK \u5c5e\u6027\u6307\u5b9a\u8981\u751f\u6210\u7684\u9879\u76ee\u7c7b\u578b\u3002<\/p>\n<p>\u2777 The TargetFramework is the framework you\u2019ll run on\u2014in this case, .NET 7.<br \/>\nTargetFramework \u662f\u4f60\u5c06\u5728\u5176\u4e0a\u8fd0\u884c\u7684\u6846\u67b6\uff0c\u5728\u672c\u4f8b\u4e2d\u4e3a .NET 7\u3002<\/p>\n<p>\u2778 Enables the C# 8 feature \u201cnullable reference types\u201d<br \/>\n\u542f\u7528 C# 8 \u529f\u80fd\u201c\u53ef\u4e3a null \u7684\u5f15\u7528\u7c7b\u578b\u201d<\/p>\n<p>\u2779 Enables the C# 10 feature \u201cimplicit using statements\u201d<br \/>\n\u542f\u7528 C# 10 \u529f\u80fd\u201c\u9690\u5f0f using \u8bed\u53e5\u201d<\/p>\n<p>For simple applications, you probably won\u2019t need to change the project \ufb01le much. The Sdk attribute on the Project element includes default settings that describe how to build your project, whereas the TargetFramework element describes the framework your application will run on. For .NET 6.0 projects, this element will have the net6.0 value; if you\u2019re running on .NET 7, this will be net7.0. You can also enable and disable various features of the compiler, such as the C# 8 feature nullable reference types or the C# 10 feature implicit using statements.3\u200c\u200c<\/p>\n<p>\u5bf9\u4e8e\u7b80\u5355\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u53ef\u80fd\u4e0d\u9700\u8981\u5bf9\u9879\u76ee\u6587\u4ef6\u8fdb\u884c\u592a\u591a\u66f4\u6539\u3002Project \u5143\u7d20\u4e0a\u7684 Sdk \u5c5e\u6027\u5305\u62ec\u63cf\u8ff0\u5982\u4f55\u751f\u6210\u9879\u76ee\u7684\u9ed8\u8ba4\u8bbe\u7f6e\uff0c\u800c TargetFramework \u5143\u7d20\u63cf\u8ff0\u5e94\u7528\u7a0b\u5e8f\u5c06\u5728\u5176\u4e0a\u8fd0\u884c\u7684\u6846\u67b6\u3002\u5bf9\u4e8e .NET 6.0 \u9879\u76ee\uff0c\u6b64\u5143\u7d20\u5c06\u5177\u6709 net6.0 \u503c;\u5982\u679c\u60a8\u5728 .NET 7 \u4e0a\u8fd0\u884c\uff0c\u5219\u4e3a Net7.0\u3002\u60a8\u8fd8\u53ef\u4ee5\u542f\u7528\u548c\u7981\u7528\u7f16\u8bd1\u5668\u7684\u5404\u79cd\u529f\u80fd\uff0c\u4f8b\u5982 C# 8 \u529f\u80fd\u53ef\u4e3a null \u7684\u5f15\u7528\u7c7b\u578b\u6216 C# 10 \u9690\u5f0f using \u8bed\u53e5\u529f\u80fd\u3002 3<\/p>\n<p><strong>TIP<\/strong> With the new csproj style, Visual Studio users can double- click a project in Solution Explorer to edit the .csproj \ufb01le without having to close the project \ufb01rst.<br \/>\n<strong>\u63d0\u793a<\/strong> \u4f7f\u7528\u65b0\u7684 csproj \u6837\u5f0f\uff0cVisual Studio \u7528\u6237\u53ef\u4ee5\u5728\u201c\u89e3\u51b3\u65b9\u6848\u8d44\u6e90\u7ba1\u7406\u5668\u201d\u4e2d\u53cc\u51fb\u9879\u76ee\u6765\u7f16\u8f91 .csproj \u6587\u4ef6\uff0c\u800c\u4e0d\u5fc5\u5148\u5173\u95ed\u9879\u76ee\u3002<\/p>\n<p>The most common changes you\u2019ll make to the project \ufb01le are to add more NuGet packages by using the PackageReference element. By default, your app doesn\u2019t reference any NuGet packages at all.<\/p>\n<p>\u5bf9\u9879\u76ee\u6587\u4ef6\u8fdb\u884c\u7684\u6700\u5e38\u89c1\u66f4\u6539\u662f\u4f7f\u7528 PackageReference \u5143\u7d20\u6dfb\u52a0\u66f4\u591a NuGet \u5305\u3002\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u60a8\u7684\u5e94\u7528\u6839\u672c\u4e0d\u5f15\u7528\u4efb\u4f55 NuGet \u5305\u3002<\/p>\n<blockquote>\n<p>Using NuGet libraries in your project<br \/>\n\u5728\u9879\u76ee\u4e2d\u4f7f\u7528 NuGet \u5e93<\/p>\n<p>Even though all apps are unique in some way, they also have common requirements. Most apps need to access a database, for example, or manipulate JSON- or XML-formatted data. Rather than having to reinvent that code in every project, you should use existing reusable libraries.<br \/>\n\u5c3d\u7ba1\u6240\u6709\u5e94\u7528\u7a0b\u5e8f\u5728\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u90fd\u662f\u552f\u4e00\u7684\uff0c\u4f46\u5b83\u4eec\u4e5f\u6709\u5171\u540c\u7684\u8981\u6c42\u3002\u4f8b\u5982\uff0c\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u9700\u8981\u8bbf\u95ee\u6570\u636e\u5e93\uff0c\u6216\u8005\u4f5c JSON \u6216 XML \u683c\u5f0f\u7684\u6570\u636e\u3002\u60a8\u4e0d\u5fc5\u5728\u6bcf\u4e2a\u9879\u76ee\u4e2d\u91cd\u65b0\u521b\u5efa\u8be5\u4ee3\u7801\uff0c\u800c\u5e94\u8be5\u4f7f\u7528\u73b0\u6709\u7684\u53ef\u91cd\u7528\u5e93\u3002<\/p>\n<p>NuGet is the library package manager for .NET, where libraries are packaged in NuGet packages and published to <a href=\"https:\/\/www.nuget.org\">https:\/\/www.nuget.org<\/a>. You can use these packages in your project by referencing the unique package name in your .csproj \ufb01le, making the package\u2019s namespace and classes available in your code \ufb01les.<br \/>\nNuGet \u662f .NET \u7684\u5e93\u5305\u7ba1\u7406\u5668\uff0c\u5176\u4e2d\u7684\u5e93\u6253\u5305\u5728 NuGet \u5305\u4e2d\u5e76\u53d1\u5e03\u5230 <a href=\"https:\/\/www.nuget.org\u3002\u60a8\u53ef\u4ee5\u901a\u8fc7\u5728\">https:\/\/www.nuget.org\u3002\u60a8\u53ef\u4ee5\u901a\u8fc7\u5728<\/a> .csproj \u6587\u4ef6\u4e2d\u5f15\u7528\u552f\u4e00\u7684\u5305\u540d\u79f0\u6765\u5728\u9879\u76ee\u4e2d\u4f7f\u7528\u8fd9\u4e9b\u5305\uff0c\u4ece\u800c\u4f7f\u5305\u7684\u547d\u540d\u7a7a\u95f4\u548c\u7c7b\u5728\u4ee3\u7801\u6587\u4ef6\u4e2d\u53ef\u7528\u3002<\/p>\n<p>You can publish (and host) NuGet packages to repositories other than nuget.org; see <a href=\"https:\/\/learn.micro\">https:\/\/learn.micro<\/a> soft.com\/en-us\/nuget for details.<br \/>\n\u60a8\u53ef\u4ee5\u5c06 NuGet \u5305\u53d1\u5e03\uff08\u548c\u6258\u7ba1\uff09\u5230 nuget.org \u4ee5\u5916\u7684\u5b58\u50a8\u5e93;\u6709\u5173\u8be6\u7ec6\u4fe1\u606f \uff0c\u8bf7\u53c2\u9605 <a href=\"https:\/\/learn.micro\">https:\/\/learn.micro<\/a> soft.com\/en-us\/nuget\u3002<\/p>\n<p>You can add a NuGet reference to your project by running dotnet add package<br \/>\n\u53ef\u4ee5\u901a\u8fc7\u8fd0\u884c dotnet add package \u5c06 NuGet \u5f15\u7528\u6dfb\u52a0\u5230\u9879\u76ee<\/p>\n<packagename> from inside the project folder. This command updates your project \ufb01le with a <PackageReference> node and restores the NuGet package for your project. To install the popular Newtonsoft.Json library, for example, you would run\n<packagename> \u4ece\u9879\u76ee\u6587\u4ef6\u5939\u5185\u3002\u6b64\u547d\u4ee4\u4f7f\u7528 <PackageReference> \u8282\u70b9\u66f4\u65b0\u9879\u76ee\u6587\u4ef6\uff0c\u5e76\u8fd8\u539f\u9879\u76ee\u7684 NuGet \u5305\u3002\u4f8b\u5982\uff0c\u8981\u5b89\u88c5\u6d41\u884c\u7684 Newtonsoft.Json \u5e93\uff0c\u60a8\u9700\u8981\u8fd0\u884c<\/p>\n<p>dotnet add package Newtonsoft.Json<\/p>\n<p>This command adds a reference to the latest version of the library to your project \ufb01le, as shown next, and makes the Newtonsoft.Json namespace available in your source-code \ufb01les:<br \/>\n\u6b64\u547d\u4ee4\u5c06\u5bf9\u6700\u65b0\u7248\u672c\u7684\u5e93\u7684\u5f15\u7528\u6dfb\u52a0\u5230\u60a8\u7684\u9879\u76ee\u6587\u4ef6\u4e2d\uff0c\u5982\u4e0b\u6240\u793a\uff0c\u5e76\u4f7f Newtonsoft.Json \u547d\u540d\u7a7a\u95f4\u5728\u60a8\u7684\u6e90\u4ee3\u7801\u6587\u4ef6\u4e2d\u53ef\u7528\uff1a\n<\/p><\/blockquote>\n<pre><code>\n&lt;Project Sdk=&quot;Microsoft.NET.Sdk.Web&quot;&gt;\n    &lt;PropertyGroup&gt;\n        &lt;TargetFramework&gt;net7.0&lt;\/TargetFramework&gt;\n            &lt;Nullable&gt;enable&lt;\/Nullable&gt;\n        &lt;ImplicitUsings&gt;enable&lt;\/ImplicitUsings&gt;\n    &lt;\/PropertyGroup&gt;\n    &lt;ItemGroup&gt;\n        &lt;PackageReference Include=&quot;NewtonSoft.Json&quot; Version=&quot;13.0.1&quot; \/&gt;\n    &lt;\/ItemGroup&gt;\n&lt;\/Project&gt;\n<\/code><\/pre>\n<blockquote>\n<p>If you\u2019re using Visual Studio, you can manage packages with the NuGet Package Manager by right-clicking the solution name or a project and choosing Manage NuGet Packages from the contextual menu.<br \/>\n\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f Visual Studio\uff0c\u5219\u53ef\u4ee5\u4f7f\u7528 NuGet \u5305\u7ba1\u7406\u5668\u7ba1\u7406\u5305\uff0c\u65b9\u6cd5\u662f\u53f3\u952e\u5355\u51fb\u89e3\u51b3\u65b9\u6848\u540d\u79f0\u6216\u9879\u76ee\uff0c\u7136\u540e\u4ece\u4e0a\u4e0b\u6587\u83dc\u5355\u4e2d\u9009\u62e9 Manage NuGet Packages\u3002<\/p>\n<p>As a point of interest, there\u2019s no o\ufb03cially agreed-on pronunciation for NuGet. Feel free to use the popular \u201cnoo-get\u201d or \u201cnugget\u201d style, or if you\u2019re feeling especially posh, try \u201cnoo-jay\u201d!<br \/>\n\u503c\u5f97\u4e00\u63d0\u7684\u662f\uff0cNuGet \u6ca1\u6709\u6b63\u5f0f\u5546\u5b9a\u7684\u53d1\u97f3\u3002\u968f\u610f\u4f7f\u7528\u6d41\u884c\u7684 \u201cno-get\u201d \u6216 \u201cnugget\u201d \u98ce\u683c\uff0c\u6216\u8005\u5982\u679c\u4f60\u89c9\u5f97\u7279\u522b\u65f6\u9ae6\uff0c\u8bd5\u8bd5 \u201cno-jay\u201d\u5427\uff01<\/p>\n<\/blockquote>\n<p>The simpli\ufb01ed project \ufb01le format is much easier to edit by hand than previous versions, which is great if you\u2019re developing cross- platform. But if you\u2019re using Visual Studio, don\u2019t feel that you have to take this route. You can still use the GUI to add project references, exclude \ufb01les, manage NuGet packages, and so on.<\/p>\n<p>\u7b80\u5316\u7684\u9879\u76ee\u6587\u4ef6\u683c\u5f0f\u6bd4\u4ee5\u524d\u7684\u7248\u672c\u66f4\u5bb9\u6613\u624b\u52a8\u7f16\u8f91\uff0c\u5982\u679c\u60a8\u6b63\u5728\u8de8\u5e73\u53f0\u5f00\u53d1\uff0c\u8fd9\u975e\u5e38\u6709\u7528\u3002\u4f46\u662f\uff0c\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f Visual Studio\uff0c\u8bf7\u4e0d\u8981\u89c9\u5f97\u60a8\u5fc5\u987b\u8d70\u8fd9\u6761\u8def\u3002\u60a8\u4ecd\u7136\u53ef\u4ee5\u4f7f\u7528 GUI \u6dfb\u52a0\u9879\u76ee\u5f15\u7528\u3001\u6392\u9664\u6587\u4ef6\u3001\u7ba1\u7406 NuGet \u5305\u7b49\u3002<\/p>\n<p>Visual Studio will update the project \ufb01le itself, as it always has.<\/p>\n<p>Visual Studio \u5c06\u4e00\u5982\u65e2\u5f80\u5730\u66f4\u65b0\u9879\u76ee\u6587\u4ef6\u672c\u8eab\u3002<\/p>\n<p><strong>TIP<\/strong> For further details on the changes to the csproj format, see the documentation at <a href=\"http:\/\/mng.bz\/vnzJ\">http:\/\/mng.bz\/vnzJ<\/a>.<br \/>\n<strong>\u63d0\u793a<\/strong> \u6709\u5173\u5bf9 csproj \u683c\u5f0f\u7684\u66f4\u6539\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 <a href=\"http:\/\/mng.bz\/vnzJ\">http:\/\/mng.bz\/vnzJ<\/a> \u4e2d\u7684\u6587\u6863\u3002<\/p>\n<p>The project \ufb01le de\ufb01nes everything Visual Studio and the .NET CLI need to build your app\u2014everything, that is, except the code! In the next section we\u2019ll look at the \ufb01le that de\ufb01nes your whole ASP.NET Core application: the Program.cs \ufb01le.<\/p>\n<p>\u9879\u76ee\u6587\u4ef6\u5b9a\u4e49\u4e86 Visual Studio \u548c .NET CLI \u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u4e00\u5207\uff0c\u5373\u9664\u4ee3\u7801\u4e4b\u5916\u7684\u6240\u6709\u5185\u5bb9\uff01\u5728\u4e0b\u4e00\u8282\u4e2d\uff0c\u6211\u4eec\u5c06\u67e5\u770b\u5b9a\u4e49\u6574\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\uff1aProgram.cs \u6587\u4ef6\u3002<\/p>\n<h3>3.6 Program.cs \ufb01le: De\ufb01ning your application\u200c<\/h3>\n<h3>3.6 Program.cs \u6587\u4ef6\uff1a\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f<\/h3>\n<p>All ASP.NET Core applications start life as a .NET Console application. As of .NET 6, that typically means a program written with top-level statements, in which the startup code for your application is written directly in a file instead of inside a static void Main function.<\/p>\n<p>\u6240\u6709 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u90fd\u4ee5 .NET \u63a7\u5236\u53f0\u5e94\u7528\u7a0b\u5e8f\u7684\u5f62\u5f0f\u5f00\u59cb\u8fd0\u884c\u3002\u4ece .NET 6 \u5f00\u59cb\uff0c\u8fd9\u901a\u5e38\u610f\u5473\u7740\u4f7f\u7528\u9876\u7ea7\u8bed\u53e5\u7f16\u5199\u7684\u7a0b\u5e8f\uff0c\u5176\u4e2d\u5e94\u7528\u7a0b\u5e8f\u7684\u542f\u52a8\u4ee3\u7801\u76f4\u63a5\u5199\u5165\u6587\u4ef6\u4e2d\uff0c\u800c\u4e0d\u662f\u5199\u5165\u9759\u6001 void Main \u51fd\u6570\u4e2d\u3002<\/p>\n<blockquote>\n<p>Top-level statements<br \/>\n\u9876\u7ea7\u8bed\u53e5<\/p>\n<p>Before C# 9, every .NET program had to include a static void Main function (it could also return int, Task, or Task<int>), typically declared in a class called Program. This function, which must exist, de\ufb01nes the entry point for your program. This code runs when you start your application, as in this example:<br \/>\n\u5728 C# 9 \u4e4b\u524d\uff0c\u6bcf\u4e2a .NET \u7a0b\u5e8f\u90fd\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u9759\u6001 void Main \u51fd\u6570\uff08\u5b83\u4e5f\u53ef\u4ee5\u8fd4\u56de int\u3001Task \u6216 Task<int>\uff09\uff0c\u901a\u5e38\u5728\u540d\u4e3a Program \u7684\u7c7b\u4e2d\u58f0\u660e\u3002\u6b64\u51fd\u6570\u5fc5\u987b\u5b58\u5728\uff0c\u7528\u4e8e\u5b9a\u4e49\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002\u6b64\u4ee3\u7801\u5728\u60a8\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u65f6\u8fd0\u884c\uff0c\u5982\u4e0b\u4f8b\u6240\u793a\uff1a<\/p>\n<\/blockquote>\n<pre><code>\nusing System;\nnamespace MyApp\n{\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            Console.WriteLine(&quot;Hello World!&quot;);\n        }\n    }\n}\n<\/code><\/pre>\n<blockquote>\n<p>With top-level statements you can write the body of this method directly in the \ufb01le, and the compiler generates the Main method for you.<br \/>\n\u4f7f\u7528\u9876\u7ea7\u8bed\u53e5\uff0c\u60a8\u53ef\u4ee5\u76f4\u63a5\u5728\u6587\u4ef6\u4e2d\u7f16\u5199\u6b64\u65b9\u6cd5\u7684\u4e3b\u4f53\uff0c\u7f16\u8bd1\u5668\u5c06\u4e3a\u60a8\u751f\u6210 Main \u65b9\u6cd5\u3002<\/p>\n<p>When combined with C# 10 features such as implicit using statements, this dramatically simpli\ufb01es the entry-point code of your app to<br \/>\n\u5f53\u4e0e C# 10 \u529f\u80fd\uff08\u5982\u9690\u5f0f using \u8bed\u53e5\uff09\u7ed3\u5408\u4f7f\u7528\u65f6\uff0c\u8fd9\u4f1a\u6781\u5927\u5730\u7b80\u5316\u5e94\u7528\u7684\u5165\u53e3\u70b9\u4ee3\u7801\uff0c\u4ee5\u4fbf<\/p>\n<\/blockquote>\n<pre><code>\nConsole.WriteLine(&quot;Hello World!&quot;);\n<\/code><\/pre>\n<blockquote>\n<p>When you use the explicit Main function you can access the command-line arguments provided when the app was run using the args parameter. With top- level statements the args variable is also available as a string[], even though it\u2019s not declared explicitly. You could echo each argument provided by using\u200c<br \/>\n\u60a8\u4f7f\u7528\u663e\u5f0f Main \u51fd\u6570\u65f6\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 args \u53c2\u6570\u8bbf\u95ee\u5728\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u65f6\u63d0\u4f9b\u7684\u547d\u4ee4\u884c\u53c2\u6570\u3002\u5bf9\u4e8e\u9876\u7ea7\u8bed\u53e5\uff0cargs \u53d8\u91cf\u4e5f\u53ef\u4ee5\u4f5c\u4e3a string[] \u4f7f\u7528\uff0c\u5373\u4f7f\u5b83\u6ca1\u6709\u663e\u5f0f\u58f0\u660e\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528<\/p>\n<\/blockquote>\n<pre><code>\nforeach(string arg in args)\n{\n    Console.WriteLine(arg);\n}\n<\/code><\/pre>\n<blockquote>\n<p>In .NET 7 all the default templates use top-level statements, and I use them throughout this book. Most of the templates include an option to use the explicit Main function if you prefer (using the --use-program-main option if you\u2019re using the CLI). For more information on top-level statements and their limitations, see <a href=\"http:\/\/mng.bz\/4DZa\">http:\/\/mng.bz\/4DZa<\/a>. If you decide to switch approaches later, you can always add or remove the Main function manually as required.<br \/>\n\u5728 .NET 7 \u4e2d\uff0c\u6240\u6709\u9ed8\u8ba4\u6a21\u677f\u90fd\u4f7f\u7528\u9876\u7ea7\u8bed\u53e5\uff0c\u6211\u5728\u672c\u4e66\u4e2d\u4e00\u76f4\u4f7f\u7528\u5b83\u4eec\u3002\u5982\u679c\u60a8\u613f\u610f\uff0c\u5927\u591a\u6570\u6a21\u677f\u90fd\u5305\u542b\u4e00\u4e2a\u9009\u9879\uff0c\u53ef\u4ee5\u4f7f\u7528\u663e\u5f0f\u7684 Main \u51fd\u6570\uff08\u5982\u679c\u60a8\u4f7f\u7528\u7684\u662f CLI\uff0c\u8bf7\u4f7f\u7528 --use-program-main \u9009\u9879\uff09\u3002\u6709\u5173 top-level \u8bed\u53e5\u53ca\u5176\u9650\u5236\u7684\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 <a href=\"http:\/\/mng.bz\/4DZa\u3002\u5982\u679c\u60a8\u51b3\u5b9a\u7a0d\u540e\u5207\u6362\u65b9\u6cd5\uff0c\u5219\u59cb\u7ec8\u53ef\u4ee5\u6839\u636e\u9700\u8981\u624b\u52a8\u6dfb\u52a0\u6216\u5220\u9664\">http:\/\/mng.bz\/4DZa\u3002\u5982\u679c\u60a8\u51b3\u5b9a\u7a0d\u540e\u5207\u6362\u65b9\u6cd5\uff0c\u5219\u59cb\u7ec8\u53ef\u4ee5\u6839\u636e\u9700\u8981\u624b\u52a8\u6dfb\u52a0\u6216\u5220\u9664<\/a> Main \u51fd\u6570\u3002<\/p>\n<\/blockquote>\n<p>In .NET 7 ASP.NET Core applications the top-level statements build and run a WebApplication instance, as shown in the following listing, which shows the default Program.cs \ufb01le. The WebApplication is the core of your ASP.NET Core application, containing the application con\ufb01guration and the Kestrel server that listens for requests and sends responses.<\/p>\n<p>\u5728 .NET 7 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u9876\u7ea7\u8bed\u53e5\u6784\u5efa\u5e76\u8fd0\u884c WebApplication \u5b9e\u4f8b\uff0c\u5982\u4e0b\u9762\u7684\u6e05\u5355\u6240\u793a\uff0c\u5176\u4e2d\u663e\u793a\u4e86\u9ed8\u8ba4\u7684 Program.cs \u6587\u4ef6\u3002WebApplication \u662f ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u6838\u5fc3\uff0c\u5305\u542b\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u548c\u4fa6\u542c\u8bf7\u6c42\u5e76\u53d1\u9001\u54cd\u5e94\u7684 Kestrel \u670d\u52a1\u5668\u3002<\/p>\n<p>Listing 3.3 The default Program.cs \ufb01le that con\ufb01gures and runs a WebApplication<br \/>\n\u5217\u8868 3.3 \u914d\u7f6e\u548c\u8fd0\u884c WebApplication \u7684\u9ed8\u8ba4 Program.cs \u6587\u4ef6<\/p>\n<pre><code>\nWebApplicationBuilder builder = WebApplication.CreateBuilder(args); \u2776\nWebApplication app = builder.Build();                               \u2777\napp.MapGet(&quot;\/&quot;, () =&gt; &quot;Hello World!&quot;);                              \u2778\napp.Run();                                                          \u2779\n<\/code><\/pre>\n<p>\u2776 Creates a WebApplicationBuilder using the CreateBuilder method<br \/>\n\u4f7f\u7528 CreateBuilder \u65b9\u6cd5\u521b\u5efa WebApplicationBuilder<\/p>\n<p>\u2777 Builds and returns an instance of WebApplication from the WebApplicationBuilder<br \/>\n\u4ece WebApplicationBuilder \u6784\u5efa\u5e76\u8fd4\u56de WebApplication \u7684\u5b9e\u4f8b<\/p>\n<p>\u2778 Defines an endpoint for your application, which returns Hello World! when the path \u201c\/\u201d is called<br \/>\n\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5b9a\u4e49\u4e00\u4e2a\u7aef\u70b9\uff0c\u5f53\u8c03\u7528\u8def\u5f84 \u201c\/\u201d \u65f6\uff0c\u8be5\u7aef\u70b9\u5c06\u8fd4\u56de Hello World\uff01<\/p>\n<p>\u2779 Runs the WebApplication to start listening for requests and generating responses<br \/>\n\u8fd0\u884c WebApplication \u4ee5\u5f00\u59cb\u4fa6\u542c\u8bf7\u6c42\u5e76\u751f\u6210\u54cd\u5e94<\/p>\n<p>These four lines contain all the initialization code you need to create a web server and start listening for requests. It uses a WebApplicationBuilder, created by the call to CreateBuilder, to de\ufb01ne how the WebApplication is con\ufb01gured, before instantiating the WebApplication with a call to Build().<\/p>\n<p>\u8fd9\u56db\u884c\u5305\u542b\u521b\u5efa Web \u670d\u52a1\u5668\u548c\u5f00\u59cb\u4fa6\u542c\u8bf7\u6c42\u6240\u9700\u7684\u6240\u6709\u521d\u59cb\u5316\u4ee3\u7801\u3002\u5b83\u4f7f\u7528\u901a\u8fc7\u8c03\u7528 CreateBuilder \u521b\u5efa\u7684 WebApplicationBuilder \u6765\u5b9a\u4e49 WebApplication \u7684\u914d\u7f6e\u65b9\u5f0f\uff0c\u7136\u540e\u901a\u8fc7\u8c03\u7528 Build\uff08\uff09 \u5b9e\u4f8b\u5316 WebApplication\u3002<\/p>\n<p><strong>NOTE<\/strong> You\u2019ll \ufb01nd this pattern of using a builder object to con\ufb01gure a complex object repeated throughout the ASP.NET Core framework. This technique is useful for allowing users to con\ufb01gure an object, delaying its creation until all con\ufb01guration has \ufb01nished. It\u2019s also one of the patterns described in the \u201cGang of Four\u201d book Design Patterns: Elements of Reusable Object- Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (Addison-Wesley, 1994).\u200c\u200c\u200c\u200c<br \/>\n<strong>\u6ce8\u610f<\/strong> \u60a8\u4f1a\u53d1\u73b0\u8fd9\u79cd\u4f7f\u7528 builder \u5bf9\u8c61\u914d\u7f6e\u590d\u6742\u5bf9\u8c61\u7684\u6a21\u5f0f\u5728\u6574\u4e2a ASP.NET Core \u6846\u67b6\u4e2d\u91cd\u590d\u51fa\u73b0\u3002\u6b64\u6280\u672f\u53ef\u7528\u4e8e\u5141\u8bb8\u7528\u6237\u914d\u7f6e\u5bf9\u8c61\uff0c\u5ef6\u8fdf\u5176\u521b\u5efa\uff0c\u76f4\u5230\u6240\u6709\u914d\u7f6e\u5b8c\u6210\u3002\u5b83\u4e5f\u662f Erich Gamma\u3001Richard Helm\u3001Ralph Johnson \u548c John Vlissides \u5408\u8457\u7684\u300a\u8bbe\u8ba1\u6a21\u5f0f\uff1a\u53ef\u91cd\u7528\u9762\u5411\u5bf9\u8c61\u8f6f\u4ef6\u7684\u5143\u7d20\u300b\uff08Addison-Wesley\uff0c1994 \u5e74\uff09\u4e00\u4e66\u4e2d\u63cf\u8ff0\u7684\u6a21\u5f0f\u4e4b\u4e00\u3002<\/p>\n<p>In this simple application we don\u2019t make any changes to WebApplicationBuilder before calling Build(), but WebApplicationBuilder con\ufb01gures a lot of things by default, including<\/p>\n<p>\u5728\u8fd9\u4e2a\u7b80\u5355\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u6211\u4eec\u5728\u8c03\u7528 Build\uff08\uff09 \u4e4b\u524d\u4e0d\u4f1a\u5bf9 WebApplicationBuilder \u8fdb\u884c\u4efb\u4f55\u66f4\u6539\uff0c\u4f46 WebApplicationBuilder \u9ed8\u8ba4\u914d\u7f6e\u4e86\u5f88\u591a\u5185\u5bb9\uff0c\u5305\u62ec<\/p>\n<ul>\n<li>\n<p>Con\ufb01guration\u2014Your app loads values from JSON \ufb01les and environment variables that you can use to control the app\u2019s runtime behavior, such as loading connection strings for a database. You\u2019ll learn more about the con\ufb01guration system in chapter 10.<br \/>\n\u914d\u7f6e \u2013 \u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4ece JSON \u6587\u4ef6\u548c\u73af\u5883\u53d8\u91cf\u52a0\u8f7d\u503c\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e9b\u503c\u6765\u63a7\u5236\u5e94\u7528\u7a0b\u5e8f\u7684\u8fd0\u884c\u65f6\u884c\u4e3a\uff0c\u4f8b\u5982\u52a0\u8f7d\u6570\u636e\u5e93\u7684\u8fde\u63a5\u5b57\u7b26\u4e32\u3002\u60a8\u5c06\u5728\u7b2c 10 \u7ae0\u4e2d\u4e86\u89e3\u6709\u5173\u914d\u7f6e\u7cfb\u7edf\u7684\u66f4\u591a\u4fe1\u606f\u3002<\/p>\n<\/li>\n<li>\n<p>Logging\u2014ASP.NET Core includes an extensible logging system for observability and debugging. I cover the logging system in detail in chapter 26.<br \/>\n\u65e5\u5fd7\u8bb0\u5f55 \u2014 ASP.NET Core \u5305\u62ec\u4e00\u4e2a\u53ef\u6269\u5c55\u7684\u65e5\u5fd7\u8bb0\u5f55\u7cfb\u7edf\uff0c\u7528\u4e8e\u53ef\u89c2\u5bdf\u6027\u548c\u8c03\u8bd5\u3002\u6211\u5728\u7b2c 26 \u7ae0\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u65e5\u5fd7\u8bb0\u5f55\u7cfb\u7edf\u3002<\/p>\n<\/li>\n<li>\n<p>Services\u2014Any classes that your application depends on for providing functionality\u2014both those used by the framework and those speci\ufb01c to your application\u2014 must be registered so that they can be instantiated correctly at runtime. The WebApplicationBuilder con\ufb01gures the minimal set of services needed for an ASP.NET Core app. Chapters 8 and 9 look at service con\ufb01guration in detail.<br \/>\n\u670d\u52a1 \u2014 \u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7528\u4e8e\u63d0\u4f9b\u529f\u80fd\u6240\u4f9d\u8d56\u7684\u4efb\u4f55\u7c7b\uff08\u6846\u67b6\u4f7f\u7528\u7684\u7c7b\u548c\u7279\u5b9a\u4e8e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u7c7b\uff09\u90fd\u5fc5\u987b\u6ce8\u518c\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u5728\u8fd0\u884c\u65f6\u6b63\u786e\u5b9e\u4f8b\u5316\u5b83\u4eec\u3002WebApplicationBuilder \u914d\u7f6e ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u6240\u9700\u7684\u6700\u5c0f\u670d\u52a1\u96c6\u3002\u7b2c 8 \u7ae0\u548c\u7b2c 9 \u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u670d\u52a1\u914d\u7f6e\u3002<\/p>\n<\/li>\n<li>\n<p>Hosting\u2014ASP.NET Core uses the Kestrel web server by default to handle requests.<br \/>\n\u6258\u7ba1 \u2014 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cASP.NET Core \u4f7f\u7528 Kestrel Web \u670d\u52a1\u5668\u6765\u5904\u7406\u8bf7\u6c42\u3002<\/p>\n<\/li>\n<\/ul>\n<p>After con\ufb01guring the WebApplicationBuilder you call Build() to create a WebApplication instance. The WebApplication instance is where you de\ufb01ne how your application handles and responds to requests, using two building blocks:<\/p>\n<p>\u914d\u7f6e WebApplicationBuilder \u540e\uff0c\u8c03\u7528 Build\uff08\uff09 \u6765\u521b\u5efa WebApplication \u5b9e\u4f8b\u3002WebApplication \u5b9e\u4f8b\u662f\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u5904\u7406\u548c\u54cd\u5e94\u8bf7\u6c42\u7684\u5730\u65b9\uff0c\u5b83\u4f7f\u7528\u4e24\u4e2a\u6784\u5efa\u5757\uff1a<\/p>\n<ul>\n<li>\n<p>Middleware\u2014These small components execute in sequence when the application receives an HTTP request. They can perform a whole host of functions, such as logging, identifying the current user for a request, serving static \ufb01les, and handling errors. We\u2019ll look in detail at the middleware pipeline in chapter 4.<br \/>\n\u4e2d\u95f4\u4ef6 \u2014 \u5f53\u5e94\u7528\u7a0b\u5e8f\u6536\u5230 HTTP \u8bf7\u6c42\u65f6\uff0c\u8fd9\u4e9b\u5c0f\u7ec4\u4ef6\u4f1a\u6309\u987a\u5e8f\u6267\u884c\u3002\u5b83\u4eec\u53ef\u4ee5\u6267\u884c\u4e00\u7cfb\u5217\u529f\u80fd\uff0c\u4f8b\u5982\u65e5\u5fd7\u8bb0\u5f55\u3001\u8bc6\u522b\u8bf7\u6c42\u7684\u5f53\u524d\u7528\u6237\u3001\u63d0\u4f9b\u9759\u6001\u6587\u4ef6\u4ee5\u53ca\u5904\u7406\u9519\u8bef\u3002\u6211\u4eec\u5c06\u5728\u7b2c 4 \u7ae0\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002<\/p>\n<\/li>\n<li>\n<p>Endpoints\u2014Endpoints de\ufb01ne how the response should be generated for a speci\ufb01c request to a URL in your app.<br \/>\n\u7aef\u70b9 - \u7aef\u70b9\u5b9a\u4e49\u5e94\u5982\u4f55\u4e3a\u5e94\u7528\u7a0b\u5e8f\u4e2d URL \u7684\u7279\u5b9a\u8bf7\u6c42\u751f\u6210\u54cd\u5e94\u3002<\/p>\n<\/li>\n<\/ul>\n<p>For the application in listing 3.3, we didn\u2019t add any middleware, but we de\ufb01ned a single endpoint using a call to MapGet:<\/p>\n<p>\u5bf9\u4e8e\u6e05\u5355 3.3 \u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u6211\u4eec\u6ca1\u6709\u6dfb\u52a0\u4efb\u4f55\u4e2d\u95f4\u4ef6\uff0c\u4f46\u6211\u4eec\u4f7f\u7528\u5bf9 MapGet \u7684\u8c03\u7528\u5b9a\u4e49\u4e86\u4e00\u4e2a\u7aef\u70b9\uff1a<\/p>\n<pre><code>app.MapGet(&quot;\/&quot;, () =&gt; &quot;Hello World!&quot;);<\/code><\/pre>\n<p>You use the MapGet function to de\ufb01ne how to handle a request that uses the GET HTTP verb. There are other Map* functions for other HTTP verbs, such as MapPost.\u200c\u200c<\/p>\n<p>\u4f7f\u7528 MapGet \u51fd\u6570\u5b9a\u4e49\u5982\u4f55\u5904\u7406\u4f7f\u7528 GET HTTP \u52a8\u8bcd\u7684\u8bf7\u6c42\u3002\u8fd8\u6709\u5176\u4ed6 Map* \u51fd\u6570\u53ef\u7528\u4e8e\u5176\u4ed6 HTTP \u52a8\u8bcd\uff0c\u4f8b\u5982 MapPost\u3002<\/p>\n<p><strong>DEFINITION<\/strong> Every HTTP request includes a verb that indicates the type of the request. When you\u2019re browsing a website, the default verb is GET, which fetches a resource from the server so you can view it. The second-most-common verb is POST, which is used to send data to the server, such as when you\u2019re completing a form.<br \/>\n<strong>\u5b9a\u4e49<\/strong> \u6bcf\u4e2a HTTP \u8bf7\u6c42\u90fd\u5305\u542b\u4e00\u4e2a\u52a8\u8bcd\uff0c\u7528\u4e8e\u6307\u793a\u8bf7\u6c42\u7684\u7c7b\u578b\u3002\u5f53\u60a8\u6d4f\u89c8\u7f51\u7ad9\u65f6\uff0c\u9ed8\u8ba4\u52a8\u8bcd\u662f GET\uff0c\u5b83\u4ece\u670d\u52a1\u5668\u83b7\u53d6\u8d44\u6e90\u4ee5\u4fbf\u60a8\u53ef\u4ee5\u67e5\u770b\u5b83\u3002\u7b2c\u4e8c\u5e38\u89c1\u7684\u52a8\u8bcd\u662f POST\uff0c\u7528\u4e8e\u5c06\u6570\u636e\u53d1\u9001\u5230\u670d\u52a1\u5668\uff0c\u4f8b\u5982\u5f53\u60a8\u586b\u5199\u8868\u5355\u65f6\u3002<\/p>\n<p>The \ufb01rst argument passed to MapGet de\ufb01nes which URL path to respond to, and the second argument de\ufb01nes how to generate the response as a delegate that returns a string. In this simple case, the arguments say \u201cWhen a request is made to the path \/ using the GET HTTP verb, respond with the plain-text value Hello World!\u201d.<\/p>\n<p>\u4f20\u9012\u7ed9 MapGet \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u5b9a\u4e49\u8981\u54cd\u5e94\u7684 URL \u8def\u5f84\uff0c\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5b9a\u4e49\u5982\u4f55\u5c06\u54cd\u5e94\u751f\u6210\u4e3a\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u59d4\u6258\u3002\u5728\u8fd9\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\u4e2d\uff0c\u53c2\u6570\u8bf4\u201c\u5f53\u4f7f\u7528 GET HTTP \u52a8\u8bcd\u5411\u8def\u5f84\u53d1\u51fa\u8bf7\u6c42\u65f6\uff0c\u4f7f\u7528\u7eaf\u6587\u672c\u503c Hello World\uff01 \u8fdb\u884c\u54cd\u5e94\u201d\u3002<\/p>\n<p><strong>DEFINITION<\/strong> A path is the remainder of the request URL after the domain has been removed. For a request to www.example.org\/accout\/manage, the path is \/account\/manage.<br \/>\n<strong>\u5b9a\u4e49<\/strong> \u8def\u5f84\u662f\u5220\u9664\u57df\u540e\u8bf7\u6c42 URL \u7684\u5176\u4f59\u90e8\u5206\u3002\u5bf9\u4e8e www.example.org\/accout\/manage \u7684\u8bf7\u6c42\uff0c\u8def\u5f84\u4e3a\/account\/manage \u4e2d\u3002<\/p>\n<p>While you\u2019re con\ufb01guring the WebApplication and WebApplicationBuilder the application isn\u2019t handling HTTP requests. Only after the call to Run() does the HTTP server start listening for requests. At this point, your application is fully operational and can respond to its \ufb01rst request from a remote browser.<\/p>\n<p>\u5728\u914d\u7f6e WebApplication \u548c WebApplicationBuilder \u65f6\uff0c\u5e94\u7528\u7a0b\u5e8f\u4e0d\u5904\u7406 HTTP \u8bf7\u6c42\u3002\u53ea\u6709\u5728\u8c03\u7528 Run\uff08\uff09 \u4e4b\u540e\uff0cHTTP \u670d\u52a1\u5668\u624d\u4f1a\u5f00\u59cb\u4fa6\u542c\u8bf7\u6c42\u3002\u6b64\u65f6\uff0c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5df2\u5b8c\u5168\u8fd0\u884c\uff0c\u5e76\u4e14\u53ef\u4ee5\u54cd\u5e94\u6765\u81ea\u8fdc\u7a0b\u6d4f\u89c8\u5668\u7684\u7b2c\u4e00\u4e2a\u8bf7\u6c42\u3002<\/p>\n<p><strong>NOTE<\/strong> The WebApplication and WebApplicationBuilder classes were introduced in .NET 6. The initialization code in previous versions of ASP.NET Core was more verbose but gave you more control of your application\u2019s behavior. Con\ufb01guration was typically split between two classes\u2014Program and Startup\u200c\u200c\u200c and used di\ufb00erent con\ufb01guration types\u2014IHostBuilder and IHost, which have fewer defaults than WebApplication. In chapter 30 I describe some of these di\ufb00erences in more detail and show how to con\ufb01gure your application by using the generic IHost instead of WebApplication.<br \/>\n<strong>\u6ce8\u610f<\/strong> WebApplication \u548c WebApplicationBuilder \u7c7b\u662f\u5728 .NET 6 \u4e2d\u5f15\u5165\u7684\u3002\u4ee5\u524d\u7248\u672c\u7684 ASP.NET Core \u4e2d\u7684\u521d\u59cb\u5316\u4ee3\u7801\u66f4\u5197\u957f\uff0c\u4f46\u53ef\u4ee5\u8ba9\u60a8\u66f4\u597d\u5730\u63a7\u5236\u5e94\u7528\u7a0b\u5e8f\u7684\u884c\u4e3a\u3002\u914d\u7f6e\u901a\u5e38\u5206\u4e3a\u4e24\u4e2a\u7c7b \u2014 Program \u548c Startup\uff0c\u5e76\u4f7f\u7528\u4e86\u4e0d\u540c\u7684\u914d\u7f6e\u7c7b\u578b - IHostBuilder \u548cIHost \u7684\u9ed8\u8ba4\u503c\u6bd4 WebApplication \u5c11\u3002\u5728\u7b2c 30 \u7ae0\u4e2d\uff0c\u6211\u5c06\u66f4\u8be6\u7ec6\u5730\u63cf\u8ff0\u5176\u4e2d\u7684\u4e00\u4e9b\u5dee\u5f02\uff0c\u5e76\u6f14\u793a\u5982\u4f55\u4f7f\u7528\u6cdb\u578b IHost \u800c\u4e0d\u662f WebApplication \u6765\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>So far in this chapter, we\u2019ve looked at the simplest ASP.NET core application you can build: a Hello World minimal API application. For the remainder of this chapter, we\u2019re going to build on this app to introduce some fundamental concepts of ASP.NET Core.\u200c<\/p>\n<p>\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u5df2\u7ecf\u4e86\u89e3\u4e86\u60a8\u53ef\u4ee5\u6784\u5efa\u7684\u6700\u7b80\u5355\u7684 ASP.NET \u6838\u5fc3\u5e94\u7528\u7a0b\u5e8f\uff1aHello World \u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\u3002\u5728\u672c\u7ae0\u7684\u5176\u4f59\u90e8\u5206\uff0c\u6211\u4eec\u5c06\u5728\u6b64\u5e94\u7528\u7a0b\u5e8f\u7684\u57fa\u7840\u4e0a\u4ecb\u7ecd ASP.NET Core \u7684\u4e00\u4e9b\u57fa\u672c\u6982\u5ff5\u3002<\/p>\n<h3>3.7 Adding functionality to your application\u200c<\/h3>\n<h3>3.7 \u5411\u5e94\u7528\u7a0b\u5e8f\u6dfb\u52a0\u529f\u80fd<\/h3>\n<p>The application setup you\u2019ve seen so far in Program.cs consists of only four lines of code but still shows the overall structure of a typical ASP.NET Core app entry point, which typically consists of six steps:<\/p>\n<p>\u5230\u76ee\u524d\u4e3a\u6b62\uff0c\u60a8\u5728 Program.cs \u4e2d\u770b\u5230\u7684\u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e\u4ec5\u5305\u542b\u56db\u884c\u4ee3\u7801\uff0c\u4f46\u4ecd\u663e\u793a\u4e86\u5178\u578b\u7684 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u5165\u53e3\u70b9\u7684\u6574\u4f53\u7ed3\u6784\uff0c\u901a\u5e38\u5305\u62ec\u516d\u4e2a\u6b65\u9aa4\uff1a<\/p>\n<ol>\n<li>\n<p>Create a WebApplicationBuilder instance.<br \/>\n\u521b\u5efa WebApplicationBuilder \u5b9e\u4f8b\u3002<\/p>\n<\/li>\n<li>\n<p>Register the required services and con\ufb01guration with the WebApplicationBuilder.<br \/>\n\u5411 WebApplicationBuilder \u6ce8\u518c\u6240\u9700\u7684\u670d\u52a1\u548c\u914d\u7f6e\u3002<\/p>\n<\/li>\n<li>\n<p>Call Build() on the builder instance to create a WebApplication instance.<br \/>\n\u5728\u6784\u5efa\u5668\u5b9e\u4f8b\u4e0a\u8c03\u7528 Build\uff08\uff09 \u4ee5\u521b\u5efa\u4e00\u4e2aWebApplication \u5b9e\u4f8b\u3002<\/p>\n<\/li>\n<li>\n<p>Add middleware to the WebApplication to create a pipeline.<br \/>\n\u5c06\u4e2d\u95f4\u4ef6\u6dfb\u52a0\u5230 WebApplication \u4ee5\u521b\u5efa\u7ba1\u9053\u3002<\/p>\n<\/li>\n<li>\n<p>Map the endpoints in your application.<br \/>\n\u6620\u5c04\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u7ec8\u7aef\u8282\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Call Run() on the WebApplication to start the server and handle requests.<br \/>\n\u5728 WebApplication \u4e0a\u8c03\u7528 Run\uff08\uff09 \u4ee5\u542f\u52a8\u670d\u52a1\u5668\u5e76\u5904\u7406\u8bf7\u6c42\u3002<\/p>\n<\/li>\n<\/ol>\n<p>The basic minimal API app shown previously in listing 3.3 was simple enough that it didn\u2019t need steps 2 and 4, but otherwise it followed this sequence in its Program.cs \ufb01le. The following listing extends the default application to add more functionality, and in doing so it uses all six steps.<br \/>\n\u524d\u9762\u6e05\u5355 3.3 \u4e2d\u6240\u793a\u7684\u57fa\u672c\u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\u975e\u5e38\u7b80\u5355\uff0c\u5b83\u4e0d\u9700\u8981\u6b65\u9aa4 2 \u548c 4\uff0c\u4f46\u9664\u6b64\u4e4b\u5916\uff0c\u5b83\u5728\u5176 Program.cs \u6587\u4ef6\u4e2d\u9075\u5faa\u6b64\u987a\u5e8f\u3002\u4e0b\u9762\u7684\u6e05\u5355\u6269\u5c55\u4e86\u9ed8\u8ba4\u5e94\u7528\u7a0b\u5e8f\u4ee5\u6dfb\u52a0\u66f4\u591a\u529f\u80fd\uff0c\u5728\u6b64\u8fc7\u7a0b\u4e2d\uff0c\u5b83\u4f7f\u7528\u4e86\u6240\u6709 6 \u4e2a\u6b65\u9aa4\u3002<\/p>\n<p>Listing 3.4 The Program.cs \ufb01le for a more complex example minimal API<br \/>\n\u5217\u8868 3.4 \u66f4\u590d\u6742\u7684\u793a\u4f8b\u6700\u5c0f API \u7684 Program.cs \u6587\u4ef6<\/p>\n<pre><code>using Microsoft.AspNetCore.HttpLogging;\n\nWebApplicationBuilder builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddHttpLogging(opts =&gt;  opts.LoggingFields = HttpLoggingFields.RequestProperties);    \u2776\n\nbuilder.Logging.AddFilter( &quot;Microsoft.AspNetCore.HttpLogging&quot;, LogLevel.Information);                  \u2777\n\nWebApplication app = builder.Build();\n\nif (app.Environment.IsDevelopment())                                                                   \u2778\n{\n    app.UseHttpLogging();                                                                              \u2779\n}\n\napp.MapGet(&quot;\/&quot;, () =&gt; &quot;Hello World!&quot;);\napp.MapGet(&quot;\/person&quot;, () =&gt; new Person(&quot;Andrew&quot;, &quot;Lock&quot;));                                             \u277a\n\napp.Run();\n\npublic record Person(string FirstName, string LastName);                                               \u277b\n<\/code><\/pre>\n<p>\u2776 You can customize features by adding or customizing the services of the application.<br \/>\n\u60a8\u53ef\u4ee5\u901a\u8fc7\u6dfb\u52a0\u6216\u81ea\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u7684\u670d\u52a1\u6765\u81ea\u5b9a\u4e49\u529f\u80fd\u3002<\/p>\n<p>\u2777 Ensures that logs added by the HTTP logging middleware are visible in the log output<br \/>\n\u786e\u4fdd HTTP \u65e5\u5fd7\u8bb0\u5f55\u4e2d\u95f4\u4ef6\u6dfb\u52a0\u7684\u65e5\u5fd7\u5728\u65e5\u5fd7\u8f93\u51fa\u4e2d\u53ef\u89c1<\/p>\n<p>\u2778 You can add middleware conditionally, depending on the runtime environment.<br \/>\n\u60a8\u53ef\u4ee5\u6839\u636e\u8fd0\u884c\u65f6\u73af\u5883\u6709\u6761\u4ef6\u5730\u6dfb\u52a0\u4e2d\u95f4\u4ef6\u3002<\/p>\n<p>\u2779 The HTTP logging middleware logs each request to your application in the log output.<br \/>\nHTTP \u65e5\u5fd7\u8bb0\u5f55\u4e2d\u95f4\u4ef6\u5728\u65e5\u5fd7\u8f93\u51fa\u4e2d\u8bb0\u5f55\u5bf9\u5e94\u7528\u7a0b\u5e8f\u7684\u6bcf\u4e2a\u8bf7\u6c42\u3002<\/p>\n<p>\u277a Creates a new endpoint that returns the C# object serialized as JSON<br \/>\n\u521b\u5efa\u4e00\u4e2a\u65b0\u7aef\u70b9\uff0c\u8be5\u7aef\u70b9\u8fd4\u56de\u5e8f\u5217\u5316\u4e3a JSON \u7684 C# \u5bf9\u8c61<\/p>\n<p>\u277b Creates a record type<br \/>\n\u521b\u5efa\u8bb0\u5f55\u7c7b\u578b<\/p>\n<p>The application in listing 3.4 con\ufb01gures two new features:<\/p>\n<p>\u6e05\u5355 3.4 \u4e2d\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u4e86\u4e24\u4e2a\u65b0\u529f\u80fd<\/p>\n<ul>\n<li>\n<p>When running in the Development environment, details about each request are logged using the HttpLoggingMiddleware.4<br \/>\n\u5728 Development \u73af\u5883\u4e2d\u8fd0\u884c\u65f6\uff0c\u5c06\u4f7f\u7528 HttpLoggingMiddleware \u8bb0\u5f55\u6709\u5173\u6bcf\u4e2a\u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\u30024<\/p>\n<\/li>\n<li>\n<p>Creates a new endpoint at \/person that creates an instance of the C# record called Person and serializes it in the response as JSON.<br \/>\n\u5728 \/person \u5904\u521b\u5efa\u4e00\u4e2a\u65b0\u7aef\u70b9\uff0c\u8be5\u7aef\u70b9\u521b\u5efa\u540d\u4e3a Person \u7684 C# \u8bb0\u5f55\u5b9e\u4f8b\uff0c\u5e76\u5728\u54cd\u5e94\u4e2d\u5c06\u5176\u5e8f\u5217\u5316\u4e3a JSON\u3002<\/p>\n<\/li>\n<\/ul>\n<p>When you run the application and send requests via a web browser, you see details about the request displayed in the console, as shown in \ufb01gure 3.8. If you call the \/person endpoint you\u2019ll see the JSON representation of the Person record you created in the endpoint.<\/p>\n<p>\u5f53\u60a8\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u5e76\u901a\u8fc7 Web \u6d4f\u89c8\u5668\u53d1\u9001\u8bf7\u6c42\u65f6\uff0c\u60a8\u4f1a\u5728\u63a7\u5236\u53f0\u4e2d\u770b\u5230\u6709\u5173\u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5982\u56fe 3.8 \u6240\u793a\u3002\u5982\u679c\u60a8\u8c03\u7528 \/person \u7ec8\u7aef\u8282\u70b9\uff0c\u60a8\u5c06\u770b\u5230\u60a8\u5728\u7ec8\u7aef\u8282\u70b9\u4e2d\u521b\u5efa\u7684 Person \u8bb0\u5f55\u7684 JSON \u8868\u793a\u5f62\u5f0f\u3002<\/p>\n<p><strong>NOTE<\/strong> You can view the application only on the same computer that\u2019s running it at the moment; your application isn\u2019t exposed to the internet yet. You\u2019ll learn how to publish and deploy your application in chapter 27.<br \/>\n<strong>\u6ce8\u610f<\/strong> \u60a8\u53ea\u80fd\u5728\u5f53\u524d\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\u540c\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0a\u67e5\u770b\u8be5\u5e94\u7528\u7a0b\u5e8f;\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5c1a\u672a\u66b4\u9732\u5728 Internet \u4e0a\u3002\u60a8\u5c06\u5728\u7b2c 27 \u7ae0\u4e2d\u5b66\u4e60\u5982\u4f55\u53d1\u5e03\u548c\u90e8\u7f72\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0308.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.8 Calling the \/person endpoint returns a JSON- serialized version of the Person record instance. Details about each request are logged to the console by the HttpLoggingMiddleware.<br \/>\n\u56fe 3.8 \u8c03\u7528 \/person \u7aef\u70b9\u4f1a\u8fd4\u56de Person \u8bb0\u5f55\u5b9e\u4f8b\u7684 JSON \u5e8f\u5217\u5316\u7248\u672c\u3002\u6709\u5173\u6bcf\u4e2a\u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\u7531 HttpLoggingMiddleware \u8bb0\u5f55\u5230\u63a7\u5236\u53f0\u4e2d\u3002<\/p>\n<p>Con\ufb01guring services, logging, middleware, and endpoints is fundamental to building ASP.NET Core applications, so the rest of section 3.7 walks you through each of these concepts to give you a taste of how they\u2019re used. I won\u2019t explain them in detail (we have the rest of the book for that!), but you should keep in mind how they follow on from each other and how they contribute to the application\u2019s con\ufb01guration as a whole.<\/p>\n<p>\u914d\u7f6e\u670d\u52a1\u3001\u65e5\u5fd7\u8bb0\u5f55\u3001\u4e2d\u95f4\u4ef6\u548c\u7aef\u70b9\u662f\u6784\u5efa ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u57fa\u7840\uff0c\u56e0\u6b64\u7b2c 3.7 \u8282\u7684\u5176\u4f59\u90e8\u5206\u5c06\u5f15\u5bfc\u60a8\u4e86\u89e3\u8fd9\u4e9b\u6982\u5ff5\u4e2d\u7684\u6bcf\u4e00\u4e2a\uff0c\u4ee5\u4fbf\u60a8\u4e86\u89e3\u5b83\u4eec\u7684\u4f7f\u7528\u65b9\u5f0f\u3002\u6211\u4e0d\u4f1a\u8be6\u7ec6\u89e3\u91ca\u5b83\u4eec\uff08\u6211\u4eec\u8fd8\u6709\u672c\u4e66\u7684\u5176\u4f59\u90e8\u5206\u6765\u89e3\u91ca\uff09\uff0c\u4f46\u60a8\u5e94\u8be5\u8bb0\u4f4f\u5b83\u4eec\u5982\u4f55\u76f8\u4e92\u8ddf\u8fdb\uff0c\u4ee5\u53ca\u5b83\u4eec\u5982\u4f55\u4e3a\u6574\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u914d\u7f6e\u505a\u51fa\u8d21\u732e\u3002<\/p>\n<h4>3.7.1 Adding and con\ufb01guring services\u200c<\/h4>\n<h4>3.7.1 \u6dfb\u52a0\u548c\u914d\u7f6e\u670d\u52a1<\/h4>\n<p>ASP.NET Core uses small modular components for each distinct feature. This approach allows individual features to evolve separately, with only a loose coupling to others, and it\u2019s generally considered to be good design practice. The downside to this approach is that it places the burden on the consumer of a feature to instantiate it correctly. Within your application, these modular components are exposed as one or more services that are used by the application.<\/p>\n<p>ASP.NET Core \u4e3a\u6bcf\u4e2a\u4e0d\u540c\u7684\u529f\u80fd\u4f7f\u7528\u5c0f\u578b\u6a21\u5757\u5316\u7ec4\u4ef6\u3002\u8fd9\u79cd\u65b9\u6cd5\u5141\u8bb8\u5355\u4e2a\u529f\u80fd\u5355\u72ec\u53d1\u5c55\uff0c\u53ea\u4e0e\u5176\u4ed6\u529f\u80fd\u677e\u6563\u8026\u5408\uff0c\u8fd9\u901a\u5e38\u88ab\u8ba4\u4e3a\u662f\u826f\u597d\u7684\u8bbe\u8ba1\u5b9e\u8df5\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u7f3a\u70b9\u662f\uff0c\u5b83\u7ed9 Feature \u7684\u4f7f\u7528\u8005\u5e26\u6765\u4e86\u6b63\u786e\u5b9e\u4f8b\u5316\u5b83\u7684\u8d1f\u62c5\u3002\u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u8fd9\u4e9b\u6a21\u5757\u5316\u7ec4\u4ef6\u5c06\u4f5c\u4e3a\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u670d\u52a1\u516c\u5f00\u3002<\/p>\n<p><strong>DEFINITION<\/strong> Within the context of ASP.Net Core, service refers to any class that provides functionality to an application.<br \/>\n<strong>\u5b9a\u4e49<\/strong> \u5728 ASP.Net Core \u7684\u4e0a\u4e0b\u6587\u4e2d\uff0cservice \u662f\u6307\u4e3a\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u529f\u80fd\u7684\u4efb\u4f55\u7c7b\u3002<\/p>\n<p>Services could be classes exposed by a library or code you\u2019ve written for your application.<\/p>\n<p>\u670d\u52a1\u53ef\u4ee5\u662f\u7531\u60a8\u4e3a\u5e94\u7528\u7a0b\u5e8f\u7f16\u5199\u7684\u5e93\u6216\u4ee3\u7801\u516c\u5f00\u7684\u7c7b\u3002<\/p>\n<p>In an e-commerce app, for example, you might have a TaxCalculator that calculates the tax due on a particular product, taking into account the user\u2019s location in the world. Or you might have a ShippingCostService that calculates the cost of shipping to a user\u2019s location. A third service, OrderTotalCalculator, might use both of these services to work out the total price the user must pay for an order. Each service provides a small piece of independent functionality, but you can combine them to create a complete application. This design methodology scenario is known as the single- responsibility principle.<\/p>\n<p>\u4f8b\u5982\uff0c\u5728\u7535\u5b50\u5546\u52a1\u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u60a8\u53ef\u80fd\u6709\u4e00\u4e2a TaxCalculator\uff0c\u5b83\u8ba1\u7b97\u7279\u5b9a\u4ea7\u54c1\u7684\u5e94\u7f34\u7a0e\u6b3e\uff0c\u540c\u65f6\u8003\u8651\u7528\u6237\u5728\u4e16\u754c\u4e0a\u7684\u4f4d\u7f6e\u3002\u6216\u8005\uff0c\u60a8\u53ef\u80fd\u6709\u4e00\u4e2a ShippingCostService\uff0c\u7528\u4e8e\u8ba1\u7b97\u8fd0\u9001\u5230\u7528\u6237\u4f4d\u7f6e\u7684\u8d39\u7528\u3002\u7b2c\u4e09\u4e2a\u670d\u52a1 OrderTotalCalculator \u53ef\u80fd\u4f1a\u4f7f\u7528\u8fd9\u4e24\u4e2a\u670d\u52a1\u6765\u8ba1\u7b97\u7528\u6237\u5fc5\u987b\u4e3a\u8ba2\u5355\u652f\u4ed8\u7684\u603b\u4ef7\u3002\u6bcf\u4e2a\u670d\u52a1\u90fd\u63d0\u4f9b\u4e00\u5c0f\u90e8\u5206\u72ec\u7acb\u7684\u529f\u80fd\uff0c\u4f46\u60a8\u53ef\u4ee5\u5c06\u5b83\u4eec\u7ec4\u5408\u8d77\u6765\u521b\u5efa\u4e00\u4e2a\u5b8c\u6574\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u8fd9\u79cd\u8bbe\u8ba1\u65b9\u6cd5\u573a\u666f\u79f0\u4e3a\u5355\u4e00\u8d23\u4efb\u539f\u5219\u3002<\/p>\n<p><strong>DEFINITION<\/strong> The single-responsibility principle (SRP) states that every class should be responsible for only a single piece of functionality; it should need to change only if that required functionality changes. SRP is one of the \ufb01ve main design principles promoted by Robert C. Martin in Agile Software Development, Principles, Patterns, and Practices (Pearson, 2013).<br \/>\n<strong>\u5b9a\u4e49<\/strong> \u5355\u4e00\u8d23\u4efb\u539f\u5219 \uff08SRP\uff09 \u89c4\u5b9a\uff0c\u6bcf\u4e2a\u7c7b\u53ea\u5e94\u8d1f\u8d23\u4e00\u9879\u529f\u80fd;\u4ec5\u5f53\u6240\u9700\u7684\u529f\u80fd\u53d1\u751f\u53d8\u5316\u65f6\uff0c\u624d\u9700\u8981\u66f4\u6539\u3002SRP \u662f Robert C. Martin \u5728 Agile Software \u4e2d\u63a8\u5e7f\u7684\u4e94\u4e2a\u4e3b\u8981\u8bbe\u8ba1\u539f\u5219\u4e4b\u4e00\u53d1\u5c55\u3001\u539f\u5219\u3001\u6a21\u5f0f\u548c\u5b9e\u8df5\uff08\u76ae\u5c14\u900a\uff0c2013 \u5e74\uff09\u3002<\/p>\n<p>OrderTotalCalculator needs access to an instance of ShippingCostService and TaxCalculator. A naive approach to this problem is to use the new keyword and create an instance of a service whenever you need it. Unfortunately, this approach tightly couples your code to the speci\ufb01c implementation you\u2019re using and can undo all the good you achieved by modularizing the features in the \ufb01rst place. In some cases, it may break the SRP by making you perform initialization code in addition to using the service you created.<\/p>\n<p>OrderTotalCalculator \u9700\u8981\u8bbf\u95ee ShippingCostService \u548c TaxCalculator \u7684\u5b9e\u4f8b\u3002\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u7684\u4e00\u4e2a\u5929\u771f\u65b9\u6cd5\u662f\u4f7f\u7528 new \u5173\u952e\u5b57\uff0c\u5e76\u5728\u9700\u8981\u65f6\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u5b9e\u4f8b\u3002\u4e0d\u5e78\u7684\u662f\uff0c\u8fd9\u79cd\u65b9\u6cd5\u5c06\u60a8\u7684\u4ee3\u7801\u4e0e\u60a8\u6b63\u5728\u4f7f\u7528\u7684\u7279\u5b9a\u5b9e\u73b0\u7d27\u5bc6\u8026\u5408\uff0c\u5e76\u4e14\u53ef\u80fd\u4f1a\u62b5\u6d88\u60a8\u6700\u521d\u901a\u8fc7\u6a21\u5757\u5316\u529f\u80fd\u83b7\u5f97\u7684\u6240\u6709\u597d\u5904\u3002\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u9664\u4e86\u4f7f\u7528\u60a8\u521b\u5efa\u7684\u670d\u52a1\u4e4b\u5916\uff0c\u5b83\u8fd8\u4f1a\u8ba9\u60a8\u6267\u884c\u521d\u59cb\u5316\u4ee3\u7801\uff0c\u4ece\u800c\u7834\u574f SRP\u3002<\/p>\n<p>One solution to this problem is to make it somebody else\u2019s problem. When writing a service, you can declare your dependencies and let another class \ufb01ll those dependencies for you. Then your service can focus on the functionality for which it was designed instead of trying to work out how to build its dependencies.<\/p>\n<p>\u8fd9\u4e2a\u95ee\u9898\u7684\u4e00\u4e2a\u89e3\u51b3\u65b9\u6848\u662f\u8ba9\u5b83\u6210\u4e3a\u522b\u4eba\u7684\u95ee\u9898\u3002\u5728\u7f16\u5199\u670d\u52a1\u65f6\uff0c\u60a8\u53ef\u4ee5\u58f0\u660e\u60a8\u7684\u4f9d\u8d56\u9879\uff0c\u5e76\u8ba9\u53e6\u4e00\u4e2a\u7c7b\u4e3a\u60a8\u586b\u5145\u8fd9\u4e9b\u4f9d\u8d56\u9879\u3002\u7136\u540e\uff0c\u60a8\u7684\u670d\u52a1\u53ef\u4ee5\u4e13\u6ce8\u4e8e\u5b83\u6240\u8bbe\u8ba1\u7684\u529f\u80fd\uff0c\u800c\u4e0d\u662f\u5c1d\u8bd5\u5f04\u6e05\u695a\u5982\u4f55\u6784\u5efa\u5176\u4f9d\u8d56\u9879\u3002<\/p>\n<p>This technique is called dependency injection or the Inversion of Control (IoC) principle, a well-recognized design pattern that is used extensively. Typically, you\u2019ll register the dependencies of your application into a container, which you can use to create any service. You can use the container to create both your own custom application services and the framework services used by ASP.NET Core. You must register each service with the container before using it in your application.\u200c<\/p>\n<p>\u8fd9\u79cd\u6280\u672f\u79f0\u4e3a\u4f9d\u8d56\u5173\u7cfb\u6ce8\u5165\u6216\u63a7\u5236\u53cd\u8f6c \uff08IoC\uff09 \u539f\u5219\uff0c\u8fd9\u662f\u4e00\u79cd\u88ab\u5e7f\u6cdb\u4f7f\u7528\u4e14\u516c\u8ba4\u7684\u8bbe\u8ba1\u6a21\u5f0f\u3002\u901a\u5e38\uff0c\u60a8\u4f1a\u5c06\u5e94\u7528\u7a0b\u5e8f\u7684\u4f9d\u8d56\u9879\u6ce8\u518c\u5230\u5bb9\u5668\u4e2d\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u8be5\u5bb9\u5668\u521b\u5efa\u4efb\u4f55\u670d\u52a1\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528\u5bb9\u5668\u521b\u5efa\u81ea\u5df1\u7684\u81ea\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u670d\u52a1\u548c ASP.NET Core \u4f7f\u7528\u7684\u6846\u67b6\u670d\u52a1\u3002\u60a8\u5fc5\u987b\u5148\u5728\u5bb9\u5668\u4e2d\u6ce8\u518c\u6bcf\u4e2a\u670d\u52a1\uff0c\u7136\u540e\u624d\u80fd\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u4f7f\u7528\u5b83\u3002<\/p>\n<p><strong>NOTE<\/strong> I describe the dependency inversion principle and the IoC container used in ASP.NET Core in detail in chapters 8 and 9.<br \/>\n<strong>\u6ce8\u610f\uff1a<\/strong>\u6211\u5728\u7b2c 8 \u7ae0\u548c\u7b2c 9 \u7ae0\u4e2d\u8be6\u7ec6\u4ecb\u7ecd\u4e86 ASP.NET Core \u4e2d\u4f7f\u7528\u7684\u4f9d\u8d56\u53cd\u8f6c\u539f\u5219\u548c IoC \u5bb9\u5668\u3002<\/p>\n<p>In an ASP.NET Core application, this registration is performed by using the Services property of WebApplicationBuilder.<\/p>\n<p>\u5728 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e2d\uff0c\u6b64\u6ce8\u518c\u662f\u4f7f\u7528 WebApplicationBuilder \u7684 Services \u5c5e\u6027\u6267\u884c\u7684\u3002<\/p>\n<p>Whenever you use a new ASP.NET Core feature in your application, you need to come back to Program.cs and add the necessary services. This task isn\u2019t always as arduous as it sounds, typically requiring only a line or two of code to con\ufb01gure your applications.<\/p>\n<p>\u6bcf\u5f53\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u4f7f\u7528\u65b0\u7684 ASP.NET Core \u529f\u80fd\u65f6\uff0c\u90fd\u9700\u8981\u8fd4\u56de Program.cs \u5e76\u6dfb\u52a0\u5fc5\u8981\u7684\u670d\u52a1\u3002\u8fd9\u9879\u4efb\u52a1\u5e76\u4e0d\u603b\u662f\u50cf\u542c\u8d77\u6765\u90a3\u4e48\u8270\u5de8\uff0c\u901a\u5e38\u53ea\u9700\u8981\u4e00\u4e24\u884c\u4ee3\u7801\u6765\u914d\u7f6e\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>In listing 3.4 we con\ufb01gured an optional service for the HTTP logging middleware by using the line<br \/>\n\u5728\u6e05\u5355 3.4 \u4e2d\uff0c\u6211\u4eec\u4f7f\u7528<\/p>\n<pre><code>builder.Services.AddHttpLogging(opts =&gt;\n    opts.LoggingFields = HttpLoggingFields.RequestProperties);<\/code><\/pre>\n<p>Calling AddHttpLogging() adds the necessary services for the HTTP logging middleware to the IoC container and customizes the options used by the middleware for what to display.<\/p>\n<p>\u8c03\u7528 AddHttpLogging\uff08\uff09 \u4f1a\u5c06 HTTP \u65e5\u5fd7\u8bb0\u5f55\u4e2d\u95f4\u4ef6\u7684\u5fc5\u8981\u670d\u52a1\u6dfb\u52a0\u5230 IoC \u5bb9\u5668\u4e2d\uff0c\u5e76\u81ea\u5b9a\u4e49\u4e2d\u95f4\u4ef6\u7528\u4e8e\u663e\u793a\u5185\u5bb9\u7684\u9009\u9879\u3002<\/p>\n<p>AddHttpLogging isn\u2019t exposed directly on the Services property; it\u2019s an extension method that provides a convenient way to encapsulate all the code required to set up HTTP logging. This pattern of encapsulating setup behind extension methods is common in ASP.NET Core.<\/p>\n<p>AddHttpLogging \u4e0d\u4f1a\u76f4\u63a5\u5728\u670d\u52a1\u4e0a\u516c\u5f00\u8d22\u4ea7;\u5b83\u662f\u4e00\u79cd\u6269\u5c55\u65b9\u6cd5\uff0c\u63d0\u4f9b\u4e86\u4e00\u79cd\u4fbf\u6377\u7684\u65b9\u5f0f\u6765\u5c01\u88c5\u8bbe\u7f6e HTTP \u65e5\u5fd7\u8bb0\u5f55\u6240\u9700\u7684\u6240\u6709\u4ee3\u7801\u3002\u8fd9\u79cd\u5c06\u8bbe\u7f6e\u5c01\u88c5\u5728\u6269\u5c55\u65b9\u6cd5\u540e\u9762\u7684\u6a21\u5f0f\u5728 ASP.NET Core \u4e2d\u5f88\u5e38\u89c1\u3002<\/p>\n<p>As well as registering framework-related services, the Services property is where you\u2019d register any custom services you have in your application, such as the example TaxCalculator discussed previously. The Services property is an IServiceCollection, which is a list of every known service that your application will need to use. By adding a new service to it, you ensure that whenever a class declares a dependency on your service, the IoC container will know how to provide it.<\/p>\n<p>\u9664\u4e86\u6ce8\u518c\u4e0e\u6846\u67b6\u76f8\u5173\u7684\u670d\u52a1\u5916\uff0c\u60a8\u8fd8\u53ef\u4ee5\u5728 Services \u5c5e\u6027\u4e2d\u6ce8\u518c\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u4efb\u4f55\u81ea\u5b9a\u4e49\u670d\u52a1\uff0c\u4f8b\u5982\u524d\u9762\u8ba8\u8bba\u7684\u793a\u4f8b TaxCalculator\u3002Services \u5c5e\u6027\u662f\u4e00\u4e2a IServiceCollection\uff0c\u5b83\u662f\u5e94\u7528\u7a0b\u5e8f\u9700\u8981\u4f7f\u7528\u7684\u6bcf\u4e2a\u5df2\u77e5\u670d\u52a1\u7684\u5217\u8868\u3002\u901a\u8fc7\u5411\u5176\u6dfb\u52a0\u65b0\u670d\u52a1\uff0c\u60a8\u53ef\u4ee5\u786e\u4fdd\u6bcf\u5f53\u7c7b\u58f0\u660e\u5bf9\u60a8\u7684\u670d\u52a1\u7684\u4f9d\u8d56\u9879\u65f6\uff0cIoC \u5bb9\u5668\u5c06\u77e5\u9053\u5982\u4f55\u63d0\u4f9b\u5b83\u3002<\/p>\n<p>As well as con\ufb01guring services, WebApplicationBuilder is where you customize other cross-cutting concerns, such as logging. In listing 3.4, I showed how you can add a logging \ufb01lter to ensure that the logs generated by the HttpLoggingMiddleware are written to the console:<\/p>\n<p>\u9664\u4e86\u914d\u7f6e\u670d\u52a1\u4e4b\u5916\uff0cWebApplicationBuilder \u8fd8\u53ef\u4ee5\u81ea\u5b9a\u4e49\u5176\u4ed6\u6a2a\u5207\u5173\u6ce8\u70b9\uff0c\u4f8b\u5982\u65e5\u5fd7\u8bb0\u5f55\u3002\u5728\u5217\u8868 3.4 \u4e2d\uff0c\u6211\u5c55\u793a\u4e86\u5982\u4f55\u6dfb\u52a0\u65e5\u5fd7\u8fc7\u6ee4\u5668\u786e\u4fddHttpLoggingMiddleware \u5199\u5165\u63a7\u5236\u53f0\uff1a<\/p>\n<pre><code>builder.Logging.AddFilter(\n    &quot;Microsoft.AspNetCore.HttpLogging&quot;, LogLevel.Information);<\/code><\/pre>\n<p>This line ensures that logs of severity Information or greater created in the Microsoft .AspNetCore.HttpLogging namespace will be included in the log output.<\/p>\n<p>\u6b64\u884c\u53ef\u786e\u4fdd\u5728 Microsoft \u4e2d\u521b\u5efa\u4e25\u91cd\u6027 Information \u6216\u66f4\u9ad8\u7ea7\u522b\u7684\u65e5\u5fd7\u3002AspNetCore.HttpLogging \u547d\u540d\u7a7a\u95f4\u5c06\u5305\u542b\u5728\u65e5\u5fd7\u8f93\u51fa\u4e2d\u3002<\/p>\n<p><strong>NOTE<\/strong> I show con\ufb01guring log \ufb01lters in code here for convenience, but this isn\u2019t the idiomatic approach for con\ufb01guring \ufb01lters in ASP.NET Core. Typically, you control which levels are shown by adding values to appsettings.json instead, as shown in the source code accompanying this chapter. You\u2019ll learn more about logging and log \ufb01ltering in chapter 26.<br \/>\n<strong>\u6ce8\u610f<\/strong> \u4e3a\u65b9\u4fbf\u8d77\u89c1\uff0c\u6211\u5728\u6b64\u5904\u6f14\u793a\u4e86\u5728\u4ee3\u7801\u4e2d\u914d\u7f6e\u65e5\u5fd7\u7b5b\u9009\u5668\uff0c\u4f46\u8fd9\u4e0d\u662f\u5728 ASP.NET Core \u4e2d\u914d\u7f6e\u7b5b\u9009\u5668\u7684\u60ef\u7528\u65b9\u6cd5\u3002\u901a\u5e38\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7\u5411 Levels \u6dfb\u52a0\u503c\u6765\u63a7\u5236\u663e\u793a\u54ea\u4e9b\u7ea7\u522b appsettings.json \u5982\u672c\u7ae0\u968f\u9644\u7684\u6e90\u4ee3\u7801\u6240\u793a\u3002\u60a8\u5c06\u5728\u7b2c 26 \u7ae0\u4e2d\u4e86\u89e3\u6709\u5173\u65e5\u5fd7\u8bb0\u5f55\u548c\u65e5\u5fd7\u8fc7\u6ee4\u7684\u66f4\u591a\u4fe1\u606f\u3002<\/p>\n<p>After you call Build() on the WebApplicationBuilder instance, you can\u2019t register any more services or change your logging con\ufb01guration; the services de\ufb01ned for the WebApplication instance are set in stone. The next step is de\ufb01ning how your application responds to HTTP requests.\u200c<br \/>\n\u5728 WebApplicationBuilder \u5b9e\u4f8b\u4e0a\u8c03\u7528 Build\uff08\uff09 \u540e\uff0c\u60a8\u5c06\u65e0\u6cd5\u518d\u6ce8\u518c\u4efb\u4f55\u5176\u4ed6\u670d\u52a1\u6216\u66f4\u6539\u65e5\u5fd7\u8bb0\u5f55\u914d\u7f6e;\u4e3a WebApplication \u5b9e\u4f8b\u5b9a\u4e49\u7684\u670d\u52a1\u662f\u4e00\u6210\u4e0d\u53d8\u7684\u3002\u4e0b\u4e00\u6b65\u662f\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u54cd\u5e94 HTTP \u8bf7\u6c42\u3002\u200c<\/p>\n<p><strong><strong> 3.7.2 De\ufb01ning how requests are handled with middleware and endpoints\u200c<br \/>\n<\/strong><\/strong> 3.7.2 \u5b9a\u4e49\u5982\u4f55\u4f7f\u7528\u4e2d\u95f4\u4ef6\u548c\u7ec8\u7aef\u8282\u70b9\u5904\u7406\u8bf7\u6c42<\/p>\n<p>After registering your services with the IoC container on WebApplicationBuilder and doing any further customization, you create a WebApplication instance. You can do three main things with the WebApplication instance:<\/p>\n<p>\u5728 WebApplicationBuilder \u4e0a\u5411 IoC \u5bb9\u5668\u6ce8\u518c\u670d\u52a1\u5e76\u6267\u884c\u4efb\u4f55\u8fdb\u4e00\u6b65\u7684\u81ea\u5b9a\u4e49\u540e\uff0c\u60a8\u5c06\u521b\u5efa\u4e00\u4e2a WebApplication \u5b9e\u4f8b\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528 WebApplication \u5b9e\u4f8b\u6267\u884c\u4e09\u9879\u4e3b\u8981\u4f5c\uff1a<\/p>\n<ul>\n<li>\n<p>Add middleware to the pipeline.<br \/>\n\u5c06\u4e2d\u95f4\u4ef6\u6dfb\u52a0\u5230\u7ba1\u9053\u4e2d\u3002<\/p>\n<\/li>\n<li>\n<p>Map endpoints that generate a response for a request.<br \/>\n\u6620\u5c04\u4e3a\u8bf7\u6c42\u751f\u6210\u54cd\u5e94\u7684\u7ec8\u7aef\u8282\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>Run the application by calling Run().<br \/>\n\u901a\u8fc7\u8c03\u7528 Run\uff08\uff09 \u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<\/li>\n<\/ul>\n<p>As I described previously, middleware consists of small components that execute in sequence when the application receives an HTTP request. They can perform a host of functions, such as logging, identifying the current user for a request, serving static \ufb01les, and handling errors. Middleware is typically added to WebApplication by calling Use* extension methods. In listing 3.4, I showed an example of adding the HttpLoggingMiddleware to the middleware pipeline conditionally by calling UseHttpLogging():<\/p>\n<p>\u5982\u524d\u6240\u8ff0\uff0c\u4e2d\u95f4\u4ef6\u7531\u4e00\u4e9b\u5c0f\u7ec4\u4ef6\u7ec4\u6210\uff0c\u5f53\u5e94\u7528\u7a0b\u5e8f\u6536\u5230 HTTP \u8bf7\u6c42\u65f6\uff0c\u8fd9\u4e9b\u5c0f\u7ec4\u4ef6\u4f1a\u6309\u987a\u5e8f\u6267\u884c\u3002\u5b83\u4eec\u53ef\u4ee5\u6267\u884c\u8bb8\u591a\u529f\u80fd\uff0c\u4f8b\u5982\u65e5\u5fd7\u8bb0\u5f55\u3001\u8bc6\u522b\u8bf7\u6c42\u7684\u5f53\u524d\u7528\u6237\u3001\u63d0\u4f9b\u9759\u6001\u6587\u4ef6\u4ee5\u53ca\u5904\u7406\u9519\u8bef\u3002\u4e2d\u95f4\u4ef6\u901a\u5e38\u901a\u8fc7\u8c03\u7528 Use* \u6269\u5c55\u65b9\u6cd5\u6dfb\u52a0\u5230 WebApplication\u3002\u5728\u793a\u4f8b 3.4 \u4e2d\uff0c\u6211\u5c55\u793a\u4e86\u4e00\u4e2a\u901a\u8fc7\u8c03\u7528 UseHttpLogging\uff08\uff09 \u6709\u6761\u4ef6\u5730\u5c06 HttpLoggingMiddleware \u6dfb\u52a0\u5230\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u793a\u4f8b\uff1a<\/p>\n<pre><code>if (app.Environment.IsDevelopment())\n{\n    app.UseHttpLogging();\n}<\/code><\/pre>\n<p>We added only a single piece of middleware to the pipeline in this example, but when you\u2019re adding multiple pieces of middleware, the order of the Use* calls is important: the order in which they\u2019re added to the builder is the order in which they\u2019ll execute in the \ufb01nal pipeline. Middleware can use only objects created by previous middleware in the pipeline; it can\u2019t access objects created by later middleware.<\/p>\n<p>\u5728\u6b64\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u53ea\u5411\u7ba1\u9053\u6dfb\u52a0\u4e86\u4e00\u4e2a\u4e2d\u95f4\u4ef6\uff0c\u4f46\u662f\u5f53\u60a8\u6dfb\u52a0\u591a\u4e2a\u4e2d\u95f4\u4ef6\u65f6\uff0cUse* \u8c03\u7528\u7684\u987a\u5e8f\u5f88\u91cd\u8981\uff1a\u5b83\u4eec\u6dfb\u52a0\u5230\u6784\u5efa\u5668\u7684\u987a\u5e8f\u5c31\u662f\u5b83\u4eec\u5728\u6700\u7ec8\u7ba1\u9053\u4e2d\u7684\u6267\u884c\u987a\u5e8f\u3002\u4e2d\u95f4\u4ef6\u53ea\u80fd\u4f7f\u7528\u7ba1\u9053\u4e2d\u5148\u524d\u4e2d\u95f4\u4ef6\u521b\u5efa\u7684\u5bf9\u8c61;\u5b83\u65e0\u6cd5\u8bbf\u95ee\u7531\u66f4\u9ad8\u7248\u672c\u7684 middleware \u521b\u5efa\u7684\u5bf9\u8c61\u3002<\/p>\n<p><strong>WARNING<\/strong> It\u2019s important to consider the order of middleware when adding it to the pipeline, as middleware can use only objects created earlier in the pipeline.<br \/>\n<strong>\u8b66\u544a<\/strong> \u5c06\u4e2d\u95f4\u4ef6\u6dfb\u52a0\u5230\u7ba1\u9053\u65f6\uff0c\u8bf7\u52a1\u5fc5\u8003\u8651\u4e2d\u95f4\u4ef6\u7684\u987a\u5e8f\uff0c\u56e0\u4e3a\u4e2d\u95f4\u4ef6\u53ea\u80fd\u4f7f\u7528\u5728\u7ba1\u9053\u4e2d\u8f83\u65e9\u521b\u5efa\u7684\u5bf9\u8c61\u3002<\/p>\n<p>You should also note that listing 3.4 uses the WebApplication.Environment property (an instance of IWebHostEnvironment) to provide di\ufb00erent behavior when you\u2019re in a development environment. The HttpLoggingMiddleware is added to the pipeline only when you\u2019re running in development; when you\u2019re running in production (or, rather, when EnvironmentName is not set to &quot;Development&quot;), the HttpLoggingMiddleware will not be added.<\/p>\n<p>\u60a8\u8fd8\u5e94\u8be5\u6ce8\u610f\uff0c\u6e05\u5355 3.4 \u4f7f\u7528 WebApplication.Environment \u5c5e\u6027\uff08IWebHostEnvironment \u7684\u4e00\u4e2a\u5b9e\u4f8b\uff09\u5728\u5f00\u53d1\u73af\u5883\u4e2d\u63d0\u4f9b\u4e0d\u540c\u7684\u884c\u4e3a\u3002\u8fd9HttpLoggingMiddleware \u4ec5\u5728\u4f60\u5728\u5f00\u53d1\u4e2d\u8fd0\u884c\u65f6\u624d\u4f1a\u6dfb\u52a0\u5230\u7ba1\u9053\u4e2d;\u5f53\u60a8\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u8fd0\u884c\u65f6\uff08\u6216\u8005\u66f4\u786e\u5207\u5730\u8bf4\uff0c\u5f53 EnvironmentName \u672a\u8bbe\u7f6e\u4e3a \u201cDevelopment\u201d \u65f6\uff09\uff0c\u5c06\u4e0d\u4f1a\u6dfb\u52a0 HttpLoggingMiddleware\u3002<\/p>\n<p><strong>NOTE<\/strong>  You\u2019ll learn about hosting environments and how to change the current environment in chapter 10.<br \/>\n<strong>\u6ce8\u610f\uff1a<\/strong> \u60a8\u5c06\u5728\u7b2c 10 \u7ae0\u4e2d\u4e86\u89e3\u6258\u7ba1\u73af\u5883\u4ee5\u53ca\u5982\u4f55\u66f4\u6539\u5f53\u524d\u73af\u5883\u3002<\/p>\n<p>The WebApplicationBuilder builds an IWebHostEnvironment object and sets it on the Environment property. IWebHostEnvironment exposes several environment-related properties, such as\u200c<\/p>\n<p>WebApplicationBuilder \u6784\u5efa\u4e00\u4e2a IWebHostEnvironment \u5bf9\u8c61\uff0c\u5e76\u5728 Environment \u5c5e\u6027\u4e0a\u8bbe\u7f6e\u5b83\u3002IWebHostEnvironment \u516c\u5f00\u4e86\u51e0\u4e2a\u4e0e\u73af\u5883\u76f8\u5173\u7684\u5c5e\u6027\uff0c\u4f8b\u5982<\/p>\n<ul>\n<li>\n<p>ContentRootPath\u2014Location of the working directory for the app, typically the folder in which the application is running<br \/>\nContentRootPath - \u5e94\u7528\u7a0b\u5e8f\u5de5\u4f5c\u76ee\u5f55\u7684\u4f4d\u7f6e\uff0c\u901a\u5e38\u662f\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u5939<\/p>\n<\/li>\n<li>\n<p>WebRootPath\u2014Location of the wwwroot folder that contains static \ufb01les<br \/>\nWebRootPath \u2014 \u5305\u542b\u9759\u6001\u6587\u4ef6\u7684 wwwroot \u6587\u4ef6\u5939\u7684\u4f4d\u7f6e<\/p>\n<\/li>\n<li>\n<p>EnvironmentName\u2014Whether the current environment is a development or production environment<br \/>\nEnvironmentName - \u5f53\u524d\u73af\u5883\u662f\u5f00\u53d1\u73af\u5883\u8fd8\u662f\u751f\u4ea7\u73af\u5883<\/p>\n<\/li>\n<\/ul>\n<p>IWebHostEnvironment is already set by the time the WebApplication instance is created. EnvironmentName is typically set externally by using an environment variable when your application starts.<\/p>\n<p>IWebHostEnvironment \u5728\u521b\u5efa WebApplication \u5b9e\u4f8b\u65f6\u5df2\u8bbe\u7f6e\u3002 EnvironmentName \u901a\u5e38\u662f\u5728\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\u65f6\u4f7f\u7528\u73af\u5883\u53d8\u91cf\u5728\u5916\u90e8\u8bbe\u7f6e\u7684\u3002<\/p>\n<p>Listing 3.4 added only a single piece of middleware to the pipeline, but WebApplication automatically adds more middleware, including two of the most important and substantial pieces of middleware in the pipeline: the routing middleware and the endpoint middleware. The routing middleware is added automatically to the start of the pipeline, before any of the additional middleware added in Program.cs (so before the HttpLoggingMiddleware). The endpoint middleware is added to the end of the pipeline, after all the other middleware added in Program.cs.<\/p>\n<p>\u6e05\u5355 3.4 \u53ea\u5411\u7ba1\u9053\u6dfb\u52a0\u4e86\u4e00\u4e2a\u4e2d\u95f4\u4ef6\uff0c\u4f46 WebApplication \u81ea\u52a8\u6dfb\u52a0\u4e86\u66f4\u591a\u4e2d\u95f4\u4ef6\uff0c\u5305\u62ec\u7ba1\u9053\u4e2d\u4e24\u4e2a\u6700\u91cd\u8981\u548c\u6700\u91cd\u8981\u7684\u4e2d\u95f4\u4ef6\u90e8\u5206\uff1a\u8def\u7531\u4e2d\u95f4\u4ef6\u548c\u7aef\u70b9 \u4e2d\u95f4\u4ef6\u3002\u8def\u7531\u4e2d\u95f4\u4ef6\u4f1a\u81ea\u52a8\u6dfb\u52a0\u5230\u7ba1\u9053\u7684\u5f00\u5934\uff0c\u5728 Program.cs \u4e2d\u6dfb\u52a0\u7684\u4efb\u4f55\u5176\u4ed6\u4e2d\u95f4\u4ef6\u4e4b\u524d\uff08\u56e0\u6b64\u5728 HttpLoggingMiddleware \u4e4b\u524d\uff09\u3002\u7aef\u70b9\u4e2d\u95f4\u4ef6\u5c06\u6dfb\u52a0\u5230\u7ba1\u9053\u7684\u672b\u5c3e\uff0c\u5728 Program.cs \u4e2d\u6dfb\u52a0\u6240\u6709\u5176\u4ed6\u4e2d\u95f4\u4ef6\u4e4b\u540e\u3002<\/p>\n<p><strong>NOTE<\/strong> WebApplication adds several more pieces of middleware to the pipeline by default. It automatically adds error-handling middleware when you\u2019re running in the development environment, for example. I discuss some of this autoadded middleware in detail in chapter 4.<br \/>\n<strong>\u6ce8\u610f\uff1a<\/strong> \u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cWebApplication \u4f1a\u5411\u7ba1\u9053\u6dfb\u52a0\u66f4\u591a\u7684\u4e2d\u95f4\u4ef6\u3002\u4f8b\u5982\uff0c\u5f53\u60a8\u5728\u5f00\u53d1\u73af\u5883\u4e2d\u8fd0\u884c\u65f6\uff0c\u5b83\u4f1a\u81ea\u52a8\u6dfb\u52a0\u9519\u8bef\u5904\u7406\u4e2d\u95f4\u4ef6\u3002\u6211\u5728\u7b2c 4 \u7ae0\u4e2d\u8be6\u7ec6\u8ba8\u8bba\u4e86\u4e00\u4e9b\u81ea\u52a8\u6dfb\u52a0\u7684\u4e2d\u95f4\u4ef6\u3002<\/p>\n<p>Together, this pair of middleware is responsible for interpreting the request to determine which endpoint to invoke, for reading parameters from the request, and for generating the \ufb01nal response. For each request, the routing middleware uses the request\u2019s URL to determine which endpoint to invoke. Then the rest of the middleware pipeline executes until the request reaches the endpoint middleware, at which point the endpoint middleware executes the endpoint to generate the \ufb01nal response.<\/p>\n<p>\u8fd9\u5bf9\u4e2d\u95f4\u4ef6\u5171\u540c\u8d1f\u8d23\u89e3\u91ca\u8bf7\u6c42\u4ee5\u786e\u5b9a\u8981\u8c03\u7528\u7684\u7ec8\u7aef\u8282\u70b9\u3001\u4ece\u8bf7\u6c42\u4e2d\u8bfb\u53d6\u53c2\u6570\u4ee5\u53ca\u751f\u6210\u6700\u7ec8\u54cd\u5e94\u3002\u5bf9\u4e8e\u6bcf\u4e2a\u8bf7\u6c42\uff0c\u8def\u7531\u4e2d\u95f4\u4ef6\u4f7f\u7528\u8bf7\u6c42\u7684 URL \u6765\u786e\u5b9a\u8981\u8c03\u7528\u7684\u7ec8\u7aef\u8282\u70b9\u3002\u7136\u540e\uff0c\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u5176\u4f59\u90e8\u5206\u6267\u884c\uff0c\u76f4\u5230\u8bf7\u6c42\u5230\u8fbe\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\uff0c\u6b64\u65f6\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\u6267\u884c\u7ec8\u7aef\u8282\u70b9\u4ee5\u751f\u6210\u6700\u7ec8\u54cd\u5e94\u3002<\/p>\n<p>The routing and endpoint middleware work in tandem, using the set of endpoints de\ufb01ned for your application. In listing 3.4 we de\ufb01ned two endpoints:<\/p>\n<p>\u8def\u7531\u548c\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\u4f7f\u7528\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5b9a\u4e49\u7684\u7ec8\u7aef\u8282\u70b9\u96c6\u534f\u540c\u5de5\u4f5c\u3002\u5728\u6e05\u5355 3.4 \u4e2d\uff0c\u6211\u4eec\u5b9a\u4e49\u4e86\u4e24\u4e2a\u7aef\u70b9\uff1a<\/p>\n<pre><code>app.MapGet(&quot;\/&quot;, () =&gt; &quot;Hello World!&quot;);\napp.MapGet(&quot;\/person&quot;, () =&gt; new Person(&quot;Andrew&quot;, &quot;Lock&quot;));<\/code><\/pre>\n<p>You\u2019ve already seen the default &quot;Hello World!&quot; endpoint. When you send a GET request to \/, the routing middleware selects the &quot;Hello World!&quot; endpoint. The request continues down the middleware pipeline until it reaches the endpoint middleware, which executes the lambda and returns the string value in the response body.<\/p>\n<p>\u60a8\u5df2\u7ecf\u770b\u5230\u4e86\u9ed8\u8ba4\u7684 \u201cHello World\uff01\u201d \u7aef\u70b9\u3002\u5f53\u60a8\u5411 \/ \u53d1\u9001 GET \u8bf7\u6c42\u65f6\uff0c\u8def\u7531\u4e2d\u95f4\u4ef6\u4f1a\u9009\u62e9 \u201cHello World\uff01\u201d \u7aef\u70b9\u3002\u8bf7\u6c42\u7ee7\u7eed\u6cbf\u4e2d\u95f4\u4ef6\u7ba1\u9053\u5411\u4e0b\u79fb\u52a8\uff0c\u76f4\u5230\u5230\u8fbe\u7ec8\u7aef\u8282\u70b9middleware\uff0c\u5b83\u6267\u884c lambda \u5e76\u8fd4\u56de\u5b57\u7b26\u4e32\u503c\u3002<\/p>\n<p>The other endpoint de\ufb01nes a lambda to run for GET requests to the \/person path, but it returns a C# record instead of a string. When you return a C# object from a minimal API endpoint, the object is serialized to JSON automatically and returned in the response body, as you saw in \ufb01gure 3.8. In chapter 6 you\u2019ll learn how to customize this response, as well as return other types of responses.<\/p>\n<p>\u53e6\u4e00\u4e2a\u7ec8\u7aef\u8282\u70b9\u5b9a\u4e49\u4e00\u4e2a lambda\uff0c\u7528\u4e8e\u5bf9 \/person \u8def\u5f84\u7684 GET \u8bf7\u6c42\u8fd0\u884c\uff0c\u4f46\u5b83\u8fd4\u56de C# \u8bb0\u5f55\u800c\u4e0d\u662f\u5b57\u7b26\u4e32\u3002\u5f53\u60a8\u4ece\u6700\u5c0f API \u7aef\u70b9\u8fd4\u56de C# \u5bf9\u8c61\u65f6\uff0c\u8be5\u5bf9\u8c61\u4f1a\u81ea\u52a8\u5e8f\u5217\u5316\u4e3a JSON \u5e76\u5728\u54cd\u5e94\u6b63\u6587\u4e2d\u8fd4\u56de\uff0c\u5982\u56fe 3.8 \u6240\u793a\u3002\u5728\u7b2c 6 \u7ae0\u4e2d\uff0c\u60a8\u5c06\u5b66\u4e60\u5982\u4f55\u81ea\u5b9a\u4e49\u6b64\u54cd\u5e94\uff0c\u4ee5\u53ca\u8fd4\u56de\u5176\u4ed6\u7c7b\u578b\u7684\u54cd\u5e94\u3002<\/p>\n<p>And there you have it. You\u2019ve \ufb01nished the tour of your \ufb01rst ASP.NET Core application! Before we move on, let\u2019s take one last look at how our application handles a request. Figure 3.9 shows a request to the \/person path being handled by the sample application. You\u2019ve seen everything here already, so the process of handling a request should be familiar. The \ufb01gure shows how the request passes through the middleware pipeline before being handled by the endpoint middleware. The endpoint executes the lambda method and generates the JSON response, which passes back through the middleware to the ASP.NET Core web server before being sent to the user\u2019s browser.<\/p>\n<p>\u4f60\u6709\u5b83\u3002\u60a8\u5df2\u7ecf\u5b8c\u6210\u4e86\u7b2c\u4e00\u4e2a ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684\u6d4f\u89c8\uff01\u5728\u7ee7\u7eed\u4e4b\u524d\uff0c\u8ba9\u6211\u4eec\u6700\u540e\u770b\u4e00\u4e0b\u6211\u4eec\u7684\u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u5904\u7406\u8bf7\u6c42\u3002\u56fe 3.9 \u663e\u793a\u4e86\u5bf9\u793a\u4f8b\u5e94\u7528\u7a0b\u5e8f\u6b63\u5728\u5904\u7406\u7684 \/person \u8def\u5f84\u7684\u8bf7\u6c42\u3002\u60a8\u5df2\u7ecf\u5728\u8fd9\u91cc\u770b\u5230\u4e86\u6240\u6709\u5185\u5bb9\uff0c\u56e0\u6b64\u5904\u7406\u8bf7\u6c42\u7684\u8fc7\u7a0b\u5e94\u8be5\u5f88\u719f\u6089\u3002\u8be5\u56fe\u663e\u793a\u4e86\u8bf7\u6c42\u5728\u7531\u7ec8\u7aef\u8282\u70b9\u4e2d\u95f4\u4ef6\u5904\u7406\u4e4b\u524d\u5982\u4f55\u901a\u8fc7\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002\u7ec8\u7aef\u8282\u70b9\u6267\u884c lambda \u65b9\u6cd5\u5e76\u751f\u6210 JSON \u54cd\u5e94\uff0c\u8be5\u54cd\u5e94\u901a\u8fc7\u4e2d\u95f4\u4ef6\u4f20\u56de ASP.NET Core Web \u670d\u52a1\u5668\uff0c\u7136\u540e\u518d\u53d1\u9001\u5230\u7528\u6237\u7684\u6d4f\u89c8\u5668\u3002<\/p>\n<p><img decoding=\"async\" src=\"\/images\/aspnetcoreinaction\/0309.png\" alt=\"alt text\" \/><\/p>\n<p>Figure 3.9 An overview of a request to the \/person URL for the extended ASP.NET Core minimal API application. The routing middleware routes the request to the correct lambda method. The endpoint generates a JSON response by executing the method and passes the response back through the middleware pipeline to the browser.<br \/>\n\u56fe 3.9 \u5bf9\u6269\u5c55 ASP.NET Core \u6700\u5c0f API \u5e94\u7528\u7a0b\u5e8f\u7684 \/person URL \u7684\u8bf7\u6c42\u6982\u8ff0\u3002\u8def\u7531\u4e2d\u95f4\u4ef6\u5c06\u8bf7\u6c42\u8def\u7531\u5230\u6b63\u786e\u7684 lambda \u65b9\u6cd5\u3002\u7ec8\u7aef\u8282\u70b9\u901a\u8fc7\u6267\u884c\u8be5\u65b9\u6cd5\u751f\u6210 JSON \u54cd\u5e94\uff0c\u5e76\u901a\u8fc7\u4e2d\u95f4\u4ef6\u7ba1\u9053\u5c06\u54cd\u5e94\u4f20\u9012\u56de\u6d4f\u89c8\u5668\u3002<\/p>\n<p>The trip has been pretty intense, but now you have a good overview of how an entire application is con\ufb01gured and how it handles a request by using minimal APIs. In chapter 4, you\u2019ll take a closer look at the middleware pipeline that exists in all ASP.NET Core applications. You\u2019ll learn how it\u2019s composed, how you can use it to add functionality to your application, and how you can use it to create simple HTTP services.<\/p>\n<p>\u8fd9\u6b21\u65c5\u884c\u975e\u5e38\u7d27\u5f20\uff0c\u4f46\u73b0\u5728\u60a8\u5df2\u7ecf\u5f88\u597d\u5730\u4e86\u89e3\u4e86\u6574\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684\u914d\u7f6e\u65b9\u5f0f\u4ee5\u53ca\u5b83\u5982\u4f55\u4f7f\u7528\u6700\u5c11\u7684 API \u5904\u7406\u8bf7\u6c42\u3002\u5728\u7b2c 4 \u7ae0\u4e2d\uff0c\u60a8\u5c06\u4ed4\u7ec6\u7814\u7a76\u6240\u6709 ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u4e2d\u5b58\u5728\u7684\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3002\u60a8\u5c06\u4e86\u89e3\u5b83\u662f\u5982\u4f55\u7f16\u5199\u7684\uff0c\u5982\u4f55\u4f7f\u7528\u5b83\u6765\u5411\u5e94\u7528\u7a0b\u5e8f\u6dfb\u52a0\u529f\u80fd\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528\u5b83\u6765\u521b\u5efa\u7b80\u5355\u7684 HTTP \u670d\u52a1\u3002<\/p>\n<h2>Summary<\/h2>\n<h2>\u603b\u7ed3<\/h2>\n<p>The .csproj \ufb01le contains the details of how to build your project, including which NuGet packages it depends on. Visual Studio and the .NET CLI use this \ufb01le to build your application.<br \/>\n.csproj \u6587\u4ef6\u5305\u542b\u6709\u5173\u5982\u4f55\u751f\u6210\u9879\u76ee\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5305\u62ec\u5b83\u6240\u4f9d\u8d56\u7684 NuGet \u5305\u3002Visual Studio \u548c .NET CLI \u4f7f\u7528\u6b64\u6587\u4ef6\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>Restoring the NuGet packages for an ASP.NET Core application downloads all your project\u2019s dependencies so that it can be built and run.<br \/>\n\u8fd8\u539f ASP.NET Core \u5e94\u7528\u7a0b\u5e8f\u7684 NuGet \u5305\u4f1a\u4e0b\u8f7d\u9879\u76ee\u7684\u6240\u6709\u4f9d\u8d56\u9879\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u751f\u6210\u548c\u8fd0\u884c\u5b83\u3002<\/p>\n<p>Program.cs is where you de\ufb01ne the code that runs when your app starts. You can create a WebApplicationBuilder by using WebApplication.CreateBuilder() and call methods on the builder to create your application.<br \/>\nProgram.cs \u662f\u60a8\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u542f\u52a8\u65f6\u8fd0\u884c\u7684\u4ee3\u7801\u7684\u4f4d\u7f6e\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528 WebApplication.CreateBuilder\uff08\uff09 \u521b\u5efa WebApplicationBuilder\uff0c\u5e76\u5728\u751f\u6210\u5668\u4e0a\u8c03\u7528\u65b9\u6cd5\u6765\u521b\u5efa\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>All services, both framework and custom application services, must be registered with the WebApplicationBuilder by means of the Services property, to be accessed later in your application.<br \/>\n\u6240\u6709\u670d\u52a1\uff08\u5305\u62ec\u6846\u67b6\u670d\u52a1\u548c\u81ea\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u670d\u52a1\uff09\u90fd\u5fc5\u987b\u901a\u8fc7 Services \u5c5e\u6027\u5411 WebApplicationBuilder \u6ce8\u518c\uff0c\u4ee5\u4fbf\u7a0d\u540e\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8bbf\u95ee\u3002<\/p>\n<p>After your services are con\ufb01gured you call Build() on the WebApplicationBuilder instance to create a WebApplication instance. You use WebApplication to con\ufb01gure your app\u2019s middleware pipeline, to register the endpoints, and to start the server listening for requests.<br \/>\n\u914d\u7f6e\u670d\u52a1\u540e\uff0c\u5728 WebApplicationBuilder \u5b9e\u4f8b\u4e0a\u8c03\u7528 Build\uff08\uff09 \u4ee5\u521b\u5efa WebApplication \u5b9e\u4f8b\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528 WebApplication \u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u7684\u4e2d\u95f4\u4ef6\u7ba1\u9053\u3001\u6ce8\u518c\u7ec8\u7aef\u8282\u70b9\u4ee5\u53ca\u542f\u52a8\u670d\u52a1\u5668\u4fa6\u542c\u8bf7\u6c42\u3002<\/p>\n<p>Middleware de\ufb01nes how your application responds to requests. The order in which middleware is registered de\ufb01nes the \ufb01nal order of the middleware pipeline for the application.<br \/>\n\u4e2d\u95f4\u4ef6\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u5982\u4f55\u54cd\u5e94\u8bf7\u6c42\u3002\u4e2d\u95f4\u4ef6\u7684\u6ce8\u518c\u987a\u5e8f\u5b9a\u4e49\u4e86\u5e94\u7528\u7a0b\u5e8f\u7684\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u6700\u7ec8\u987a\u5e8f\u3002<\/p>\n<p>The WebApplication instance automatically adds RoutingMiddleware to the start of the middleware pipeline and EndpointMiddleware as the last middleware in the pipeline.<br \/>\nWebApplication \u5b9e\u4f8b\u81ea\u52a8\u5c06 RoutingMiddleware \u6dfb\u52a0\u5230\u4e2d\u95f4\u4ef6\u7ba1\u9053\u7684\u5f00\u5934\uff0c\u5e76\u5c06 EndpointMiddleware \u4f5c\u4e3a\u7ba1\u9053\u4e2d\u7684\u6700\u540e\u4e00\u4e2a\u4e2d\u95f4\u4ef6\u3002<\/p>\n<p>Endpoints de\ufb01ne how a response should be generated for a given request and are typically tied to a request\u2019s path. With minimal APIs, a simple function is used to generate a response.<br \/>\n\u7ec8\u7aef\u8282\u70b9\u5b9a\u4e49\u5e94\u5982\u4f55\u4e3a\u7ed9\u5b9a\u8bf7\u6c42\u751f\u6210\u54cd\u5e94\uff0c\u5e76\u4e14\u901a\u5e38\u4e0e\u8bf7\u6c42\u7684\u8def\u5f84\u76f8\u5173\u8054\u3002\u4f7f\u7528\u6700\u5c11\u7684 API\uff0c\u4f7f\u7528\u4e00\u4e2a\u7b80\u5355\u7684\u51fd\u6570\u6765\u751f\u6210\u54cd\u5e94\u3002<\/p>\n<p>You can start the web server and begin accepting HTTP requests by calling Run on the WebApplication instance.<br \/>\n\u60a8\u53ef\u4ee5\u901a\u8fc7\u5728 WebApplication \u5b9e\u4f8b\u4e0a\u8c03\u7528 Run \u6765\u542f\u52a8 Web \u670d\u52a1\u5668\u5e76\u5f00\u59cb\u63a5\u53d7 HTTP \u8bf7\u6c42\u3002<\/p>\n<hr \/>\n<ol>\n<li>\n<p>If you want to learn more about Kestrel, IIS HTTP Server, and HTTP.sys, this documentation describes the di\ufb00erences among them: <a href=\"http:\/\/mng.bz\/6DgD\">http:\/\/mng.bz\/6DgD<\/a>.<br \/>\n\u5982\u679c\u60a8\u60f3\u4e86\u89e3\u6709\u5173 Kestrel\u3001IIS HTTP Server \u548c HTTP.sys \u7684\u66f4\u591a\u4fe1\u606f\uff0c\u672c\u6587\u6863\u4ecb\u7ecd\u4e86\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\uff1a<a href=\"http:\/\/mng.bz\/6DgD\">http:\/\/mng.bz\/6DgD<\/a>\u3002<\/p>\n<\/li>\n<li>\n<p>You can install the development certi\ufb01cate in Windows and macOS. For instructions on trusting the certi\ufb01cate on Linux, see your distribution\u2019s instructions. Not all browsers (Mozilla Firefox, for example) use the certi\ufb01cate store, so follow your browser\u2019s guidelines for trusting the certi\ufb01cate. If you still have di\ufb03culties, see the troubleshooting tips at <a href=\"http:\/\/mng.bz\/o1pr\">http:\/\/mng.bz\/o1pr<\/a>.<br \/>\n\u60a8\u53ef\u4ee5\u5728 Windows \u548c macOS \u4e2d\u5b89\u88c5\u5f00\u53d1\u8bc1\u4e66\u3002\u6709\u5173\u5728 Linux \u4e0a\u4fe1\u4efb\u8bc1\u4e66\u7684\u8bf4\u660e\uff0c\u8bf7\u53c2\u9605\u60a8\u7684\u5206\u914d\u7684\u8bf4\u660e\u3002\u5e76\u975e\u6240\u6709\u6d4f\u89c8\u5668\uff08\u4f8b\u5982 Mozilla Firefox\uff09\u90fd\u4f7f\u7528\u8bc1\u4e66\u5b58\u50a8\uff0c\u56e0\u6b64\u8bf7\u9075\u5faa\u6d4f\u89c8\u5668\u7684\u4fe1\u4efb\u8bc1\u4e66\u6307\u5357\u3002\u5982\u679c\u60a8\u4ecd\u9047\u5230\u56f0\u96be\uff0c\u8bf7\u53c2\u9605 <a href=\"http:\/\/mng.bz\/o1pr\">http:\/\/mng.bz\/o1pr<\/a> \u4e2d\u7684\u6545\u969c\u6392\u9664\u63d0\u793a\u3002<\/p>\n<\/li>\n<li>\n<p>You can read about the new C# features included in .NET 7 and C# 11 at <a href=\"http:\/\/mng.bz\/nWMg\">http:\/\/mng.bz\/nWMg<\/a>.<br \/>\n\u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/nWMg\">http:\/\/mng.bz\/nWMg<\/a> \u4e0a\u9605\u8bfb .NET 7 \u548c C# 11 \u4e2d\u5305\u542b\u7684\u65b0 C# \u529f\u80fd\u3002<\/p>\n<\/li>\n<li>\n<p>You can read in more detail about HTTP logging in the documentation at <a href=\"http:\/\/mng.bz\/QPmw\">http:\/\/mng.bz\/QPmw<\/a>.<br \/>\n\u60a8\u53ef\u4ee5\u5728 <a href=\"http:\/\/mng.bz\/QPmw\">http:\/\/mng.bz\/QPmw<\/a> \u4e0a\u7684\u6587\u6863\u4e2d\u9605\u8bfb\u6709\u5173 HTTP \u65e5\u5fd7\u8bb0\u5f55\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\u3002<\/p>\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>ASP.NET Core in Action 3 Your first application 3 Your first application 3 \u60a8\u7684\u7b2c\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f This chapter covers \u672c\u7ae0\u6db5\u76d6 Creating your first ASP.NET Core web application Running your application \u521b\u5efa\u60a8\u7684\u7b2c\u4e00\u4e2a ASP.NET Core Web \u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f *Understanding the components of your application \u4e86\u89e3\u5e94\u7528\u7a0b\u5e8f\u7684\u7ec4\u4ef6 In the previous chapters, I gave you an overview of how ASP.NET Core applications work [&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":[19],"class_list":["post-572","post","type-post","status-publish","format-standard","hentry","category-csharp","tag-asp-net-core-in-action"],"_links":{"self":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/572","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=572"}],"version-history":[{"count":0,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/572\/revisions"}],"wp:attachment":[{"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}