diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b7cd34..3fa19bc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,19 @@ +# 参与方式 + +重要的先说:这本 简明 ASP.NET Core 手册 基于 [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/)([创作共用署名4.0](https://creativecommons.org/licenses/by/4.0/deed.zh))许可证,这意味着,欢迎你按自己的意愿复制、分发、克隆、重排本书中的资料。我仅有的要求就是,你要指出原作者(Nate Barbettini)。当然,中文版请别忘了译者:windsting 和 yuyi。 + +## 发现错误? + +如果你看到错别字或者有问题的代码,欢迎修正它。我们乐于接受 pull request。 + +如果你不熟悉 Git 或者用不惯它,也没关系。可以在 [登记问题](https://github.com/windsting/little-aspnetcore-book/issues) 页面指出这个错误。请写得尽量详细一些。 + +## 欢迎建议 + +如果你有什么建议,欢迎提交一个 [议题](https://github.com/windsting/little-aspnetcore-book/issues) 或者发邮件到 nate@barbettini.com 给我。我不一定回复所有来信,但我会尽量都读一下。 + +--- + # How to contribute First things first: the Little ASP.NET Core Book is licensed under the [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/) license, which means you are welcome to copy, redistribute, fork, or remix the material in the book as much as you want. All I ask is that you give credit to the original author (Nate Barbettini). diff --git a/README.md b/README.md index ff627e0..11d179d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,104 @@ +# 简明 ASP.NET Core 手册 + +*Nate Barbettini 著* + +*windsting 、 yuyi 译* + +Copyright © 2018. All rights reserved. + +以 创作共用署名4.0国际许可证 发布。您可以自由地:共享 — 在任何媒介以任何形式复制、发行本作品,演绎 — 修改、转换或以本作品为基础进行创作,在任何用途下,甚至商业目的。您必须给出适当的署名,提供指向本许可协议的链接。 + +详情请访问:https://creativecommons.org/licenses/by/4.0/deed.zh + +- If you like this project, please consider + + + +## 前言 + +感谢你选择这本 简明 ASP.NET Core 手册!我写这本小书的目的,是帮助 web 编程开发者以及爱好者了解 ASP.NET Core 2.0,一个用于创建 Web应用 和 API 的框架。 + +这本 简明 ASP.NET Core 手册 的内容组织成了一篇教程。你将从头开始,完整地构建一个应用程序,同时了解以下内容: + +* MVC (Model-View-Controller) 模式的基本内容 +* 前端代码(HTML、CSS、JavaScript)怎样与后端代码交互 +* 什么是依赖注入以及它的实用之处 +* 如何进行数据库的读写操作 +* 如何添加 登录、注册功能,以及如何提升安全性 +* 如何部署该应用程序到网络上 + +别担心,就算对 ASP.NET Core (及以上列表的内容)一无所知,也不妨碍你学下去。 + +## 开始之前 + +你将要构建的这个应用,其完整源码位于 GitHub: + +https://www.github.com/nbarbettini/little-aspnetcore-todo + +如果需要与你自己的代码做对比,可任意下载。 + +这本书本身也会由于修订和内容的增加而频繁更新。如果你阅读的是 PDF、电子书,或者打印版,请查阅官网([littleasp.net/book](http://www.littleasp.net/book),中文版为 [windsting.github.io/little-aspnetcore-book/book/](https://windsting.github.io/little-aspnetcore-book/book/))的版本更新。有关版本信息和更新内容,请查阅本书的最后一页。 + +### 选择你的语言阅读 + +感谢那些多语言的投稿者,简明 ASP.NET Core 手册 已经被翻译成其它语言: + +* [**The Little ASP.NET Core Book**](https://www.recaffeinate.co/book/) (English -- original version) + +* [**ASP.NET Core El Kitabı**](https://sahinyanlik.gitbooks.io/kisa-asp-net-core-kitabi/) (Turkish) + +## 本书的目标读者 + +如果你刚开始编程,本书将在“构建最新web应用”方面,使你了解其中的模式和概念。你将以从无到有、循序渐进的方式,学习构建一个 web 应用的方法(以及合理组织各模块的方法)。对于你在编程方面所需的内容,本书不能事无巨细的涵盖,但它可以作为一个起点,引导你了解更高级的内容。 + +如果你已经在使用诸如 Node、Python、Ruby、Go 或者 Java 之类的后端语言写程序,你会注意到很多熟悉的概念,比如 MVC、视图模板和依赖注入。你将使用 C# 进行编程,但跟你熟知的内容相去不远。 + +如果你是一个 ASP.NET MVC 开发者,将如鱼得水。 ASP.NET Core 增添了一些新工具,并复用(及简化)了你用过的那些东西。我将在后续章节指出部分差异。 + +不论你此前在 web 编程方面经验如何,本书都会倾囊相授,足够你借助 ASP.NET Core 创建一个简单但实用的 web 应用。你将学习如何通过前后端代码实现设计目标,如何与数据库交互,如何部署应用到真实环境。 + +## 什么是 ASP.NET Core? + +ASP.NET Core 是一个由微软创建的,用于构建 web 应用、API、微服务 的 web 框架。它使用常见的模式,诸如 MVC(Model-View-Controller)、依赖注入,和一个由中间件构成的请求处理管线。它基于 Apache 2.0 许可证开放源码,就是说,源代码可以自由获取,并且欢迎社区成员以 缺陷修复 和 新功能提交 的方式进行贡献。 + +ASP.NET Core 运行在微软的 .NET 运行时库上,类似于 Java 的 虚拟机(JVM)或者 Ruby 的解释器。有几种语言(C#,Visual Basic,F#)可以用来编写 ASP.NET Core 程序。C# 是最常见的选择,我在本书中也会采用它。你可以在 Windows、Mac,和 Linux 上构建并运行 ASP.NET Core 应用。 + +## 又一个 web 框架,需求何在? + +现存的 web 框架选项已经很多了:Node/Express、Spring、Ruby on Rails、Django、Laravel 等等,数不胜数。ASP.NET Core 又有什么可取之处呢? + +* **速度** ASP.NET Core 很快。因为 .NET Core 是编译运行的,执行速度远高于解释执行的语言,比如 JavaScript 或者 Ruby。ASP.NET Core 也为多线程和异步任务作了专门的优化。与使用 Node.js 写的代码相比,执行速度高出 5-10 倍是很正常的。 + +* **生态** ASP.NET Core 可能初出茅庐,但 .NET 却已久经考验。在 NuGet(.NET 的包管理系统,类似 npm、Ruby gems,或者 Maven)上有成千上万的软件包。有现成的包可用来完成 JSON 反序列化、数据库连接、PDF生成,或者几乎你能想到的任何需求。 + +* **安全性** 微软的开发团队很注重安全性,ASP.NET Core 从构建伊始就注重安全。它已经自动处理了净化输入数据和跨域伪造请求(CSRF),你就不需要操心这些了。你同时还享有 .NET 编译器的静态类型检测的优势,它像个时刻警惕着,还有些强迫症的审校者。这样,在使用一个变量或者某些数据时,那些无意识的错误就插翅难逃了。 + +## .NET Core 和 .NET 标准 + +贯穿本书,你将学习有关 ASP.NET Core (web 框架)的知识。我会偶尔提及 .NET 运行时,这个用于运行 .NET 代码的支持库。如果你看着这段已经像天书那么晦涩,直接跳到下一章吧。 + +你可能还会听说 .NET Core 和 .NET标准,这些命名有些混乱,所以在此做一简短的释疑: + +**.NET 标准** 是一个平台无关的接口,它定义了特性和 API。值得指出的是,.NET 标准并不等同于任何实际的代码或者功能,仅仅是 API 的定义。.NET 标准现存多个不同的“版本”或者说级别,反映出提供 API 的数量(或者说 API 所覆盖的广度)。比如 .NET标准2.0 的 API 数量,比 .NET标准1.5 多,后者的 API 又比 .NET标准1.0 多。 + +**.NET Core** 是可在 Windows、Mac或者Linux上安装的 .NET 运行时库。它在各个操作系统上,使用对应的平台相关代码,实现了定义于 .NET 标准中的 API。这是你将要安装到机器上,用来构建和运行 ASP.NET Core 应用程序的部分。 + +作为对比,这里要指出, **.NET Framework** 是另一个 .NET标准 的实现,它只能运行在 Windows 上。在 .NET Core 出现并把 .NET 推向 Mac 和 Linux 之前,它是唯一的 .NET 运行时库。 ASP.NET Core 也可以跑在 Windows 专用的 .NET Framework 上,但我不会过多涉及这个主题。 + +如果你已经被这些命名搞糊涂了,别发愁!咱们马上就要写代码进行实践了。 + +## ASP.NET 4 开发者注意 + +如果你从没用过 ASP.NET 以前的版本,直接看下一章去吧! + +ASP.NET Core 是对 ASP.NET 彻底的重写,重点关注于:让该框架应用新的开发方法,并最终使其与 System.Web、IIS、和 Windows 解耦。你要是还记得 ASP.NET 4 的 OWIN/Katana 那些内容,你就已经学会一半了: Katana 项目成了 ASP.NET 5,而后者的名字最终被改成了 ASP.NET Core。 + +作为 Katana 的传承, `Startup` 类成了起始和中心,`Application_Start` 和 `Global.asax` 则不复存在了。整个处理管线由中间件驱动,MVC 和 Web API 不再有区别:控制器可以方便的返回视图、状态码,或者数据。依赖注入功能已经内置了,所以,如果你不想费劲的话,完全可以不用再安装并配置一个服务容器了,比如 StructureMap 或者 Ninject。整个框架已经针对速度和运行时效率进行了优化。 + +好了,前言就到这儿。开始学习 ASP.NET Core 吧。 + +--- + # The Little ASP.NET Core Book *by Nate Barbettini* diff --git a/SUMMARY.md b/SUMMARY.md index 1ba33ff..90bb32e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,35 +1,35 @@ # Summary -* [Your first application](chapters/your-first-application/README.md) - * [Get the SDK](chapters/your-first-application/get-the-sdk.md) - * [Hello World in C#](chapters/your-first-application/hello-world-in-csharp.md) - * [Create an ASP.NET Core project](chapters/your-first-application/create-aspnetcore-project.md) -* [MVC basics](chapters/mvc-basics/README.md) - * [Create a controller](chapters/mvc-basics/create-controller.md) - * [Create models](chapters/mvc-basics/create-models.md) - * [Create a view](chapters/mvc-basics/create-view.md) - * [Add a service class](chapters/mvc-basics/add-service-class.md) - * [Use dependency injection](chapters/mvc-basics/use-dependency-injection.md) - * [Finish the controller](chapters/mvc-basics/finish-controller.md) - * [Update the layout](chapters/mvc-basics/update-the-layout.md) -* [Add external packages](chapters/add-external-packages/README.md) -* [Use a database](chapters/use-a-database/README.md) - * [Connect to a database](chapters/use-a-database/connect-to-a-database.md) - * [Update the context](chapters/use-a-database/update-context.md) - * [Create a migration](chapters/use-a-database/create-migration.md) - * [Create a new service class](chapters/use-a-database/create-service-class.md) -* [Add more features](chapters/add-more-features/README.md) - * [Add new to-do items](chapters/add-more-features/add-todo-items.md) - * [Complete items with a checkbox](chapters/add-more-features/complete-with-checkbox.md) -* [Security and identity](chapters/security-and-identity/README.md) - * [Require authentication](chapters/security-and-identity/require-authentication.md) - * [Using identity in the application](chapters/security-and-identity/using-identity-in-the-application.md) - * [Authorization with roles](chapters/security-and-identity/authorization-with-roles.md) - * [More resources](chapters/security-and-identity/more-resources.md) -* [Automated testing](chapters/automated-testing/README.md) - * [Unit testing](chapters/automated-testing/unit-testing.md) - * [Integration testing](chapters/automated-testing/integration-testing.md) -* [Deploy the application](chapters/deploy-the-application/README.md) - * [Deploy to Azure](chapters/deploy-the-application/deploy-to-azure.md) - * [Deploy with Docker](chapters/deploy-the-application/deploy-with-docker.md) -* [Conclusion](chapters/conclusion/README.md) +* [你的第一个程序](chapters/your-first-application/README.md) + * [获取 SDK](chapters/your-first-application/get-the-sdk.md) + * [C# 版的 Hello World](chapters/your-first-application/hello-world-in-csharp.md) + * [创建一个 ASP.NET Core 项目](chapters/your-first-application/create-aspnetcore-project.md) +* [MVC 基础](chapters/mvc-basics/README.md) + * [创建控制器](chapters/mvc-basics/create-controller.md) + * [创建模型](chapters/mvc-basics/create-models.md) + * [创建视图](chapters/mvc-basics/create-view.md) + * [添加一个服务类](chapters/mvc-basics/add-service-class.md) + * [运用依赖注入](chapters/mvc-basics/use-dependency-injection.md) + * [完成控制器](chapters/mvc-basics/finish-controller.md) + * [修改布局](chapters/mvc-basics/update-the-layout.md) +* [添加外来软件包](chapters/add-external-packages/README.md) +* [运用数据库](chapters/use-a-database/README.md) + * [连接数据库](chapters/use-a-database/connect-to-a-database.md) + * [修改数据库上下文](chapters/use-a-database/update-context.md) + * [创建变更](chapters/use-a-database/create-migration.md) + * [创建服务类](chapters/use-a-database/create-service-class.md) +* [添加新特性](chapters/add-more-features/README.md) + * [添加 待办事项 条目](chapters/add-more-features/add-todo-items.md) + * [使用复选框标记条目完成](chapters/add-more-features/complete-with-checkbox.md) +* [安全和身份](chapters/security-and-identity/README.md) + * [提示认证](chapters/security-and-identity/require-authentication.md) + * [在程序中使用身份](chapters/security-and-identity/using-identity-in-the-application.md) + * [按角色进行授权](chapters/security-and-identity/authorization-with-roles.md) + * [附加资源](chapters/security-and-identity/more-resources.md) +* [自动化测试](chapters/automated-testing/README.md) + * [单元测试](chapters/automated-testing/unit-testing.md) + * [集成测试](chapters/automated-testing/integration-testing.md) +* [部署程序](chapters/deploy-the-application/README.md) + * [部署到 Azure](chapters/deploy-the-application/deploy-to-azure.md) + * [使用 Docker 进行部署](chapters/deploy-the-application/deploy-with-docker.md) +* [结束语](chapters/conclusion/README.md) diff --git a/book.json b/book.json index 697bca3..d8951e2 100644 --- a/book.json +++ b/book.json @@ -1,17 +1,21 @@ { - "title": "The Little ASP.NET Core Book", - "description": "A friendly introduction to building web applications with the ASP.NET Core framework.", + "title": "简明 ASP.NET Core 手册", + "description": "一个关于“使用 ASP.NET Core 框架的构建 web 应用程序”的入门简介。", "author": "Nate Barbettini", - "isbn": "978-1-387-75615-5", + "language": "zh-hans", "pdf": { + "fontSize": 13, "paperSize": "a5", - "fontFamily": "Lato" + "fontFamily": "Microsoft YaHei" }, - "plugins": ["expandable-chapters-small", "anchors", "forkmegithub"], + "plugins": ["expandable-chapters-small", "disqus", "splitter", "anchors", "copy-code-button", "forkmegithub"], "pluginsConfig": { + "disqus": { + "shortName": "little-aspnetcore-book-cn" + }, "forkmegithub": { - "color": "green", - "url": "https://github.com/nbarbettini/little-aspnetcore-book" + "color": "orange", + "url": "https://github.com/windsting/little-aspnetcore-book" } } -} +} \ No newline at end of file diff --git a/book/CONTRIBUTING.md b/book/CONTRIBUTING.md new file mode 100644 index 0000000..3fa19bc --- /dev/null +++ b/book/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# 参与方式 + +重要的先说:这本 简明 ASP.NET Core 手册 基于 [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/)([创作共用署名4.0](https://creativecommons.org/licenses/by/4.0/deed.zh))许可证,这意味着,欢迎你按自己的意愿复制、分发、克隆、重排本书中的资料。我仅有的要求就是,你要指出原作者(Nate Barbettini)。当然,中文版请别忘了译者:windsting 和 yuyi。 + +## 发现错误? + +如果你看到错别字或者有问题的代码,欢迎修正它。我们乐于接受 pull request。 + +如果你不熟悉 Git 或者用不惯它,也没关系。可以在 [登记问题](https://github.com/windsting/little-aspnetcore-book/issues) 页面指出这个错误。请写得尽量详细一些。 + +## 欢迎建议 + +如果你有什么建议,欢迎提交一个 [议题](https://github.com/windsting/little-aspnetcore-book/issues) 或者发邮件到 nate@barbettini.com 给我。我不一定回复所有来信,但我会尽量都读一下。 + +--- + +# How to contribute + +First things first: the Little ASP.NET Core Book is licensed under the [Creative Commons Attribution](https://creativecommons.org/licenses/by/4.0/) license, which means you are welcome to copy, redistribute, fork, or remix the material in the book as much as you want. All I ask is that you give credit to the original author (Nate Barbettini). + +## Notice a problem? + +If you see a typo or a code error, feel free to fix it. Pull requests are gladly accepted! + +If you're not familiar or comfortable with Git, that's fine. [File an issue](https://github.com/nbarbettini/little-aspnetcore-book/issues) to point out the error. Please be as detailed as possible. + +## Suggestions are welcome + +If you have a suggestion, feel free to file an [issue](https://github.com/nbarbettini/little-aspnetcore-book/issues) or email me at nate@barbettini.com. I can't promise I will be able to respond to every suggestion, but I'll read as many as I can. diff --git a/book/LICENSE b/book/LICENSE new file mode 100644 index 0000000..2f244ac --- /dev/null +++ b/book/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/book/VERSIONING.md b/book/VERSIONING.md new file mode 100644 index 0000000..ed3b9bf --- /dev/null +++ b/book/VERSIONING.md @@ -0,0 +1,12 @@ +# How this book is versioned + +After the [first release](https://github.com/nbarbettini/little-aspnetcore-book/releases/tag/v1.0.0) (1.0.0), + +* Small fixes such as typos, code errors, and re-formatting will be released as patch versions, e.g. 1.0.1 +* Larger changes or updates will be released as minor versions, e.g. 1.1.0 + +The [Github release history](https://github.com/nbarbettini/little-aspnetcore-book/releases) contains the version history. + +## Latest version + +You can always get the latest version at [littleasp.net/book](http://littleasp.net/book). diff --git a/book/chapters/add-external-packages/friendly-dates.png b/book/chapters/add-external-packages/friendly-dates.png new file mode 100644 index 0000000..2ecb7ce Binary files /dev/null and b/book/chapters/add-external-packages/friendly-dates.png differ diff --git a/book/chapters/add-external-packages/index.html b/book/chapters/add-external-packages/index.html new file mode 100644 index 0000000..a5546f2 --- /dev/null +++ b/book/chapters/add-external-packages/index.html @@ -0,0 +1,807 @@ + + + + + + + 添加外来软件包 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ +
+ + + + + + + + +
+
+ +
+
+ +
+ +

添加外来软件包

+

选择诸如 .NET 这种成熟的生态系统,其最大的优势之一,就是第三方软件包和插件的量非常庞大。正如其它的软件包系统一样,你可以下载并安装 .NET 软件包,以获取协助,来完成几乎任何能想到的任务和难题。

+

NuGet 即是包管理工具,也是官方的软件包仓库(位于 https://www.nuget.org)。你可以在网页上检索 NuGet 软件包,并在自己的机器上使用终端(或者 Visual Studio 里的图形界面)安装它们。

+

安装软件包 Humanizer

+

上一章结尾处,待办事项 程序展示的 待办事项条目 看起来是这样的:

+

Dates in ISO 8601 format

+

“截止日期”一栏所展示的日期,这种格式(叫做 ISO 8601)对机器来说很方便,但是人类看着就不爽了。如果看到的是“还剩 X 天”这样,不是更好吗?

+

你完全可以自己写一段代码,把一个日期转换成更人性化的字符串,不过幸运的是,还有个更便捷的方法。

+

NuGet 上的软件包 Humanizer (https://www.nuget.org/packages/Humanizer) 解决了这种问题,它提供的方法可以“人性化(humanize)” 或者说 改写 几乎任何东西:日期、时间、时长、数字等等。它是个很好很有用的开源项目,根据 MIT 许可证发布。

+

要把它加入到你的项目里,在终端窗口运行这个命令:

+
dotnet add package Humanizer
+

如果你浏览项目文件 AspNetCoreTodo.csproj,会看到新增了一行 PackageReference,引用了 Humanizer

+

在视图中使用 Humanizer

+

要在代码里使用一个软件包,你通常需要在文件顶端添加一个 using 语句,以导入该软件包的内容。

+

既然 Humanizer 将用于在视图中改写日期,你可以直接在视图里使用它。首先在视图顶端添加一个 @using 语句:

+

Views/Todo/Index.cshtml

+
@model TodoViewModel
+@using Humanizer
+
+// ...
+
+

然后,修改那行写着 DueAt 方法的代码,使用 Humanizer 里的 Humanize 方法:

+
<td>@item.DueAt.Humanize()</td>
+
+

现在,日期的可读性大大提高了:

+

Human-readable dates

+

NuGet 上有着大量的软件包,从 XML解析 到 机器学习 到 Twitter发帖,包罗万象。ASP.NET Core 自身,在表象之下,也只不过是添加到你项目里的一个 NuGet 软件包集合。

+
+

使用 dotnet new mvc 创建的项目文件包含一条指向Microsoft.AspNetCore.All软件包的引用,这是个便捷的“元软件包(metapackage)”,它引用了你在项目中所需的所有其它 ASP.NET Core 软件包。这样,你就不必在项目文件里添加数百个软件包的引用了。

+
+

下一章里,你将使用另一套 NuGet 软件包(一个叫 Entity Framework Core 的系统),编写代码与数据库进行交互。

+
+

Add external packages

+

One of the big advantages of using a mature ecosystem like .NET is that the number of third-party packages and plugins is huge. Just like other package systems, you can download and install .NET packages that help with almost any task or problem you can imagine.

+

NuGet is both the package manager tool and the official package repository (at https://www.nuget.org). You can search for NuGet packages on the web, and install them from your local machine through the terminal (or the GUI, if you're using Visual Studio).

+

Install the Humanizer package

+

At the end of the last chapter, the to-do application displayed to-do items like this:

+

Dates in ISO 8601 format

+

The due date column is displaying dates in a format that's good for machines (called ISO 8601), but clunky for humans. Wouldn't it be nicer if it simply read "X days from now"?

+

You could write code yourself that converted an ISO 8601 date into a human-friendly string, but fortunately, there's a faster way.

+

The Humanizer package on NuGet solves this problem by providing methods that can "humanize" or rewrite almost anything: dates, times, durations, numbers, and so on. It's a fantastic and useful open-source project that's published under the permissive MIT license.

+

To add it to your project, run this command in the terminal:

+
dotnet add package Humanizer
+

If you peek at the AspNetCoreTodo.csproj project file, you'll see a new PackageReference line that references Humanizer.

+

Use Humanizer in the view

+

To use a package in your code, you usually need to add a using statement that imports the package at the top of the file.

+

Since Humanizer will be used to rewrite dates rendered in the view, you can use it directly in the view itself. First, add a @using statement at the top of the view:

+

Views/Todo/Index.cshtml

+
@model TodoViewModel
+@using Humanizer
+
+// ...
+
+

Then, update the line that writes the DueAt property to use Humanizer's Humanize method:

+
<td>@item.DueAt.Humanize()</td>
+
+

Now the dates are much more readable:

+

Human-readable dates

+

There are packages available on NuGet for everything from parsing XML to machine learning to posting to Twitter. ASP.NET Core itself, under the hood, is nothing more than a collection of NuGet packages that are added to your project.

+
+

The project file created by dotnet new mvc includes a single reference to the Microsoft.AspNetCore.All package, which is a convenient "metapackage" that references all of the other ASP.NET Core packages you need for a typical project. That way, you don't need to have hundreds of package references in your project file.

+
+

In the next chapter, you'll use another set of NuGet packages (a system called Entity Framework Core) to write code that interacts with a database.

+ + +
+ +
+
+
+ +

results matching ""

+
    + +
    +
    + +

    No results matching ""

    + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/add-external-packages/iso8601.png b/book/chapters/add-external-packages/iso8601.png new file mode 100644 index 0000000..be39c4d Binary files /dev/null and b/book/chapters/add-external-packages/iso8601.png differ diff --git a/book/chapters/add-more-features/add-todo-items.html b/book/chapters/add-more-features/add-todo-items.html new file mode 100644 index 0000000..c877c75 --- /dev/null +++ b/book/chapters/add-more-features/add-todo-items.html @@ -0,0 +1,967 @@ + + + + + + + 添加 待办事项 条目 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + +
    + +
    + + + + + + + + +
    +
    + +
    +
    + +
    + +

    添加 待办事项 条目

    +

    使用列表下面那个简易的表单,用户可以添加新的 待办事项 条目:

    +

    Final form

    +

    添加这个功能,需要几个步骤:

    +
      +
    • 在视图里添加一个 表单
    • +
    • 在控制器里添加一个新的 action 处理这个表单
    • +
    • 在服务层添加代码,对数据库进行修改
    • +
    +

    添加一个表单

    +

    视图 Todo/Index.cshtml 里有个占位符,代表 Add Item form:

    +
    <div class="panel-footer add-item-form">
    +  <!-- TODO: Add item form -->
    +</div>
    +
    +

    为保持各部分独立且组织良好,你应该以 局部视图(partial view) 的形式创建这个表单。局部视图是较大视图的一个小片段,存放于一个独立的文件。

    +

    创建一个 AddItemPartial.cshtml 视图:

    +

    Views/Todo/AddItemPartial.cshtml

    +
    @model TodoItem
    +
    +<form asp-action="AddItem" method="POST">
    +    <label asp-for="Title">Add a new item:</label>
    +    <input asp-for="Title">
    +    <button type="submit">Add</button>
    +</form>
    +
    +

    asp-action 这个 tag helper 会为该表单生成一个 URL,就像你将其应用在一个 <a> 元素上那样。在本例中,asp-action 会被你创建的 AddItem 的真实地址取代:

    +
    <form action="/Todo/AddItem" method="POST">
    +
    +

    <form> 元素里,添加一个 asp- tag helper 的同时会在表单里添加一个隐藏字段,其中包含一个验证标记。该验证标记可用于防止 跨站请求伪造(cross-site request forgery -- CSRF) 攻击。在你编写这个 action 的时候,会验证这个标记。

    +

    局部视图就这样创建好了。然后,要在 Todo 主视图里引用它:

    +

    Views/Todo/Index.cshtml

    +
    <div class="panel-footer add-item-form">
    +  @await Html.PartialAsync("AddItemPartial", new TodoItem())
    +</div>
    +
    +

    添加 action

    +

    当某个用户在你刚刚创建的表单里点击 Add,其浏览器会构建一个 POST 请求到你应用程序的 /Todo/AddItem。眼下这不会有效果,因为还没有任何 action 会处理 /Todo/AddItem 这个路由。如果你现在去尝试,ASP.NET Core 会返回一个 404 Not Found 错误。

    +

    你需要在 TodoConteoller 中添加一个名为 AddItem 的新 action:

    +
    [ValidateAntiForgeryToken]
    +public async Task<IActionResult> AddItem(TodoItem newItem)
    +{
    +    if (!ModelState.IsValid)
    +    {
    +        return RedirectToAction("Index");
    +    }
    +
    +    var successful = await _todoItemService.AddItemAsync(newItem);
    +    if (!successful)
    +    {
    +        return BadRequest("Could not add item.");
    +    }
    +
    +    return RedirectToAction("Index");
    +}
    +
    +

    注意到 AddItem action 接受一个 TodoItem 参数的方式了吗?这是你在 MVC basics 章节中创建的那个,用于存储一个 待办事项条目 相关信息的 TodoItem 模型。当它在这里作为一个 action 参数使用, ASP.NET Core 会自动执行一个称为 模型绑定 的处理流程。

    +

    模型绑定流程会查看请求内的数据,并试图智能地把输入的字段和模型里的属性匹配起来。换句话说,当用户提交这个表单,并且浏览器 POST 到了此 action,ASP.NET Core 会从表单里提取信息,并存放到那个 newItem 变量里。

    +

    位于 action 前面的 [ValidateAntiForgeryToken] 属性告知 ASP.NET Core 去查找(并验证)那个隐藏的验证标记,就是由 asp-action tag helper 添加到表单里的那个标记。在处理 跨站请求伪造(CSRF) 的时候,这是个重要的安全措施,你的用户可能被欺骗,以至于在一个恶意的网站上提交数据。这里的验证标记被用于确保呈现和提交表单的,是你的程序。

    +

    再检视一次 AddItemPartial.cshtml 视图。文件顶部的 @model TodoItem 那行告知 ASP.NET Core,该视图需要配合 TodoItem 模型一起使用。它促成了以下功能,在 <input> 标签上,应用 asp-for="Title",让 ASP.NET Core 知晓该 input 元素是为 Title 字段服务的。

    +

    由于 @model 这一行的存在,此局部视图在被渲染的时候,期望被传入一个 TodoItem 对象。经由 Html.PartialAsync 传给它一个 new TodoItem,以一个空条目初始化该表单。(请尝试添加{ Title = "hello" },看看会发生什么!)

    +

    在模型绑定流程中,模型里的任何属性,如果不能匹配到请求里的字段,都会被忽略掉。由于表单里仅包含一个 Title 元素,你能预见 TodoItem 上的其它属性(IsDone 标记,DueAt 日期)将为空,或者包含着一个默认值。

    +
    +

    作为复用 TodoItem 模型的替代方案,还可以创建一个独立的模型(比如叫 NewTodoItem),仅用于这个 action 中,并仅具有特定的字段(Title),用于添加新的待办事项条目。模型绑定流程依然要用到,但现在,你分离了两个模型,一个用于在数据库中存储待办事项条目,另一个用于绑定传入的请求数据。这个方案,也被称作 绑定模型(binding model) 或者 数据传输对象(data transfer object)(DTO)。这个模式常见于更大更复杂的项目。

    +
    +

    请求数据绑定到模型后,ASP.NET Core 还进行了 模型核验操作(model validation)。核验操作检查从传入请求绑定到模型的数据,鉴别其合理性和有效性。你可以在模型中添加属性,告知 ASP.NET Core 以怎样的方式进行核验。

    +

    Title 字段上的 [Required] 属性告知 ASP.NET Core 的模型核验器,如果标题缺失或为空,则判定其无效。看一下 action AddItem 的代码:首个代码块检查 ModelState(模型核验的结果)是否有效。习惯上,这种核验都在 action 最开始的地方进行。

    +
    if (!ModelState.IsValid)
    +{
    +    return RedirectToAction("Index");
    +}
    +
    +

    如果 ModelState 出于某种原因无效,浏览器会被重定向到路由 /Todo/Index,后者会刷新页面。

    +

    接下来,控制器调用到服务层,进行实际的数据库操作,保存这个新的待办事项条目:

    +
    var successful = await _todoItemService.AddItemAsync(newItem);
    +if (!successful)
    +{
    +    return BadRequest(new { error = "Could not add item." });
    +}
    +
    +

    取决于该条目添加到数据库的结果成功与否,AddItemAsync 方法会返回 true 或者 false。如果该操作因为某些原因失败了,action 会连带一个包含 error 字段的对象,返回 400 Bad Request

    +

    最终,如果操作顺利完成,action 会将浏览器重定向到路由 /Todo/Index,后者会刷新页面并向用户显示新的待办事项列表。

    +

    添加服务方法(函数)

    +

    如果你使用的代码编辑器了解 C# 的语法,你会在 AddItemAsync 下面看到红色的波浪线,因为该方法尚未定义。

    +

    作为最后一步,你需要在服务层里添加一个方法。首先,在 ITodoItemService 接口里添加它的定义:

    +
    public interface ITodoItemService
    +{
    +    Task<TodoItem[]> GetIncompleteItemsAsync();
    +
    +    Task<bool> AddItemAsync(TodoItem newItem);
    +}
    +
    +

    然后,在 TodoItemService 里面添加实现:

    +
    public async Task<bool> AddItemAsync(TodoItem newItem)
    +{
    +    newItem.Id = Guid.NewGuid();
    +    newItem.IsDone = false;
    +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
    +
    +    _context.Items.Add(newItem);
    +
    +    var saveResult = await _context.SaveChangesAsync();
    +    return saveResult == 1;
    +}
    +
    +

    字段 newItem.Title 已经由 ASP.NET Core 的模型绑定器设置,所以,这个方法仅需要分配 ID 并为其它字段设置缺省值。然后,这个新条目被加入到数据库上下文中。在调用 SaveChangesAsync() 前它尚未被保存。如果保存操作成功,SaveChangesAsync() 会返回 1。

    +

    试试看

    +

    运行程序,使用页面上的表单添加几个条目到 待办事项 列表里。因为这些条目存储在数据库里,就算你关闭程序后再重新运行,这些条目都还保存在那里。

    +
    +

    作为附加练习,请尝试使用 HTML 和 JavaScript 添加一个日期选择框,并让用户为 DueAt 属性选择一个(可选的)日期。然后,用这个日期替换那个默认的“3天后到期”。

    +
    +
    +

    Add new to-do items

    +

    The user will add new to-do items with a simple form below the list:

    +

    Final form

    +

    Adding this feature requires a few steps:

    +
      +
    • Adding a form to the view
    • +
    • Creating a new action on the controller to handle the form
    • +
    • Adding code to the service layer to update the database
    • +
    +

    Add a form

    +

    The Views/Todo/Index.cshtml view has a placeholder for the Add Item form:

    +
    <div class="panel-footer add-item-form">
    +  <!-- TODO: Add item form -->
    +</div>
    +
    +

    To keep things separate and organized, you'll create the form as a partial view. A partial view is a small piece of a larger view that lives in a separate file.

    +

    Create an AddItemPartial.cshtml view:

    +

    Views/Todo/AddItemPartial.cshtml

    +
    @model TodoItem
    +
    +<form asp-action="AddItem" method="POST">
    +    <label asp-for="Title">Add a new item:</label>
    +    <input asp-for="Title">
    +    <button type="submit">Add</button>
    +</form>
    +
    +

    The asp-action tag helper can generate a URL for the form, just like when you use it on an <a> element. In this case, the asp-action helper gets replaced with the real path to the AddItem route you'll create:

    +
    <form action="/Todo/AddItem" method="POST">
    +
    +

    Adding an asp- tag helper to the <form> element also adds a hidden field to the form containing a verification token. This verification token can be used to prevent cross-site request forgery (CSRF) attacks. You'll verify the token when you write the action.

    +

    That takes care of creating the partial view. Now, reference it from the main Todo view:

    +

    Views/Todo/Index.cshtml

    +
    <div class="panel-footer add-item-form">
    +  @await Html.PartialAsync("AddItemPartial", new TodoItem())
    +</div>
    +
    +

    Add an action

    +

    When a user clicks Add on the form you just created, their browser will construct a POST request to /Todo/AddItem on your application. That won't work right now, because there isn't any action that can handle the /Todo/AddItem route. If you try it now, ASP.NET Core will return a 404 Not Found error.

    +

    You'll need to create a new action called AddItem on the TodoController:

    +
    [ValidateAntiForgeryToken]
    +public async Task<IActionResult> AddItem(TodoItem newItem)
    +{
    +    if (!ModelState.IsValid)
    +    {
    +        return RedirectToAction("Index");
    +    }
    +
    +    var successful = await _todoItemService.AddItemAsync(newItem);
    +    if (!successful)
    +    {
    +        return BadRequest("Could not add item.");
    +    }
    +
    +    return RedirectToAction("Index");
    +}
    +
    +

    Notice how the new AddItem action accepts a TodoItem parameter? This is the same TodoItem model you created in the MVC basics chapter to store information about a to-do item. When it's used here as an action parameter, ASP.NET Core will automatically perform a process called model binding.

    +

    Model binding looks at the data in a request and tries to intelligently match the incoming fields with properties on the model. In other words, when the user submits this form and their browser POSTs to this action, ASP.NET Core will grab the information from the form and place it in the newItem variable.

    +

    The [ValidateAntiForgeryToken] attribute before the action tells ASP.NET Core that it should look for (and verify) the hidden verification token that was added to the form by the asp-action tag helper. This is an important security measure to prevent cross-site request forgery (CSRF) attacks, where your users could be tricked into submitting data from a malicious site. The verification token ensures that your application is actually the one that rendered and submitted the form.

    +

    Take a look at the AddItemPartial.cshtml view once more. The @model TodoItem line at the top of the file tells ASP.NET Core that the view should expect to be paired with the TodoItem model. This makes it possible to use asp-for="Title" on the <input> tag to let ASP.NET Core know that this input element is for the Title property.

    +

    Because of the @model line, the partial view will expect to be passed a TodoItem object when it's rendered. Passing it a new TodoItem via Html.PartialAsync initializes the form with an empty item. (Try appending { Title = "hello" } and see what happens!)

    +

    During model binding, any model properties that can't be matched up with fields in the request are ignored. Since the form only includes a Title input element, you can expect that the other properties on TodoItem (the IsDone flag, the DueAt date) will be empty or contain default values.

    +
    +

    Instead of reusing the TodoItem model, another approach would be to create a separate model (like NewTodoItem) that's only used for this action and only has the specific properties (Title) you need for adding a new to-do item. Model binding is still used, but this way you've separated the model that's used for storing a to-do item in the database from the model that's used for binding incoming request data. This is sometimes called a binding model or a data transfer object (DTO). This pattern is common in larger, more complex projects.

    +
    +

    After binding the request data to the model, ASP.NET Core also performs model validation. Validation checks whether the data bound to the model from the incoming request makes sense or is valid. You can add attributes to the model to tell ASP.NET Core how it should be validated.

    +

    The [Required] attribute on the Title property tells ASP.NET Core's model validator to consider the title invalid if it is missing or blank. Take a look at the code of the AddItem action: the first block checks whether the ModelState (the model validation result) is valid. It's customary to do this validation check right at the beginning of the action:

    +
    if (!ModelState.IsValid)
    +{
    +    return RedirectToAction("Index");
    +}
    +
    +

    If the ModelState is invalid for any reason, the browser will be redirected to the /Todo/Index route, which refreshes the page.

    +

    Next, the controller calls into the service layer to do the actual database operation of saving the new to-do item:

    +
    var successful = await _todoItemService.AddItemAsync(newItem);
    +if (!successful)
    +{
    +    return BadRequest(new { error = "Could not add item." });
    +}
    +
    +

    The AddItemAsync method will return true or false depending on whether the item was successfully added to the database. If it fails for some reason, the action will return an HTTP 400 Bad Request error along with an object that contains an error message.

    +

    Finally, if everything completed without errors, the action redirects the browser to the /Todo/Index route, which refreshes the page and displays the new, updated list of to-do items to the user.

    +

    Add a service method

    +

    If you're using a code editor that understands C#, you'll see red squiggely lines under AddItemAsync because the method doesn't exist yet.

    +

    As a last step, you need to add a method to the service layer. First, add it to the interface definition in ITodoItemService:

    +
    public interface ITodoItemService
    +{
    +    Task<TodoItem[]> GetIncompleteItemsAsync();
    +
    +    Task<bool> AddItemAsync(TodoItem newItem);
    +}
    +
    +

    Then, the actual implementation in TodoItemService:

    +
    public async Task<bool> AddItemAsync(TodoItem newItem)
    +{
    +    newItem.Id = Guid.NewGuid();
    +    newItem.IsDone = false;
    +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
    +
    +    _context.Items.Add(newItem);
    +
    +    var saveResult = await _context.SaveChangesAsync();
    +    return saveResult == 1;
    +}
    +
    +

    The newItem.Title property has already been set by ASP.NET Core's model binder, so this method only needs to assign an ID and set the default values for the other properties. Then, the new item is added to the database context. It isn't actually saved until you call SaveChangesAsync(). If the save operation was successful, SaveChangesAsync() will return 1.

    +

    Try it out

    +

    Run the application and add some items to your to-do list with the form. Since the items are being stored in the database, they'll still be there even after you stop and start the application again.

    +
    +

    As an extra challenge, try adding a date picker using HTML and JavaScript, and let the user choose an (optional) date for the DueAt property. Then, use that date instead of always making new tasks that are due in 3 days.

    +
    + + +
    + +
    +
    +
    + +

    results matching ""

    +
      + +
      +
      + +

      No results matching ""

      + +
      +
      +
      + +
      +
      + +
      + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/add-more-features/complete-with-checkbox.html b/book/chapters/add-more-features/complete-with-checkbox.html new file mode 100644 index 0000000..d6546ef --- /dev/null +++ b/book/chapters/add-more-features/complete-with-checkbox.html @@ -0,0 +1,955 @@ + + + + + + + 使用复选框标记条目完成 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + +
      + +
      + +
      + + + + + + + + +
      +
      + +
      +
      + +
      + +

      使用复选框标记条目完成

      +

      向 待办事项 列表里添加条目,这功能很棒,但无论如何,这些事项都得被处理掉。在 Views/Todo/Index.cshtml 视图里,为每个待办事项条目显示了一个复选框:

      +
      <input type="checkbox" class="done-checkbox">
      +
      +

      点击这个复选框(还)不会导致任何结果。像上一章节一样,你要通过表单和 action 添加这一功能。在本例中,你还要写一丁点 JavaScript 代码。

      +

      向视图添加表单元素

      +

      首先,修改视图,并用让每个复选框都被一个 <form> 元素包含。然后,添加一个隐藏元素,其中包含条目的 ID:

      +

      Views/Todo/Index.cshtml

      +
      <td>
      +    <form asp-action="MarkDone" method="POST">
      +        <input type="checkbox" class="done-checkbox">
      +        <input type="hidden" name="id" value="@item.Id">
      +    </form>
      +</td>
      +
      +

      当视图中的 foreach 循环运行并为每个待办事项条目显示一行,每一行都会包含此表单的一个副本。隐藏的输入框包含该 待办事项条目 的 ID,以便你的控制器代码辨别是哪个复选框被选中了。(如果没有它,你只能知道 某个 复选框被选中了,而无法知道是哪个。)

      +

      如果你现在立刻运行你的程序,复选框还是没什么作用,因为没有提交按钮通知浏览器,让它根据表单数据构建一个 POST 请求。你可以在每个复选框下面添加一个提交按钮,但这样的用户体验太蠢了。理想的方法是,点击复选框的时候,能够自动地提交该表单。你可以添加一些 JavaScript 达成这一点。

      +

      添加 JavaScript 代码

      +

      wwwroot/js 目录找到文件 site.js ,并添加如下代码:

      +

      wwwroot/js/site.js

      +
      $(document).ready(function() {
      +
      +    // Wire up all of the checkboxes to run markCompleted()
      +    $('.done-checkbox').on('click', function(e) {
      +        markCompleted(e.target);
      +    });
      +});
      +
      +function markCompleted(checkbox) {
      +    checkbox.disabled = true;
      +
      +    var row = checkbox.closest('tr');
      +    $(row).addClass('done');
      +
      +    var form = checkbox.closest('form');
      +    form.submit();
      +}
      +
      +

      这段代码先使用 jQuery(一个 JavaScript 辅助库),通过 CSS 类 done-checkbox 找出页面上的所有复选框,将一些代码关联到其 click 事件。当一个复选框被点击,markCompleted() 函数就被执行。

      +

      markCompleted() 函数的功能如下:

      +
        +
      • 添加 disabled 属性到该复选框,避免它再次被点击
      • +
      • 为包含该复选框的行添加 done CSS 类,这个类会基于 style.css 中的 CSS 规则,改变该行的外观
      • +
      • 提交该表单
      • +
      +

      视图和前端代码就这样搞定了。是时候添加一个新 action 了!

      +

      在控制器里添加 action

      +

      正如你可能已经猜到的那样,你需要在 TodoController 里添加一个 action MarkDone

      +
      [ValidateAntiForgeryToken]
      +public async Task<IActionResult> MarkDone(Guid id)
      +{
      +    if (id == Guid.Empty)
      +    {
      +        return RedirectToAction("Index");
      +    }
      +
      +    var successful = await _todoItemService.MarkDoneAsync(id);
      +    if (!successful)
      +    {
      +        return BadRequest("Could not mark item as done.");
      +    }
      +
      +    return RedirectToAction("Index");
      +}
      +
      +

      让我们逐行分析这个 action 方法。首先,该方法接受一个名为 idGuid 类型参数。参数 id 非常简单,这跟 AddItem 不同,那个 action 用了一个模型作为参数,还进行了 模型绑定/核验 的处理。如果传入的请求中包括一个名为 id 的参数, ASP.NET Core 会尝试将其解析为一个 guid。这项功能得益于你在表单里加入的那个名为 id 的隐藏元素。

      +

      既然你没使用 模型绑定流程,就没有用于有效性检查的 ModelState。取而代之,你可以直接检查 guid 的值,以判断它的有效性。如果出于某些原因,请求中的 id 参数缺失了,或者无法解析为一个 guid,则 id 的值将是 GUID.Empty。如果这种情况发生,action 就让浏览器重定向到 /Todo/Index 并刷新页面。

      +

      接下来,控制器需要调用服务层去修改数据库。这个功能,将要由 ITodoItemService 接口中的一个新方法 MarkDoneAsync 来实现,它会根据操作成功与否,返回 true 或者 false:

      +
      var successful = await _todoItemService.MarkDoneAsync(id);
      +if (!successful)
      +{
      +    return BadRequest("Could not mark item as done.");
      +}
      +
      +

      最终,如果一切顺利,浏览器会被重定向到 /Todo/Index,并刷新页面。

      +

      修改过视图和控制器,剩下的就是要添加缺失的服务方法了。

      +

      添加服务方法

      +

      首先,在接口定义中添加 MarkDoneAsync

      +

      Services/ITodoItemService.cs

      +
      Task<bool> MarkDoneAsync(Guid id);
      +
      +

      然后,在 TodoItemService 中添加具体的实现:

      +

      Services/TodoItemService.cs

      +
      public async Task<bool> MarkDoneAsync(Guid id)
      +{
      +    var item = await _context.Items
      +        .Where(x => x.Id == id)
      +        .SingleOrDefaultAsync();
      +
      +    if (item == null) return false;
      +
      +    item.IsDone = true;
      +
      +    var saveResult = await _context.SaveChangesAsync();
      +    return saveResult == 1; // One entity should have been updated
      +}
      +
      +

      该方法使用 Entity Framework Core 和 Where() 在数据库中按 ID 查找一个条目。SingleOrDefaultAsync() 方法要么返回该条目(若存在),要么返回 null——如果找不到。

      +

      一旦你确定 item 不是 null,设置 IsDone 属性就是小事一桩了:

      +
      item.IsDone = true;
      +
      +

      修改该字段仅仅影响该条目的本地拷贝,SaveChangesAsync() 被调用之后才会把修改的内容持久化到数据库里。SaveChangesAsync() 返回一个整数,表示在这次保存操作中被更新的条目的数量。在当前的情况下,它要么是1(条目更新了),要么是0(有错误发生)。

      +

      试试看

      +

      运行程序并勾选列表中的某些条目完成掉。刷新页面,它们将自动消失掉,这归功于 GetIncompleteItemsAsync() 方法中的 Where() 过滤器。

      +

      现在,程序里包含一个单一、共享的待办事项列表。如果它为每个用户保存独立的列表,将会更有用。下一章,你将使用 ASP.NET Core Identity,为项目添加安全及认证等特性。

      +
      +

      Complete items with a checkbox

      +

      Adding items to your to-do list is great, but eventually you'll need to get things done, too. In the Views/Todo/Index.cshtml view, a checkbox is rendered for each to-do item:

      +
      <input type="checkbox" class="done-checkbox">
      +
      +

      Clicking the checkbox doesn't do anything (yet). Just like the last chapter, you'll add this behavior using forms and actions. In this case, you'll also need a tiny bit of JavaScript code.

      +

      Add form elements to the view

      +

      First, update the view and wrap each checkbox with a <form> element. Then, add a hidden element containing the item's ID:

      +

      Views/Todo/Index.cshtml

      +
      <td>
      +    <form asp-action="MarkDone" method="POST">
      +        <input type="checkbox" class="done-checkbox">
      +        <input type="hidden" name="id" value="@item.Id">
      +    </form>
      +</td>
      +
      +

      When the foreach loop runs in the view and prints a row for each to-do item, a copy of this form will exist in each row. The hidden input containing the to-do item's ID makes it possible for your controller code to tell which box was checked. (Without it, you'd be able to tell that some box was checked, but not which one.)

      +

      If you run your application right now, the checkboxes still won't do anything, because there's no submit button to tell the browser to create a POST request with the form's data. You could add a submit button under each checkbox, but that would be a silly user experience. Ideally, clicking the checkbox should automatically submit the form. You can achieve that by adding some JavaScript.

      +

      Add JavaScript code

      +

      Find the site.js file in the wwwroot/js directory and add this code:

      +

      wwwroot/js/site.js

      +
      $(document).ready(function() {
      +
      +    // Wire up all of the checkboxes to run markCompleted()
      +    $('.done-checkbox').on('click', function(e) {
      +        markCompleted(e.target);
      +    });
      +});
      +
      +function markCompleted(checkbox) {
      +    checkbox.disabled = true;
      +
      +    var row = checkbox.closest('tr');
      +    $(row).addClass('done');
      +
      +    var form = checkbox.closest('form');
      +    form.submit();
      +}
      +
      +

      This code first uses jQuery (a JavaScript helper library) to attach some code to the click even of all the checkboxes on the page with the CSS class done-checkbox. When a checkbox is clicked, the markCompleted() function is run.

      +

      The markCompleted() function does a few things:

      +
        +
      • Adds the disabled attribute to the checkbox so it can't be clicked again
      • +
      • Adds the done CSS class to the parent row that contains the checkbox, which changes the way the row looks based on the CSS rules in style.css
      • +
      • Submits the form
      • +
      +

      That takes care of the view and frontend code. Now it's time to add a new action!

      +

      Add an action to the controller

      +

      As you've probably guessed, you need to add an action called MarkDone in the TodoController:

      +
      [ValidateAntiForgeryToken]
      +public async Task<IActionResult> MarkDone(Guid id)
      +{
      +    if (id == Guid.Empty)
      +    {
      +        return RedirectToAction("Index");
      +    }
      +
      +    var successful = await _todoItemService.MarkDoneAsync(id);
      +    if (!successful)
      +    {
      +        return BadRequest("Could not mark item as done.");
      +    }
      +
      +    return RedirectToAction("Index");
      +}
      +
      +

      Let's step through each line of this action method. First, the method accepts a Guid parameter called id in the method signature. Unlike the AddItem action, which used a model and model binding/validation, the id parameter is very simple. If the incoming request data includes a field called id, ASP.NET Core will try to parse it as a guid. This works because the hidden element you added to the checkbox form is named id.

      +

      Since you aren't using model binding, there's no ModelState to check for validity. Instead, you can check the guid value directly to make sure it's valid. If for some reason the id parameter in the request was missing or couldn't be parsed as a guid, id will have a value of Guid.Empty. If that's the case, the action tells the browser to redirect to /Todo/Index and refresh the page.

      +

      Next, the controller needs to call the service layer to update the database. This will be handled by a new method called MarkDoneAsync on the ITodoItemService interface, which will return true or false depending on whether the update succeeded:

      +
      var successful = await _todoItemService.MarkDoneAsync(id);
      +if (!successful)
      +{
      +    return BadRequest("Could not mark item as done.");
      +}
      +
      +

      Finally, if everything looks good, the browser is redirected to the /Todo/Index action and the page is refreshed.

      +

      With the view and controller updated, all that's left is adding the missing service method.

      +

      Add a service method

      +

      First, add MarkDoneAsync to the interface definition:

      +

      Services/ITodoItemService.cs

      +
      Task<bool> MarkDoneAsync(Guid id);
      +
      +

      Then, add the concrete implementation to the TodoItemService:

      +

      Services/TodoItemService.cs

      +
      public async Task<bool> MarkDoneAsync(Guid id)
      +{
      +    var item = await _context.Items
      +        .Where(x => x.Id == id)
      +        .SingleOrDefaultAsync();
      +
      +    if (item == null) return false;
      +
      +    item.IsDone = true;
      +
      +    var saveResult = await _context.SaveChangesAsync();
      +    return saveResult == 1; // One entity should have been updated
      +}
      +
      +

      This method uses Entity Framework Core and Where() to find an item by ID in the database. The SingleOrDefaultAsync() method will either return the item or null if it couldn't be found.

      +

      Once you're sure that item isn't null, it's a simple matter of setting the IsDone property:

      +
      item.IsDone = true;
      +
      +

      Changing the property only affects the local copy of the item until SaveChangesAsync() is called to persist the change back to the database. SaveChangesAsync() returns a number that indicates how many entities were updated during the save operation. In this case, it'll either be 1 (the item was updated) or 0 (something went wrong).

      +

      Try it out

      +

      Run the application and try checking some items off the list. Refresh the page and they'll disappear completely, because of the Where() filter in the GetIncompleteItemsAsync() method.

      +

      Right now, the application contains a single, shared to-do list. It'd be even more useful if it kept track of individual to-do lists for each user. In the next chapter, you'll add login and security features to the project.

      + + +
      + +
      +
      +
      + +

      results matching ""

      +
        + +
        +
        + +

        No results matching ""

        + +
        +
        +
        + +
        +
        + +
        + + + + + + + + + + + + + + +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/add-more-features/final-form.png b/book/chapters/add-more-features/final-form.png new file mode 100644 index 0000000..d8453db Binary files /dev/null and b/book/chapters/add-more-features/final-form.png differ diff --git a/book/chapters/add-more-features/index.html b/book/chapters/add-more-features/index.html new file mode 100644 index 0000000..feec006 --- /dev/null +++ b/book/chapters/add-more-features/index.html @@ -0,0 +1,749 @@ + + + + + + + 添加新特性 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + + + + + + + +
        + +
        + +
        + + + + + + + + +
        +
        + +
        +
        + +
        + +

        添加新特性

        +

        现在,你借助 Entity Framework Core 连接到了数据库,就为“给程序添加更多新特性”做好准备了。首先是这个功能:使用一个表单,添加新的待办事项条目。

        +
        +

        Add more features

        +

        Now that you've connected to a database using Entity Framework Core, you're ready to add some more features to the application. First, you'll make it possible to add new to-do items using a form.

        + + +
        + +
        +
        +
        + +

        results matching ""

        +
          + +
          +
          + +

          No results matching ""

          + +
          +
          +
          + +
          +
          + +
          + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/automated-testing/index.html b/book/chapters/automated-testing/index.html new file mode 100644 index 0000000..237b9dc --- /dev/null +++ b/book/chapters/automated-testing/index.html @@ -0,0 +1,751 @@ + + + + + + + 自动化测试 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + + + + + + + +
          + +
          + +
          + + + + + + + + +
          +
          + +
          +
          + +
          + +

          自动化测试

          +

          测试的编写在构建任何程序时都很重要。测试代码有助于发现及避免 bug,并使你后续重构代码的工作轻松些,以免破坏现有功能或引入新的问题。

          +

          在本章里,你将学习如何编写 单元测试集成测试 以检验你的 ASP.NET Core 程序。单元测试较小,用来确保单个方法或者逻辑块工作良好。集成测试(有时候也叫 功能性 测试)较大,模拟实际的应用场景,并检验你程序里的多个层次或组件。

          +
          +

          Automated testing

          +

          Writing tests is an important part of building any application. Testing your code helps you find and avoid bugs, and makes it easier to refactor your code later without breaking functionality or introducing new problems.

          +

          In this chapter you'll learn how to write both unit tests and integration tests that exercise your ASP.NET Core application. Unit tests are small tests that make sure a single method or chunk of logic works properly. Integration tests (sometimes called functional tests) are larger tests that simulate real-world scenarios and test multiple layers or parts of your application.

          + + +
          + +
          +
          +
          + +

          results matching ""

          +
            + +
            +
            + +

            No results matching ""

            + +
            +
            +
            + +
            +
            + +
            + + + + + + + + + + + + + + +
            + + +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/automated-testing/integration-testing.html b/book/chapters/automated-testing/integration-testing.html new file mode 100644 index 0000000..53f1d3c --- /dev/null +++ b/book/chapters/automated-testing/integration-testing.html @@ -0,0 +1,1008 @@ + + + + + + + 集成测试 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            +
            + + + + + + + + +
            + +
            + +
            + + + + + + + + +
            +
            + +
            +
            + +
            + +

            集成测试

            +

            与单元测试相比,集成测试在范围上大得多。它检验整个程序栈。集成测试并不会把一个类或组件隔离出来,而是确保你程序的所有组件协作良好,这些组件包括:路由、控制器、服务、数据库访问等等。

            +

            与单元测试相比,集成测试较慢,并且涵盖的范围较大,所以,一般来说,一个项目会有大量的单元测试内容,而集成测试的内容则屈指可数。

            +

            为了测试整个程序栈(包括控制器路由),集成测试往往像网络浏览器那样向程序发起 HTTP 请求。

            +

            要执行一个集成测试,你也可以启动程序,并手动向http://localhost:5000发起请求。不过,ASP.NET Core 提供了一个上佳的替代品:TestServer 类。这个类能够在测试期间托管你的程序,并在测试完成之后自动关闭它。

            +

            创建一个测试项目

            +

            如果你此刻位于项目目录,cd 到上一层的 AspNetCoreTodo 目录,使用以下命令搭建一个新项目:

            +
            dotnet new xunit -o AspNetCoreTodo.IntegrationTests
            +

            你现在的目录结构看起来应该是这样:

            +
            AspNetCoreTodo/
            +    AspNetCoreTodo/
            +        AspNetCoreTodo.csproj
            +        Controllers/
            +        (etc...)
            +
            +    AspNetCoreTodo.UnitTests/
            +        AspNetCoreTodo.UnitTests.csproj
            +
            +    AspNetCoreTodo.IntegrationTests/
            +        AspNetCoreTodo.IntegrationTests.csproj
            +
            +

            如果你愿意,可以把单元测试和集成测试放置在同一个项目里。对大型项目而言,通常会把它们分开,以便于它们各自独立运行。

            +
            +

            既然这个测试项目要用到主项目中的类,你需要添加一个引用指向主项目:

            +
            dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj
            +

            还需要添加 NuGet 包 Microsoft.AspNetCore.TestHost

            +
            dotnet add package Microsoft.AspNetCore.TestHost
            +

            删除 dotnet new 默认创建的文件 UnitTest1.cs,这样你就为集成测试的编写准备就绪了。

            +

            编写集成测试

            +

            在每次集成测试执行之前,需要进行一些配置。为免配置相关的代码把测试代码弄的乱七八糟,你可以把配置相关的内容提取到一个独立的类里。创建一个名为 TestFixture 的类:

            +

            AspNetCoreTodo.IntegrationTests/TestFixture.cs

            +
            using System;
            +using System.Collections.Generic;
            +using System.IO;
            +using System.Net.Http;
            +using Microsoft.AspNetCore.Hosting;
            +using Microsoft.AspNetCore.TestHost;
            +using Microsoft.Extensions.Configuration;
            +
            +namespace AspNetCoreTodo.IntegrationTests
            +{
            +    public class TestFixture : IDisposable  
            +    {
            +        private readonly TestServer _server;
            +
            +        public HttpClient Client { get; }
            +
            +        public TestFixture()
            +        {
            +            var builder = new WebHostBuilder()
            +                .UseStartup<AspNetCoreTodo.Startup>()
            +                .ConfigureAppConfiguration((context, config) =>
            +                {
            +                    config.SetBasePath(Path.Combine(
            +                        Directory.GetCurrentDirectory(),
            +                        "..\\..\\..\\..\\AspNetCoreTodo"));
            +
            +                    config.AddJsonFile("appsettings.json");
            +                });
            +
            +            _server = new TestServer(builder);
            +
            +            Client = _server.CreateClient();
            +            Client.BaseAddress = new Uri("http://localhost:8888");
            +        }
            +
            +        public void Dispose()
            +        {
            +            Client.Dispose();
            +            _server.Dispose();
            +        }
            +    }
            +}
            +
            +

            这个类配置好了一个 TestServer,并使测试代码干净利索。

            +

            现在你(真的)可以开始编写集成测试了。创建一个名为 TodoRouteShould 的类:

            +

            AspNetCoreTodo.IntegrationTests/TodoRouteShould.cs

            +
            using System.Net;
            +using System.Net.Http;
            +using System.Threading.Tasks;
            +using Xunit;
            +
            +namespace AspNetCoreTodo.IntegrationTests
            +{
            +    public class TodoRouteShould : IClassFixture<TestFixture>
            +    {
            +        private readonly HttpClient _client;
            +
            +        public TodoRouteShould(TestFixture fixture)
            +        {
            +            _client = fixture.Client;
            +        }
            +
            +        [Fact]
            +        public async Task ChallengeAnonymousUser()
            +        {
            +            // Arrange
            +            var request = new HttpRequestMessage(
            +                HttpMethod.Get, "/todo");
            +
            +            // Act: request the /todo route
            +            var response = await _client.SendAsync(request);
            +
            +            // Assert: the user is sent to the login page
            +            Assert.Equal(
            +                HttpStatusCode.Redirect,
            +                response.StatusCode);
            +
            +            Assert.Equal(
            +                "http://localhost:8888/Account" +
            +                "/Login?ReturnUrl=%2Ftodo",
            +                response.Headers.Location.ToString());
            +        }
            +    }
            +}
            +
            +

            这个测试发起一个匿名(未登录)的请求到路径 /todo,并验证浏览器被重定向到了登录页面。

            +

            这是个很适合集成测试的使用场景,因为它涵盖了程序的多个组件:路由系统、控制器、控制器被标记了 [Authorize] 等等。这是个良好的测试点,因为它确保你不会意外地弄丢了 [Authorize] 属性,从而导致待办事项视图对所有人可见。

            +

            在终端窗口运行 dotnet test,如果一切工作顺利,你会看到这样的成功信息:

            +
            Starting test execution, please wait...
            + Discovering: AspNetCoreTodo.IntegrationTests
            + Discovered:  AspNetCoreTodo.IntegrationTests
            + Starting:    AspNetCoreTodo.IntegrationTests
            + Finished:    AspNetCoreTodo.IntegrationTests
            +
            +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
            +Test Run Successful.
            +Test execution time: 2.0588 Seconds
            +

            本章总结

            +

            测试是个宽泛的话题,还有很多东西需要学习。本章节没有涉及 UI 测试,也没有对前端(JavaScript)代码进行测试——它本身可能就需要一整本书去讲述。不过,你应该已经掌握了一些基本的技能和知识,可用于实践并学习更多相关测试程序的编写。

            +

            像以往一样,ASP.NET Core 文档(https://docs.asp.net)和 StackOverflow 都是用于了解更多知识以及遇到问题时查找答案的好资源。

            +
            +

            Integration testing

            +

            Compared to unit tests, integration tests are much larger in scope. exercise the whole application stack. Instead of isolating one class or method, integration tests ensure that all of the components of your application are working together properly: routing, controllers, services, database code, and so on.

            +

            Integration tests are slower and more involved than unit tests, so it's common for a project to have lots of small unit tests but only a handful of integration tests.

            +

            In order to test the whole stack (including controller routing), integration tests typically make HTTP calls to your application just like a web browser would.

            +

            To perform an integration test, you could start your application and manually make requests to http://localhost:5000. However, ASP.NET Core provides a better alternative: the TestServer class. This class can host your application for the duration of the test, and then stop it automatically when the test is complete.

            +

            Create a test project

            +

            If you're currently in your project directory, cd up one level to the root AspNetCoreTodo directory. Use this command to scaffold a new test project:

            +
            dotnet new xunit -o AspNetCoreTodo.IntegrationTests
            +

            Your directory structure should now look like this:

            +
            AspNetCoreTodo/
            +    AspNetCoreTodo/
            +        AspNetCoreTodo.csproj
            +        Controllers/
            +        (etc...)
            +
            +    AspNetCoreTodo.UnitTests/
            +        AspNetCoreTodo.UnitTests.csproj
            +
            +    AspNetCoreTodo.IntegrationTests/
            +        AspNetCoreTodo.IntegrationTests.csproj
            +
            +

            If you prefer, you can keep your unit tests and integration tests in the same project. For large projects, it's common to split them up so it's easy to run them separately.

            +
            +

            Since the test project will use the classes defined in your main project, you'll need to add a reference to the main project:

            +
            dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj
            +

            You'll also need to add the Microsoft.AspNetCore.TestHost NuGet package:

            +
            dotnet add package Microsoft.AspNetCore.TestHost
            +

            Delete the UnitTest1.cs file that's created by dotnet new. You're ready to write an integration test.

            +

            Write an integration test

            +

            There are a few things that need to be configured on the test server before each test. Instead of cluttering the test with this setup code, you can keep this setup in a separate class. Create a new class called TestFixture:

            +

            AspNetCoreTodo.IntegrationTests/TestFixture.cs

            +
            using System;
            +using System.Collections.Generic;
            +using System.IO;
            +using System.Net.Http;
            +using Microsoft.AspNetCore.Hosting;
            +using Microsoft.AspNetCore.TestHost;
            +using Microsoft.Extensions.Configuration;
            +
            +namespace AspNetCoreTodo.IntegrationTests
            +{
            +    public class TestFixture : IDisposable  
            +    {
            +        private readonly TestServer _server;
            +
            +        public HttpClient Client { get; }
            +
            +        public TestFixture()
            +        {
            +            var builder = new WebHostBuilder()
            +                .UseStartup<AspNetCoreTodo.Startup>()
            +                .ConfigureAppConfiguration((context, config) =>
            +                {
            +                    config.SetBasePath(Path.Combine(
            +                        Directory.GetCurrentDirectory(),
            +                        "..\\..\\..\\..\\AspNetCoreTodo"));
            +
            +                    config.AddJsonFile("appsettings.json");
            +                });
            +
            +            _server = new TestServer(builder);
            +
            +            Client = _server.CreateClient();
            +            Client.BaseAddress = new Uri("http://localhost:8888");
            +        }
            +
            +        public void Dispose()
            +        {
            +            Client.Dispose();
            +            _server.Dispose();
            +        }
            +    }
            +}
            +
            +

            This class takes care of setting up a TestServer, and will help keep the tests themselves clean and tidy.

            +

            Now you're (really) ready to write an integration test. Create a new class called TodoRouteShould:

            +

            AspNetCoreTodo.IntegrationTests/TodoRouteShould.cs

            +
            using System.Net;
            +using System.Net.Http;
            +using System.Threading.Tasks;
            +using Xunit;
            +
            +namespace AspNetCoreTodo.IntegrationTests
            +{
            +    public class TodoRouteShould : IClassFixture<TestFixture>
            +    {
            +        private readonly HttpClient _client;
            +
            +        public TodoRouteShould(TestFixture fixture)
            +        {
            +            _client = fixture.Client;
            +        }
            +
            +        [Fact]
            +        public async Task ChallengeAnonymousUser()
            +        {
            +            // Arrange
            +            var request = new HttpRequestMessage(
            +                HttpMethod.Get, "/todo");
            +
            +            // Act: request the /todo route
            +            var response = await _client.SendAsync(request);
            +
            +            // Assert: the user is sent to the login page
            +            Assert.Equal(
            +                HttpStatusCode.Redirect,
            +                response.StatusCode);
            +
            +            Assert.Equal(
            +                "http://localhost:8888/Account" +
            +                "/Login?ReturnUrl=%2Ftodo",
            +                response.Headers.Location.ToString());
            +        }
            +    }
            +}
            +
            +

            This test makes an anonymous (not-logged-in) request to the /todo route and verifies that the browser is redirected to the login page.

            +

            This scenario is a good candidate for an integration test, because it involves multiple components of the application: the routing system, the controller, the fact that the controller is marked with [Authorize], and so on. It's also a good test because it ensures you won't ever accidentally remove the [Authorize] attribute and make the to-do view accessible to everyone.

            +

            Run the test

            +

            Run the test in the terminal with dotnet test. If everything's working right, you'll see a success message:

            +
            Starting test execution, please wait...
            + Discovering: AspNetCoreTodo.IntegrationTests
            + Discovered:  AspNetCoreTodo.IntegrationTests
            + Starting:    AspNetCoreTodo.IntegrationTests
            + Finished:    AspNetCoreTodo.IntegrationTests
            +
            +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
            +Test Run Successful.
            +Test execution time: 2.0588 Seconds
            +

            Wrap up

            +

            Testing is a broad topic, and there's much more to learn. This chapter doesn't touch on UI testing or testing frontend (JavaScript) code, which probably deserve entire books of their own. You should, however, have the skills and base knowledge you need to learn more about testing and to practice writing tests for your own applications.

            +

            The ASP.NET Core documentation (https://docs.asp.net) and Stack Overflow are great resources for learning more and finding answers when you get stuck.

            + + +
            + +
            +
            +
            + +

            results matching ""

            +
              + +
              +
              + +

              No results matching ""

              + +
              +
              +
              + +
              +
              + +
              + + + + + + + + + + + + + + +
              + + +
              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/automated-testing/unit-testing.html b/book/chapters/automated-testing/unit-testing.html new file mode 100644 index 0000000..6a0671a --- /dev/null +++ b/book/chapters/automated-testing/unit-testing.html @@ -0,0 +1,1029 @@ + + + + + + + 单元测试 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              +
              + + + + + + + + +
              + +
              + +
              + + + + + + + + +
              +
              + +
              +
              + +
              + +

              单元测试

              +

              单元测试是短小的测试,检查单个方法或类的行为。当你测试的代码依赖其它方法或类时,单元测试依赖于 虚构(mocking) 出来的其它类,以便在一个时时刻专注在一个点上。

              +

              例如,TodoController 有两个依赖: ITodoItemServiceUserManagerTodoItemService 接下来又依赖于 ApplicationDbContext。(你可以画一条线表示 TodoController > TodoItemService > ApplicationDbContext,这种方式被称为 依赖图)。

              +

              当程序运转正常的时候, ASP.NET Core 的服务容器和依赖注入系统在 TodoController 或者 TodoItemService 被创建时,把这些对象逐一地注入到依赖图里。

              +

              另一方面,当你写单元测试的时候,你需要自己处理这个依赖图。典刑的做法是,提供这些依赖的 虚构 或者 测试专用 版本。这意味着你可以把正在测试的类或者方法的逻辑隔离出来。(这很重要!如果你在测试一个服务,显然不应该一失手 顺带 写到数据库里去。)

              +

              创建一个测试项目

              +

              为测试创建独立的项目是一个良好的实践,以便把它们和你的程序代码分离开。新的测试项目应该被置于你主项目的同级目录(而非在主项目目录内)。

              +

              如果你当前在你项目目录里,向上 cd 一层。(这个目录也叫做 AspNetCoreTodo)。然后使用以下命令搭建出一个新的测试项目:

              +
              dotnet new xunit -o AspNetCoreTodo.UnitTests
              +

              xUnit.NET 是一个常用的针对 .NET 代码的测试框架,可用于编写单元和集成测试。像其它组件一样,它也是一组NuGet 包,可被安装在任意项目中 。dotnet new xunit 已经包括了你所需的一切。

              +

              你的目录结构看起来应该是这样:

              +
              AspNetCoreTodo/
              +    AspNetCoreTodo/
              +        AspNetCoreTodo.csproj
              +        Controllers/
              +        (etc...)
              +
              +    AspNetCoreTodo.UnitTests/
              +        AspNetCoreTodo.UnitTests.csproj
              +

              既然测试项目要使用你主项目中的类,你需要添加一个引用指向主项目:

              +
              dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj
              +

              删除自动创建的文件 UnitTest1.cs。你已经为第一个测试的编写准备就绪了。

              +
              +

              如果你用的是 Visual Studio Code,你可能需要关闭并重新打开 Visual Studio Code 窗口,以便代码完成功能在新项目里生效。

              +
              +

              写一个服务测试

              +

              看一下 TodoItemService 里面的 AddItemAsync() 方法:

              +
              public async Task<bool> AddItemAsync(
              +    TodoItem newItem, ApplicationUser user)
              +{
              +    newItem.Id = Guid.NewGuid();
              +    newItem.IsDone = false;
              +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
              +    newItem.UserId = user.Id;
              +
              +    _context.Items.Add(newItem);
              +
              +    var saveResult = await _context.SaveChangesAsync();
              +    return saveResult == 1;
              +}
              +
              +

              该方法在把新条目真正存入数据库之前,做了多个判断与假设(换句话说,在新条目上执行了业务逻辑):

              +
                +
              • UserId 属性应该被设置为用户的 ID
              • +
              • 新条目应该总是未完成状态(IsDone = false
              • +
              • 新条目的标题应该复制自 newItem.Title
              • +
              • 新条目应该总是从现在开始3天后过期
              • +
              +

              设想一下,如果你或者其他什么人重构了这个 AddItemAsync() 方法,并遗漏了某些以上的业务逻辑。你程序的行为,会在你意识不到的情况下变掉!你有办法避免这个情况,方法是编写一个测试,用以复核这些业务逻辑并未发生变化(就算是该方法的内部实现已经发生了变化)。

              +
              +

              这种情形——你意识不到自己改变了业务逻辑,虽然现在看起来好像不会发生,但是在一个更大更复杂的项目中,这会因为各种决策和假设而变得难以追踪。在越大的项目中,确保业务逻辑稳定的自动化检查就越重要。

              +
              +

              要编写一个单元测试来检验 TodoItemService 中的逻辑,在你的测试项目中创建一个新类:

              +

              AspNetCoreTodo.UnitTests/TodoItemServiceShould.cs

              +
              using System;
              +using System.Threading.Tasks;
              +using AspNetCoreTodo.Data;
              +using AspNetCoreTodo.Models;
              +using AspNetCoreTodo.Services;
              +using Microsoft.EntityFrameworkCore;
              +using Xunit;
              +
              +namespace AspNetCoreTodo.UnitTests
              +{
              +    public class TodoItemServiceShould
              +    {
              +        [Fact]
              +        public async Task AddNewItemAsIncompleteWithDueDate()
              +        {
              +            // ...
              +        }
              +    }
              +}
              +
              +
              +

              有很多不同的方法可以命名和组织测试,它们都有着各自的优缺点。我喜欢给测试类加上 Should 前缀,使方法名构成一个可读性良好的句子,不过你可以按自己的意愿选择命名风格。

              +
              +

              [Fact] 属性是 xUnit.NET 包里带来的,它把这个方法标记为一个测试方法。

              +

              TodoItemService 需要一个 ApplicationDbContext,后者通常连接到你的开发或生产环境里的数据库。你不该把这些数据库用于测试。相反,你可以在测试代码里使用 Entity Framework Core 的内存数据库 provider。因为整个数据库都存在于内存里,每次测试重新开始的时候,他就会被清空。并且,因为这是个合乎规格的 Entity Framework Core 的 provider,TodoItemService 不会察觉有什么异样。

              +

              用一个 DbContextOptionsBuilder 来配置内存数据库的 provider,然后对 AddItemAsync() 发起一个调用:

              +
              var options = new DbContextOptionsBuilder<ApplicationDbContext>()
              +    .UseInMemoryDatabase(databaseName: "Test_AddNewItem").Options;
              +
              +// Set up a context (connection to the "DB") for writing
              +using (var context = new ApplicationDbContext(options))
              +{
              +    var service = new TodoItemService(context);
              +
              +    var fakeUser = new ApplicationUser
              +    {
              +        Id = "fake-000",
              +        UserName = "fake@example.com"
              +    };
              +
              +    await service.AddItemAsync(new TodoItem
              +    {
              +        Title = "Testing?"
              +    }, fakeUser);
              +}
              +
              +

              最后一行创建了一个新的名为 Testing? 的待办事项,并通知服务将其存储到(内存)数据库里。

              +

              为验证业务逻辑执行的正确性,请在原有的 using 代码块下编写新内容:

              +
              // Use a separate context to read data back from the "DB"
              +using (var context = new ApplicationDbContext(options))
              +{
              +    var itemsInDatabase = await context
              +        .Items.CountAsync();
              +    Assert.Equal(1, itemsInDatabase);
              +
              +    var item = await context.Items.FirstAsync();
              +    Assert.Equal("Testing?", item.Title);
              +    Assert.Equal(false, item.IsDone);
              +
              +    // Item should be due 3 days from now (give or take a second)
              +    var difference = DateTimeOffset.Now.AddDays(3) - item.DueAt;
              +    Assert.True(difference < TimeSpan.FromSeconds(1));
              +}
              +
              +

              第一个验证步骤是个明智的检查:内存数据库里保存的条目绝不会超过一条。假设这个检查通过了,测试会使用 FirstAsync 方法取出存储的条目,然后断言其中的属性被设置了预期的值。

              +
              +

              不论是单元测试还是集成测试,都遵循 AAA(布置-执行-断言——Arrange-Act-Assert)模式:对象和数据首先被建立出来,然后执行一些动作,最后测试程序检查(断言)预期表现的存在。

              +
              +

              断言一个日期时间值有点棘手,因为比较两个日期值的时候,就算是只有毫秒部分不同,两个值也是不等的。替代方案是,检查 DueAt 的值距离期望值小于一秒。

              +

              运行测试

              +

              在终端窗口,运行以下命令(请确保你位于 AspNetCoreTodo.UnitTests 目录):

              +
              dotnet test
              +

              test 命令在当前的项目里查找测试方法(本例中,由 [Fact] 属性标记出来),然后运行它找到的所有测试,你会看到类似这样的输出:

              +
              Starting test execution, please wait...
              + Discovering: AspNetCoreTodo.UnitTests
              + Discovered:  AspNetCoreTodo.UnitTests
              + Starting:    AspNetCoreTodo.UnitTests
              + Finished:    AspNetCoreTodo.UnitTests
              +
              +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
              +Test Run Successful.
              +Test execution time: 1.9074 Seconds
              +

              你现在有了测试程序,覆盖了 TodoItemService 的测试范围。作为一个补充练习,请写出单元测试以确保:

              +
                +
              • 如果传入一个不存在的 ID, MarkDoneAsync() 返回 false
              • +
              • 当一个有效的条目被标记为完成状态, MarkDoneAsync() 返回 true
              • +
              • GetIncompleteItemsAsync() 只返回某个特定用户的条目
              • +
              +
              +

              Unit testing

              +

              Unit tests are small, short tests that check the behavior of a single method or class. When the code you're testing relies on other methods or classes, unit tests rely on mocking those other classes so that the test only focuses on one thing at a time.

              +

              For example, the TodoController class has two dependencies: an ITodoItemService and the UserManager. The TodoItemService, in turn, depends on the ApplicationDbContext. (The idea that you can draw a line from TodoController > TodoItemService > ApplicationDbContext is called a dependency graph).

              +

              When the application runs normally, the ASP.NET Core service container and dependency injection system injects each of those objects into the dependency graph when the TodoController or the TodoItemService is created.

              +

              When you write a unit test, on the other hand, you have to handle the dependency graph yourself. It's typical to provide test-only or "mocked" versions of those dependencies. This means you can isolate just the logic in the class or method you are testing. (This is important! If you're testing a service, you don't want to also be accidentally writing to your database.)

              +

              Create a test project

              +

              It's a best practice to create a separate project for your tests, so they are kept separate from your application code. The new test project should live in a directory that's next to (not inside) your main project's directory.

              +

              If you're currently in your project directory, cd up one level. (This root directory will also be called AspNetCoreTodo). Then use this command to scaffold a new test project:

              +
              dotnet new xunit -o AspNetCoreTodo.UnitTests
              +

              xUnit.NET is a popular test framework for .NET code that can be used to write both unit and integration tests. Like everything else, it's a set of NuGet packages that can be installed in any project. The dotnet new xunit template already includes everything you need.

              +

              Your directory structure should now look like this:

              +
              AspNetCoreTodo/
              +    AspNetCoreTodo/
              +        AspNetCoreTodo.csproj
              +        Controllers/
              +        (etc...)
              +
              +    AspNetCoreTodo.UnitTests/
              +        AspNetCoreTodo.UnitTests.csproj
              +

              Since the test project will use the classes defined in your main project, you'll need to add a reference to the AspNetCoreTodo project:

              +
              dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj
              +

              Delete the UnitTest1.cs file that's automatically created. You're ready to write your first test.

              +
              +

              If you're using Visual Studio Code, you may need to close and reopen the Visual Studio Code window to get code completion working in the new project.

              +
              +

              Write a service test

              +

              Take a look at the logic in the AddItemAsync() method of the TodoItemService:

              +
              public async Task<bool> AddItemAsync(
              +    TodoItem newItem, ApplicationUser user)
              +{
              +    newItem.Id = Guid.NewGuid();
              +    newItem.IsDone = false;
              +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
              +    newItem.UserId = user.Id;
              +
              +    _context.Items.Add(newItem);
              +
              +    var saveResult = await _context.SaveChangesAsync();
              +    return saveResult == 1;
              +}
              +
              +

              This method makes a number of decisions or assumptions about the new item (in other words, performs business logic on the new item) before it actually saves it to the database:

              +
                +
              • The UserId property should be set to the user's ID
              • +
              • New items should always be incomplete (IsDone = false)
              • +
              • The title of the new item should be copied from newItem.Title
              • +
              • New items should always be due 3 days from now
              • +
              +

              Imagine if you or someone else refactored the AddItemAsync() method and forgot about part of this business logic. The behavior of your application could change without you realizing it! You can prevent this by writing a test that double-checks that this business logic hasn't changed (even if the method's internal implementation changes).

              +
              +

              It might seem unlikely now that you could introduce a change in business logic without realizing it, but it becomes much harder to keep track of decisions and assumptions in a large, complex project. The larger your project is, the more important it is to have automated checks that make sure nothing has changed!

              +
              +

              To write a unit test that will verify the logic in the TodoItemService, create a new class in your test project:

              +

              AspNetCoreTodo.UnitTests/TodoItemServiceShould.cs

              +
              using System;
              +using System.Threading.Tasks;
              +using AspNetCoreTodo.Data;
              +using AspNetCoreTodo.Models;
              +using AspNetCoreTodo.Services;
              +using Microsoft.EntityFrameworkCore;
              +using Xunit;
              +
              +namespace AspNetCoreTodo.UnitTests
              +{
              +    public class TodoItemServiceShould
              +    {
              +        [Fact]
              +        public async Task AddNewItemAsIncompleteWithDueDate()
              +        {
              +            // ...
              +        }
              +    }
              +}
              +
              +
              +

              There are many different ways of naming and organizing tests, all with different pros and cons. I like postfixing my test classes with Should to create a readable sentence with the test method name, but feel free to use your own style!

              +
              +

              The [Fact] attribute comes from the xUnit.NET package, and it marks this method as a test method.

              +

              The TodoItemService requires an ApplicationDbContext, which is normally connected to your database. You won't want to use that for tests. Instead, you can use Entity Framework Core's in-memory database provider in your test code. Since the entire database exists in memory, it's wiped out every time the test is restarted. And, since it's a proper Entity Framework Core provider, the TodoItemService won't know the difference!

              +

              Use a DbContextOptionsBuilder to configure the in-memory database provider, and then make a call to AddItemAsync():

              +
              var options = new DbContextOptionsBuilder<ApplicationDbContext>()
              +    .UseInMemoryDatabase(databaseName: "Test_AddNewItem").Options;
              +
              +// Set up a context (connection to the "DB") for writing
              +using (var context = new ApplicationDbContext(options))
              +{
              +    var service = new TodoItemService(context);
              +
              +    var fakeUser = new ApplicationUser
              +    {
              +        Id = "fake-000",
              +        UserName = "fake@example.com"
              +    };
              +
              +    await service.AddItemAsync(new TodoItem
              +    {
              +        Title = "Testing?"
              +    }, fakeUser);
              +}
              +
              +

              The last line creates a new to-do item called Testing?, and tells the service to save it to the (in-memory) database.

              +

              To verify that the business logic ran correctly, write some more code below the existing using block:

              +
              // Use a separate context to read data back from the "DB"
              +using (var context = new ApplicationDbContext(options))
              +{
              +    var itemsInDatabase = await context
              +        .Items.CountAsync();
              +    Assert.Equal(1, itemsInDatabase);
              +
              +    var item = await context.Items.FirstAsync();
              +    Assert.Equal("Testing?", item.Title);
              +    Assert.Equal(false, item.IsDone);
              +
              +    // Item should be due 3 days from now (give or take a second)
              +    var difference = DateTimeOffset.Now.AddDays(3) - item.DueAt;
              +    Assert.True(difference < TimeSpan.FromSeconds(1));
              +}
              +
              +

              The first assertion is a sanity check: there should never be more than one item saved to the in-memory database. Assuming that's true, the test retrieves the saved item with FirstAsync and then asserts that the properties are set to the expected values.

              +
              +

              Both unit and integration tests typically follow the AAA (Arrange-Act-Assert) pattern: objects and data are set up first, then some action is performed, and finally the test checks (asserts) that the expected behavior occurred.

              +
              +

              Asserting a datetime value is a little tricky, since comparing two dates for equality will fail if even the millisecond components are different. Instead, the test checks that the DueAt value is less than a second away from the expected value.

              +

              Run the test

              +

              On the terminal, run this command (make sure you're still in the AspNetCoreTodo.UnitTests directory):

              +
              dotnet test
              +

              The test command scans the current project for tests (marked with [Fact] attributes in this case), and runs all the tests it finds. You'll see output similar to:

              +
              Starting test execution, please wait...
              + Discovering: AspNetCoreTodo.UnitTests
              + Discovered:  AspNetCoreTodo.UnitTests
              + Starting:    AspNetCoreTodo.UnitTests
              + Finished:    AspNetCoreTodo.UnitTests
              +
              +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
              +Test Run Successful.
              +Test execution time: 1.9074 Seconds
              +

              You now have one test providing test coverage of the TodoItemService. As an extra challenge, try writing unit tests that ensure:

              +
                +
              • The MarkDoneAsync() method returns false if it's passed an ID that doesn't exist
              • +
              • The MarkDoneAsync() method returns true when it makes a valid item as complete
              • +
              • The GetIncompleteItemsAsync() method returns only the items owned by a particular user
              • +
              + + +
              + +
              +
              +
              + +

              results matching ""

              +
                + +
                +
                + +

                No results matching ""

                + +
                +
                +
                + +
                +
                + +
                + + + + + + + + + + + + + + +
                + + +
                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/conclusion/index.html b/book/chapters/conclusion/index.html new file mode 100644 index 0000000..2c8a241 --- /dev/null +++ b/book/chapters/conclusion/index.html @@ -0,0 +1,835 @@ + + + + + + + 结束语 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                +
                + + + + + + + + +
                + +
                + +
                + + + + + + + + +
                +
                + +
                +
                + +
                + +

                结束语

                +

                感谢你读完了这本简明 ASP.NET Core 手册!如果这本书有点(或者没有)用处,我很乐于倾听您的想法。请在 Twitter 上发表看法:https://twitter.com/nbarbettini

                +

                更深入的学习

                +

                ASP.NET Core 还有很多功能,但是无法纳入到这本小册子里,包括:

                +
                  +
                • 构建 RESTFul 的 API 和 微服务
                • +
                • 把 ASP.NET Core 用于 单页面应用,例如 Angular 和 React
                • +
                • Razor 页面
                • +
                • 打包和压缩静态资源
                • +
                • WebSockets 和 SignalR
                • +
                +

                如果要深入学习,以下这些方式可供参考:

                + +

                祝你代码敲得愉快!

                +

                关于作者

                +

                嗨,我是 Nate!我在一个漫长的灌着咖啡的周末写了这本 简明 ASP.NET Core 手册,因为我热爱 .NET 社区,并希望以我的微薄之力付出回报。希望它帮助你学了一点儿新东西。

                +

                你可以在 Twitter(@nbarbettini)上和我保持联系,或者在我的博客上(https://www.recaffeinate.co)。你还可以通过电子邮件(nate@barbettini.com)联系我。

                +

                特别致谢

                +

                Jennifer,她总是支持我各种疯狂的点子。

                +

                以下这些贡献者,提升了这本书的质量:

                +
                  +
                • 0xNF
                • +
                • Matt Welke [welkie]
                • +
                • Raman Zhylich [zhilich]
                • +
                +

                以下这些很棒的各国程序员,翻译了本书:

                +
                  +
                • sahinyanlik (土耳其语)
                • +
                • windsting、yuyi (简体中文)
                • +
                +

                变更记录

                +

                需要完整、详尽的变更记录,可以到:

                +

                https://github.com/nbarbettini/little-aspnetcore-book/releases

                +

                1.1.1 (2018-06-11): 修正了读者们发现的一些笔误。

                +

                1.1.0 (2018-05-03): 大幅度重写了 添加新特性 一章,深入地使用了整个 MVC 框架并移除了 AJAX 模式。移除 Facebook 登录以简化安全章节、流水线式的测试和部署。修改了 Docker 指令以反映最新的优秀实践。修正了笔误,添加了来自读者的建议。还弄了个新改良的封面得瑟了一下!

                +

                1.0.4 (2018-01-15): 为服务容器(service container)的生命周期添加说明,阐释服务端口和 -o 选项,移除 Razor 指令后的分号。修正中文版译者信息。修正其它笔误和读者反馈的问题。

                +

                1.0.3 (2017-11-13): 笔误修正和一些读者建议的改进。

                +

                1.0.2 (2017-10-20): 更多的Bug修正和一些小改进。添加译版的链接。

                +

                1.0.1 (2017-09-23): Bug修正和一些小改进。

                +

                1.0.0 (2017-09-18): 初次发布。

                +
                +

                Conclusion

                +

                Thanks for making it to the end of the Little ASP.NET Core Book! If this book was helpful (or not), I'd love to hear your thoughts. Send me your comments via Twitter: https://twitter.com/nbarbettini

                +

                How to learn more

                +

                There's a lot more that ASP.NET Core can do that couldn't fit in this short book, including

                +
                  +
                • Building RESTful APIs and microservices
                • +
                • Using ASP.NET Core with single-page apps like Angular and React
                • +
                • Razor Pages
                • +
                • Bundling and minifying static assets
                • +
                • WebSockets and SignalR
                • +
                +

                There are a number of ways you can learn more:

                +
                  +
                • The ASP.NET Core documentation. The official ASP.NET Core documentation at http://docs.asp.net contains a number of in-depth tutorials covering many of these topics. I'd highly recommend it!

                  +
                • +
                • ASP.NET Core in Action. This book by Andrew Lock is a comprehensive, deep dive into ASP.NET Core. You can get it from Amazon or a local bookstore.

                  +
                • +
                • Courses on LinkedIn Learning and Pluralsight. If you learn best from videos, there are fantastic courses available on Pluralsight and LinkedIn Learning (including some by yours truly). If you don't have an account and need a coupon, send me an email: nate@barbettini.com.

                  +
                • +
                • Nate's blog. I also write about ASP.NET Core and more on my blog at https://www.recaffeinate.co.

                  +
                • +
                +

                Happy coding!

                +

                About the author

                +

                Hey, I'm Nate! I wrote the Little ASP.NET Core Book in a long, caffeine-fueled weekend because I love the .NET community and wanted to give back in my own little way. I hope it helped you learn something new!

                +

                You can stay in touch with me on Twitter (@nbarbettini) or on my blog (https://www.recaffeinate.co). You can also reach me via email at nate@barbettini.com.

                +

                Special thanks

                +

                To Jennifer, who always supports my crazy ideas.

                +

                To the following contributors who improved the Little ASP.NET Core Book:

                +
                  +
                • 0xNF
                • +
                • Matt Welke [welkie]
                • +
                • Raman Zhylich [zhilich]
                • +
                +

                To these amazing polyglot programmers who translated the Little ASP.NET Core Book:

                +
                  +
                • sahinyanlik (Turkish)
                • +
                • windsting, yuyi (Simplified Chinese)
                • +
                +

                Changelog

                +

                The full, detailed changelog is always available here:

                +

                https://github.com/nbarbettini/little-aspnetcore-book/releases

                +

                1.1.1 (2018-06-11): Fixed typos found by readers.

                +

                1.1.0 (2018-05-03): Significantly reworked the Add more features chapter to use MVC thorough the whole stack and remove the AJAX pattern. Removed Facebook login to simplify the security chapter and streamline testing and deployment. Updated the Docker instructions to reflect the latest best practices. Fixed typos and added suggestions from readers. The book also sports a new, improved cover design!

                +

                1.0.4 (2018-01-15): Added explanation of service container lifecycles, clarified server ports and the -o flag, and removed semicolons after Razor directives. Corrected Chinese translation author credit. Fixed other small typos and issues noticed by readers.

                +

                1.0.3 (2017-11-13): Typo fixes and small improvements suggested by readers.

                +

                1.0.2 (2017-10-20): More bug fixes and small improvements. Added link to translations.

                +

                1.0.1 (2017-09-23): Bug fixes and small improvements.

                +

                1.0.0 (2017-09-18): Initial release.

                + + +
                + +
                +
                +
                + +

                results matching ""

                +
                  + +
                  +
                  + +

                  No results matching ""

                  + +
                  +
                  +
                  + +
                  +
                  + +
                  + + + + + + + + + + +
                  + + +
                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/deploy-the-application/deploy-to-azure.html b/book/chapters/deploy-the-application/deploy-to-azure.html new file mode 100644 index 0000000..1cbac3e --- /dev/null +++ b/book/chapters/deploy-the-application/deploy-to-azure.html @@ -0,0 +1,849 @@ + + + + + + + 部署到 Azure · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                  +
                  + + + + + + + + +
                  + +
                  + +
                  + + + + + + + + +
                  +
                  + +
                  +
                  + +
                  + +

                  部署到 Azure

                  +

                  把你的 ASP.NET Core 程序部署到 Azure 只需要简单几步。你可以通过 Azure 的网上门户实施,也可以在 Azure CLI 命令行工具里实施。我会讲解后者。

                  +

                  准备材料

                  +
                    +
                  • Git(使用 git --version 命令确认它已经安装了)
                  • +
                  • Azure CLI(按照 https://github.com/Azure/azure-cli 的指示进行安装)
                  • +
                  • 一个 Azure 订阅(免费的订阅就可以了)
                  • +
                  • 项目的根目录里要有一个部署配置文件
                  • +
                  +

                  创建部署配置文件

                  +

                  因为你的目录结构里存在多个项目(Web项目和两个测试项目),Azure 并不知道该把哪个发布出去。为解决这个问题,在你的目录结构顶层创建一个名为 .deployment 的文件:

                  +

                  .deployment

                  +
                  [config]
                  +project = AspNetCoreTodo/AspNetCoreTodo.csproj
                  +
                  +

                  确保你把这个文件保存为 .deployment,而不带有什么其它的零碎儿。(在 Windows 上,你可能需要把文件名用引号括起来,比如 ".deployment",以此避免被添加一个 .txt 扩展名。)

                  +

                  如果你在顶层目录里执行 ls 或者 dir 命令,应该看到如下的内容:

                  +
                  .deployment
                  +AspNetCoreTodo
                  +AspNetCoreTodo.IntegrationTests
                  +AspNetCoreTodo.UnitTests
                  +

                  设置 Azure 资源

                  +

                  如果你的 Azure CLI 才初次安装完成,运行:

                  +
                  az login
                  +

                  并按照提示在你的电脑上登录,然后,为这个程序创建一个新的 资源组(Resource Group):

                  +
                  az group create -l westus -n AspNetCoreTodoGroup
                  +

                  这个命令在美国西部(West US)地区创建了一个资源组。如果你距离美国西部很远,请使用 az account list-locations 命令获取一个地点列表,并找出距离你比较近的一个。

                  +

                  接下来,在你刚刚创建的组里,创建一个 App Service 方案:

                  +
                  az appservice plan create -g AspNetCoreTodoGroup -n AspNetCoreTodoPlan --sku F1
                  +
                  +

                  提示:F1 是免费的 app 方案。如果想在你的应用上使用自己指定的域名,请使用 D1($10/月)或更高级的方案。

                  +
                  +

                  现在,在这个 App Service 方案里创建一个 Web 应用:

                  +
                  az webapp create -g AspNetCoreTodoGroup -p AspNetCoreTodoPlan -n MyTodoApp
                  +

                  这个应用的名称(上面的 MyTodoApp)在 Azure 上必须是全局唯一的。一旦这个应用创建好了,会具有一个以下格式的默认 URL:http://mytodoapp.azurewebsites.net

                  +

                  把项目文件部署到 Azure

                  +

                  你可以用 Git 把程序文件推送到 Azure 网络应用。如果你本地目录尚未作为一个 Git 仓库管理,执行下列命令进行设置:

                  +
                  git init
                  +git add .
                  +git commit -m "First commit!"
                  +

                  接下来,为部署工作创建一个 Azure 用户名和密码,

                  +
                  az webapp deployment user set --user-name nate
                  +

                  按提示创建密码。然后用 config-local-git 得到一个 Git URL:

                  +
                  az webapp deployment source config-local-git -g AspNetCoreTodoGroup -n MyTodoApp --out tsv
                  +
                  +https://nate@mytodoapp.scm.azurewebsites.net/MyTodoApp.git
                  +

                  复制这个 URL 到剪切板,并把它在本地仓库里添加为一个 Git remote:

                  +
                  git remote add azure <粘贴>
                  +

                  你只需要执行这些步骤一次。现在开始,任何时候,你需要推送程序文件到 Azure ,只需要在 Git 里提交它们,然后运行:

                  +
                  git push azure master
                  +

                  程序部署到 Azure 的时候,你会看到一系列的日志信息。

                  +

                  输出结束之后,浏览 http://yourappname.azurewebsites.net 以检验结果。

                  +
                  +

                  Deploy to Azure

                  +

                  Deploying your ASP.NET Core application to Azure only takes a few steps. You can do it through the Azure web portal, or on the command line using the Azure CLI. I'll cover the latter.

                  +

                  What you'll need

                  +
                    +
                  • Git (use git --version to make sure it's installed)
                  • +
                  • The Azure CLI (follow the install instructions at https://github.com/Azure/azure-cli)
                  • +
                  • An Azure subscription (the free subscription is fine)
                  • +
                  • A deployment configuration file in your project root
                  • +
                  +

                  Create a deployment configuration file

                  +

                  Since there are multiple projects in your directory structure (the web application, and two test projects), Azure won't know which one to publish. To fix this, create a file called .deployment at the very top of your directory structure:

                  +

                  .deployment

                  +
                  [config]
                  +project = AspNetCoreTodo/AspNetCoreTodo.csproj
                  +
                  +

                  Make sure you save the file as .deployment with no other parts to the name. (On Windows, you may need to put quotes around the filename, like ".deployment", to prevent a .txt extension from being added.)

                  +

                  If you ls or dir in your top-level directory, you should see these items:

                  +
                  .deployment
                  +AspNetCoreTodo
                  +AspNetCoreTodo.IntegrationTests
                  +AspNetCoreTodo.UnitTests
                  +

                  Set up the Azure resources

                  +

                  If you just installed the Azure CLI for the first time, run

                  +
                  az login
                  +

                  and follow the prompts to log in on your machine. Then, create a new Resource Group for this application:

                  +
                  az group create -l westus -n AspNetCoreTodoGroup
                  +

                  This creates a Resource Group in the West US region. If you're located far away from the western US, use az account list-locations to get a list of locations and find one closer to you.

                  +

                  Next, create an App Service plan in the group you just created:

                  +
                  az appservice plan create -g AspNetCoreTodoGroup -n AspNetCoreTodoPlan --sku F1
                  +
                  +

                  F1 is the free app plan. If you want to use a custom domain name with your app, use the D1 ($10/month) plan or higher.

                  +
                  +

                  Now create a Web App in the App Service plan:

                  +
                  az webapp create -g AspNetCoreTodoGroup -p AspNetCoreTodoPlan -n MyTodoApp
                  +

                  The name of the app (MyTodoApp above) must be globally unique in Azure. Once the app is created, it will have a default URL in the format: http://mytodoapp.azurewebsites.net

                  +

                  Deploy your project files to Azure

                  +

                  You can use Git to push your application files up to the Azure Web App. If your local directory isn't already tracked as a Git repo, run these commands to set it up:

                  +
                  git init
                  +git add .
                  +git commit -m "First commit!"
                  +

                  Next, create an Azure username and password for deployment:

                  +
                  az webapp deployment user set --user-name nate
                  +

                  Follow the instructions to create a password. Then use config-local-git to spit out a Git URL:

                  +
                  az webapp deployment source config-local-git -g AspNetCoreTodoGroup -n MyTodoApp --out tsv
                  +
                  +https://nate@mytodoapp.scm.azurewebsites.net/MyTodoApp.git
                  +

                  Copy the URL to the clipboard, and use it to add a Git remote to your local repository:

                  +
                  git remote add azure <paste>
                  +

                  You only need to do these steps once. Now, whenever you want to push your application files to Azure, check them in with Git and run

                  +
                  git push azure master
                  +

                  You'll see a stream of log messages as the application is deployed to Azure.

                  +

                  When it's complete, browse to http://yourappname.azurewebsites.net to check out the app!

                  + + +
                  + +
                  +
                  +
                  + +

                  results matching ""

                  +
                    + +
                    +
                    + +

                    No results matching ""

                    + +
                    +
                    +
                    + +
                    +
                    + +
                    + + + + + + + + + + + + + + +
                    + + +
                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/deploy-the-application/deploy-with-docker.html b/book/chapters/deploy-the-application/deploy-with-docker.html new file mode 100644 index 0000000..1a1a26c --- /dev/null +++ b/book/chapters/deploy-the-application/deploy-with-docker.html @@ -0,0 +1,966 @@ + + + + + + + 使用 Docker 进行部署 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                    +
                    + + + + + + + + +
                    + +
                    + +
                    + + + + + + + + +
                    +
                    + +
                    +
                    + +
                    + +

                    使用 Docker 进行部署

                    +

                    如果你不使用 Azure 这样的平台,像 Docker 这样的容器化技术能极大地简化把 web 程序部署到你自己服务器上的工作。不再需要浪费时间在一个服务器上配置你程序所需的依赖、复制文件、重启进程,你只需要创建一个 Docker 镜像,里面包含你程序运行所需的一切,然后在任何 Docker 宿主机上作为容器启动起来就行了。

                    +

                    Docker 也便于把你的应用扩展为多个服务器。一旦你创建了一个镜像,用它来创建 1 个容器和 100 个容器所需要的工作是一样的。

                    +

                    开始之前,需要在你的开发机上安装 Docker CLI。搜索 "get docker for (mac/windows/linux)" 并执行 Docker 官网的提示内容。要检验是否安装成功,可以执行:

                    +
                    docker version
                    +

                    添加 Dockerfile

                    +

                    首先需要的就是一个 Dockerfile,它就像个清单,告诉 Docker 你程序的构建和运行需要些什么。

                    +

                    在程序根目录,也就是最外层的 AspNetCoreTodo 文件夹里,创建一个名为 Dockerfile(没有扩展名)的文件。用你常用的编辑器打开它,输入下面这行:

                    +
                    FROM microsoft/dotnet:2.0-sdk AS build
                    +
                    +

                    这指示 Docker 以 microsoft/dotnet:2.0-sdk 为基础创建你的镜像。这个镜像是微软发布的,其中包含了执行 dotnet build 编译程序所需的工具和依赖。以这个预编译镜像为基础,Docker 可以优化镜像生成过程并使它容量紧凑。

                    +

                    接下来,添加这一行:

                    +
                    COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/
                    +
                    +

                    这条 COPY 指令复制 .csproj 项目文件到镜像里的路径 /app/AspNetCoreTodo/ 下。注意实际的代码(.cs 文件)并未复制到镜像里。你稍后即可弄清个中缘由。

                    +
                    WORKDIR /app/AspNetCoreTodo
                    +RUN dotnet restore
                    +
                    +

                    WORKDIR 是 Docker 里的 cd。Dockerfile 中之后的命令都会在这个 /app/AspNetCoreTodo 文件夹内执行,该文件夹是上一步的 COPY 命令创建的。

                    +

                    运行 dotnet restore 命令重建在 .csproj 中定义的那些程序所需的 NuGet 包。在添加其它代码 之前 于镜像中重建这些包,Docker 将有能力缓存这些重建的包。然后,当你修改代码(而没修改项目文件中定义的包)时,重建这个 Docker 镜像将会非常迅速。

                    +

                    现在,就到了复制其余代码并编译程序的时候了:

                    +
                    COPY AspNetCoreTodo/. ./AspNetCoreTodo/
                    +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false"
                    +
                    +

                    dotnet publish 命令编译项目,而 -o out 标识会将结果输出到一个名为 out 的目录里。

                    +

                    这些编译好的文件,将会通过这最终的几条命令,运行起这个程序:

                    +
                    FROM microsoft/dotnet:2.0-runtime AS runtime
                    +ENV ASPNETCORE_URLS http://+:80
                    +WORKDIR /app
                    +COPY --from=build /app/AspNetCoreTodo/out ./
                    +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"]
                    +
                    +

                    FROM 命令再次被用到,以选择一个较小的镜像,其中仅含有运行程序所需的依赖。ENV 命令用于容器中的设置环境变量,环境变量 ASPNETCORE_URLS 指示 ASP.NET Core 应该把服务绑定到哪个网卡和端口上(本例中时 80 端口)。

                    +

                    ENTRYPOINT 命令给 Docker 指出了在被运行的时候去执行 dotnet AspNetCoreTodo.dll。这条命令告诉 dotnet,使用先前由 dotnet publish 编译出来的文件启动你的程序。(当你在开发时运行 dotnet run,它一步就完成了这些事情。)

                    +

                    完整的 Dockerfile 看起来是这样的:

                    +

                    Dockerfile

                    +
                    FROM microsoft/dotnet:2.0-sdk AS build
                    +COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/
                    +WORKDIR /app/AspNetCoreTodo
                    +RUN dotnet restore
                    +
                    +COPY AspNetCoreTodo/. ./
                    +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false"
                    +
                    +FROM microsoft/dotnet:2.0-runtime AS runtime
                    +ENV ASPNETCORE_URLS http://+:80
                    +WORKDIR /app
                    +COPY --from=build /app/AspNetCoreTodo/out ./
                    +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"]
                    +
                    +

                    创建一个镜像

                    +

                    确保 Dockerfile 已经保存好了,然后用 docker build 命令创建一个镜像:

                    +
                    docker build -t aspnetcoretodo .
                    +

                    不要漏掉结尾那个句点!它告诉 Docker 在当前目录下查找 Dockerfile。

                    +

                    一旦镜像创建完成,你可以运行 docker images 命令列出你本地电脑上的全部镜像。要通过容器尝试一下,请执行:

                    +
                    docker run --name aspnetcoretodo_sample --rm -it -p 8080:80 aspnetcoretodo
                    +

                    -it 标识告诉 Docker 以交互模式运行这个容器(输出到终端,而不是在后台运行)。当你想要停止这个容器的时候,按 Control-C

                    +

                    还记得环境变量 ASPNETCORE_URLS 指示 ASP.NET Core 去监听 80 端口吗?这里的 -p 8080:80 选项指示 Docker 把 你的 电脑的 8080 端口映射到 容器的 80端口。打开你的浏览器,浏览地址 http://localhost:8080 去查看运行在容器中的程序。

                    +

                    设置 Nginx

                    +

                    在本章开头,我提到过,你应该使用一个 Nginx 之类的反向代理服务器,把请求代理到 Kestrel 上。这件事也可以用 Docker 来做。

                    +

                    整体架构会包括两个容器:一个 Nginx 容器监听 80 端口,把请求转发到另一个运行着 Kestrel 并监听 5000 端口的容器。

                    +

                    Nginx 容器自己也需要一个 Dockerfile。为避免跟你刚才创建那个 Dockerfile 冲突,在 Web 程序根目录新建一个目录:

                    +
                    mkdir nginx
                    +

                    创建一个新的 Dockerfile 并添加这些行:

                    +

                    nginx/Dockerfile

                    +
                    FROM nginx
                    +COPY nginx.conf /etc/nginx/nginx.conf
                    +
                    +

                    接下来,创建一个 nginx.conf 文件:

                    +

                    nginx/nginx.conf

                    +
                    events { worker_connections 1024; }
                    +
                    +http {
                    +    server {
                    +        listen 80;
                    +        location / {
                    +          proxy_pass http://kestrel:80;
                    +          proxy_http_version 1.1;
                    +          proxy_set_header Upgrade $http_upgrade;
                    +          proxy_set_header Connection 'keep-alive';
                    +          proxy_set_header Host $host;
                    +          proxy_cache_bypass $http_upgrade;
                    +        }
                    +    }
                    +}
                    +

                    这个配置文件告诉 Nginx 把接到的请求转发到 http://kestrel:80。(你马上就会知道为什么要使用 kestrel 作为主机名。)

                    +
                    +

                    当你把程序部署到生产环境,你应该添加 server_name 指令,并验证及限定 host 头字段为一个已知的有效值(known good values)。更多信息请参见:
                    https://github.com/aspnet/Announcements/issues/295

                    +
                    +

                    设置 Docker Compose

                    +

                    还需要创建一个文件,回到 Web 程序的根目录,创建 docker-compose.yml

                    +

                    docker-compose.yml

                    +
                    nginx:
                    +    build: ./nginx
                    +    links:
                    +        - kestrel:kestrel
                    +    ports:
                    +        - "80:80"
                    +kestrel:
                    +    build: .
                    +    ports:
                    +        - "80"
                    +
                    +

                    Docker Compose 是个帮助你创建并运行多容器程序的工具。这个配置文件定义了两个容器: 用 ./nginx/Dockerfile 清单创建 nginx,用 ./Dockerfile 创建 kestrel。这两个容器显式地链接在一起,所以它们可以互相通信。

                    +

                    你可以运行以下指令来启动这个多容器程序:

                    +
                    docker-compose up
                    +

                    打开一个浏览器并导航至 http://localhost(不是 8080!)。Nginx 在 80 (HTTP 的默认)端口上进行监听,并把请求转发到由 Kestrel 托管的 ASP.NET Core 程序。

                    +

                    搭建 Docker 服务器

                    +

                    详尽的设置指令超出了这本书的范畴,但是任何较新的 Linux 发行版(例如 Ubuntu)都可以搭建成一个 Docker 宿主。例如,你可以用亚马逊 EC2 创建一个虚拟机,在上面安装 Docker 服务,为此你可以搜索 “amazon ec2 set up docker” 以获取说明。

                    +

                    我更喜欢用 DigitalOcean,因为他们把入门的门槛降得非常低。DigitalOcean 既有现成的 Docker 虚拟机,也有关于搭建和运行 Docker 的深度教程(请搜索“digitalocean docker”)。

                    +
                    +

                    Deploy with Docker

                    +

                    If you aren't using a platform like Azure, containerization technologies like Docker can make it easy to deploy web applications to your own servers. Instead of spending time configuring a server with the dependencies it needs to run your app, copying files, and restarting processes, you can simply create a Docker image that describes everything your app needs to run, and spin it up as a container on any Docker host.

                    +

                    Docker can make scaling your app across multiple servers easier, too. Once you have an image, using it to create 1 container is the same process as creating 100 containers.

                    +

                    Before you start, you need the Docker CLI installed on your development machine. Search for "get docker for (mac/windows/linux)" and follow the instructions on the official Docker website. You can verify that it's installed correctly with

                    +
                    docker version
                    +

                    Add a Dockerfile

                    +

                    The first thing you'll need is a Dockerfile, which is like a recipe that tells Docker what your application needs to build and run.

                    +

                    Create a file called Dockerfile (no extension) in the root, top-level AspNetCoreTodo folder. Open it in your favorite editor. Write the following line:

                    +
                    FROM microsoft/dotnet:2.0-sdk AS build
                    +
                    +

                    This tells Docker to use the microsoft/dotnet:2.0-sdk image as a starting point. This image is published by Microsoft and contains the tools and dependencies you need to execute dotnet build and compile your application. By using this pre-built image as a starting point, Docker can optimize the image produced for your app and keep it small.

                    +

                    Next, add this line:

                    +
                    COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/
                    +
                    +

                    The COPY command copies the .csproj project file into the image at the path /app/AspNetCoreTodo/. Note that none of the actual code (.cs files) have been copied into the image yet. You'll see why in a minute.

                    +
                    WORKDIR /app/AspNetCoreTodo
                    +RUN dotnet restore
                    +
                    +

                    WORKDIR is the Docker equivalent of cd. This means any commands executed next will run from inside the /app/AspNetCoreTodo directory that the COPY command created in the last step.

                    +

                    Running the dotnet restore command restores the NuGet packages that the application needs, defined in the .csproj file. By restoring packages inside the image before adding the rest of the code, Docker is able to cache the restored packages. Then, if you make code changes (but don't change the packages defined in the project file), rebuilding the Docker image will be super fast.

                    +

                    Now it's time to copy the rest of the code and compile the application:

                    +
                    COPY AspNetCoreTodo/. ./AspNetCoreTodo/
                    +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false"
                    +
                    +

                    The dotnet publish command compiles the project, and the -o out flag puts the compiled files in a directory called out.

                    +

                    These compiled files will be used to run the application with the final few commands:

                    +
                    FROM microsoft/dotnet:2.0-runtime AS runtime
                    +ENV ASPNETCORE_URLS http://+:80
                    +WORKDIR /app
                    +COPY --from=build /app/AspNetCoreTodo/out ./
                    +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"]
                    +
                    +

                    The FROM command is used again to select a smaller image that only has the dependencies needed to run the application. The ENV command is used to set environment variables in the container, and the ASPNETCORE_URLS environment variable tells ASP.NET Core which network interface and port it should bind to (in this case, port 80).

                    +

                    The ENTRYPOINT command lets Docker know that the container should be started as an executable by running dotnet AspNetCoreTodo.dll. This tells dotnet to start up your application from the compiled file created by dotnet publish earlier. (When you do dotnet run during development, you're accomplishing the same thing in one step.)

                    +

                    The full Dockerfile looks like this:

                    +

                    Dockerfile

                    +
                    FROM microsoft/dotnet:2.0-sdk AS build
                    +COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/
                    +WORKDIR /app/AspNetCoreTodo
                    +RUN dotnet restore
                    +
                    +COPY AspNetCoreTodo/. ./
                    +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false"
                    +
                    +FROM microsoft/dotnet:2.0-runtime AS runtime
                    +ENV ASPNETCORE_URLS http://+:80
                    +WORKDIR /app
                    +COPY --from=build /app/AspNetCoreTodo/out ./
                    +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"]
                    +
                    +

                    Create an image

                    +

                    Make sure the Dockerfile is saved, and then use docker build to create an image:

                    +
                    docker build -t aspnetcoretodo .
                    +

                    Don't miss the trailing period! That tells Docker to look for a Dockerfile in the current directory.

                    +

                    Once the image is created, you can run docker images to to list all the images available on your local machine. To test it out in a container, run

                    +
                    docker run --name aspnetcoretodo_sample --rm -it -p 8080:80 aspnetcoretodo
                    +

                    The -it flag tells Docker to run the container in interactive mode (outputting to the terminal, as opposed to running in the background). When you want to stop the container, press Control-C.

                    +

                    Remember the ASPNETCORE_URLS variable that told ASP.NET Core to listen on port 80? The -p 8080:80 option tells Docker to map port 8080 on your machine to the container's port 80. Open up your browser and navigate to http://localhost:8080 to see the application running in the container!

                    +

                    Set up Nginx

                    +

                    At the beginning of this chapter, I mentioned that you should use a reverse proxy like Nginx to proxy requests to Kestrel. You can use Docker for this, too.

                    +

                    The overall architecture will consist of two containers: an Nginx container listening on port 80, forwarding requests to the container you just built that hosts your application with Kestrel.

                    +

                    The Nginx container needs its own Dockerfile. To keep it from conflicting with the Dockerfile you just created, make a new directory in the web application root:

                    +
                    mkdir nginx
                    +

                    Create a new Dockerfile and add these lines:

                    +

                    nginx/Dockerfile

                    +
                    FROM nginx
                    +COPY nginx.conf /etc/nginx/nginx.conf
                    +
                    +

                    Next, create an nginx.conf file:

                    +

                    nginx/nginx.conf

                    +
                    events { worker_connections 1024; }
                    +
                    +http {
                    +    server {
                    +        listen 80;
                    +        location / {
                    +          proxy_pass http://kestrel:80;
                    +          proxy_http_version 1.1;
                    +          proxy_set_header Upgrade $http_upgrade;
                    +          proxy_set_header Connection 'keep-alive';
                    +          proxy_set_header Host $host;
                    +          proxy_cache_bypass $http_upgrade;
                    +        }
                    +    }
                    +}
                    +

                    This configuration file tells Nginx to proxy incoming requests to http://kestrel:80. (You'll see why kestrel works as a hostname in a moment.)

                    +
                    +

                    When you make deploy your application to a production environment, you should add the server_name directive and validate and restrict the host header to known good values. For more information, see:

                    +

                    https://github.com/aspnet/Announcements/issues/295

                    +
                    +

                    Set up Docker Compose

                    +

                    There's one more file to create. Up in the root directory, create docker-compose.yml:

                    +

                    docker-compose.yml

                    +
                    nginx:
                    +    build: ./nginx
                    +    links:
                    +        - kestrel:kestrel
                    +    ports:
                    +        - "80:80"
                    +kestrel:
                    +    build: .
                    +    ports:
                    +        - "80"
                    +
                    +

                    Docker Compose is a tool that helps you create and run multi-container applications. This configuration file defines two containers: nginx from the ./nginx/Dockerfile recipe, and kestrel from the ./Dockerfile recipe. The containers are explicitly linked together so they can communicate.

                    +

                    You can try spinning up the entire multi-container application by running:

                    +
                    docker-compose up
                    +

                    Try opening a browser and navigating to http://localhost (port 80, not 8080!). Nginx is listening on port 80 (the default HTTP port) and proxying requests to your ASP.NET Core application hosted by Kestrel.

                    +

                    Set up a Docker server

                    +

                    Specific setup instructions are outside the scope of this book, but any modern flavor of Linux (like Ubuntu) can be used to set up a Docker host. For example, you could create a virtual machine with Amazon EC2, and install the Docker service. You can search for "amazon ec2 set up docker" (for example) for instructions.

                    +

                    I like using DigitalOcean because they've made it really easy to get started. DigitalOcean has both a pre-built Docker virtual machine, and in-depth tutorials for getting Docker up and running (search for "digitalocean docker").

                    + + +
                    + +
                    +
                    +
                    + +

                    results matching ""

                    +
                      + +
                      +
                      + +

                      No results matching ""

                      + +
                      +
                      +
                      + +
                      +
                      + +
                      + + + + + + + + + + + + + + +
                      + + +
                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/deploy-the-application/index.html b/book/chapters/deploy-the-application/index.html new file mode 100644 index 0000000..8ff607e --- /dev/null +++ b/book/chapters/deploy-the-application/index.html @@ -0,0 +1,789 @@ + + + + + + + 部署程序 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                      +
                      + + + + + + + + +
                      + +
                      + +
                      + + + + + + + + +
                      +
                      + +
                      +
                      + +
                      + +

                      部署程序

                      +

                      万事俱备,只欠东风。当一个良好的程序构建完成,就应该与全世界分享它了。

                      +

                      因为 ASP.NET Core 程序能够运行在 Windows、Mac 以及 Linux 上,你拥有多种部署程序的方式。这一章里,我将教给你最常用(也是最简单)的上线方式。

                      +

                      部署方式

                      +

                      ASP.NET Core 通常会部署到下列环境之一:

                      +
                        +
                      • 一部 Dockers 主机 任何有能力托管 Docker 容器的机器都能用来托管 ASP.NET Core 程序。创建 Docker 镜像是个非常快捷的部署程序的方式,尤其是在你熟悉 Docker 的情况下。(如果你还不熟悉,别担心!我会在后面逐步介绍。)

                        +
                      • +
                      • Azure 微软的 Azure 对 ASP.NET Core 程序提供原生的支持。如果你有一个 Azure 订阅,你只要创建一个 Web App 并上传你的项目文件即可。下一节,我会介绍通过 Azure CLI 完成这种操作。

                        +
                      • +
                      • Linux (连同 Nginx) 如果你不想用 Docker 那个方式,依然可以在任意 Linux 服务器(这包括亚马逊的 EC2 和 DigitalOcean 虚拟机)上托管程序。通常把 ASP.NET Core 跟 Nginx 反向代理配对工作。(下面有更详细的 Nginx 相关内容。)

                        +
                      • +
                      • Winddows 你可以在 Windows 上使用 IIS 网络服务器托管 ASP.NET Core 程序。一般来说,部署到 Azure 更容易(也更便宜),不过你要是愿意自己管理 Windows 服务器,这也是个可行的方案。

                        +
                      • +
                      +

                      Kestrel 和 反向代理

                      +
                      +

                      如果你不在意 ASP.NET Core 程序托管工作的细节,而只希望参考分步的指导,可以跳转到后续两小节的任一个继续阅读。

                      +
                      +

                      ASP.NET Core 里包含一个名为 Kestrel 的快速轻量级的 web 开发服务器。你每次运行 dotnet run 并浏览 http://localhost:5000 的时候,用的就是这个服务器。当你把程序部署到生产环境的时候,它仍会在幕后使用 Kestrel。但强烈建议你在 Kestrel 之前添加一个反向代理,因为 Kestrel 并不具有负载均衡和其它更成熟的 Web 服务器所具有的其它特性。

                      +

                      在 Linux(和 Docker 容器)里,你可以用 Nginx 或者 Apache web 服务器接收从互联网上传入的请求,并派发到你用 Kestrel 托管的程序。如果你用的是 Windows,IIS 也能处理这个工作。

                      +

                      如果你把程序托管在 Azure,这些就都是自动为你处理的。在 Docker 那一节,我会讲述如何配置 Nginx 进行反向代理。

                      +
                      +

                      Deploy the application

                      +

                      You've come a long way, but you're not quite done yet. Once you've created a great application, you need to share it with the world!

                      +

                      Because ASP.NET Core applications can run on Windows, Mac, or Linux, there are a number of different ways you can deploy your application. In this chapter, I'll show you the most common (and easiest) ways to go live.

                      +

                      Deployment options

                      +

                      ASP.NET Core applications are typically deployed to one of these environments:

                      +
                        +
                      • A Docker host. Any machine capable of hosting Docker containers can be used to host an ASP.NET Core application. Creating a Docker image is a very quick way to get your application deployed, especially if you're familiar with Docker. (If you're not, don't worry! I'll cover the steps later.)

                        +
                      • +
                      • Azure. Microsoft Azure has native support for ASP.NET Core applications. If you have an Azure subscription, you just need to create a Web App and upload your project files. I'll cover how to do this with the Azure CLI in the next section.

                        +
                      • +
                      • Linux (with Nginx). If you don't want to go the Docker route, you can still host your application on any Linux server (this includes Amazon EC2 and DigitalOcean virtual machines). It's typical to pair ASP.NET Core with the Nginx reverse proxy. (More about Nginx below.)

                        +
                      • +
                      • Windows. You can use the IIS web server on Windows to host ASP.NET Core applications. It's usually easier (and cheaper) to just deploy to Azure, but if you prefer managing Windows servers yourself, it'll work just fine.

                        +
                      • +
                      +

                      Kestrel and reverse proxies

                      +
                      +

                      If you don't care about the guts of hosting ASP.NET Core applications and just want the step-by-step instructions, feel free to skip to one of the next two sections.

                      +
                      +

                      ASP.NET Core includes a fast, lightweight web server called Kestrel. It's the server you've been using every time you ran dotnet run and browsed to http://localhost:5000. When you deploy your application to a production environment, it'll still use Kestrel behind the scenes. However, it's recommended that you put a reverse proxy in front of Kestrel, because Kestrel doesn't yet have load balancing and other features that more mature web servers have.

                      +

                      On Linux (and in Docker containers), you can use Nginx or the Apache web server to receive incoming requests from the internet and route them to your application hosted with Kestrel. If you're on Windows, IIS does the same thing.

                      +

                      If you're using Azure to host your application, this is all done for you automatically. I'll cover setting up Nginx as a reverse proxy in the Docker section.

                      + + +
                      + +
                      +
                      +
                      + +

                      results matching ""

                      +
                        + +
                        +
                        + +

                        No results matching ""

                        + +
                        +
                        +
                        + +
                        +
                        + +
                        + + + + + + + + + + + + + + +
                        + + +
                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/add-service-class.html b/book/chapters/mvc-basics/add-service-class.html new file mode 100644 index 0000000..40ce1c4 --- /dev/null +++ b/book/chapters/mvc-basics/add-service-class.html @@ -0,0 +1,891 @@ + + + + + + + 添加一个服务类 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                        +
                        + + + + + + + + +
                        + +
                        + +
                        + + + + + + + + +
                        +
                        + +
                        +
                        + +
                        + +

                        添加一个服务类

                        +

                        你已经创建了一个模型、一个视图、一个控制器。在你把模型和视图应用于控制器中之前,需要先写点代码,用它把用户的待办事项条目从数据库里取出来。

                        +

                        你可以在直接在控制器里编写这段数据库相关的代码,但是作为更良好的实践,应该保持你的代码独立。为什么呢?在一个巨大的,现实世界的程序里,你不得不应付一些事情:

                        +
                          +
                        • 渲染视图 并处理接收的数据:你的控制器已经处理好了。
                        • +
                        • 执行业务逻辑,或者说跟你程序的目标和“业务”相关联的代码与逻辑。在一个待办事项列表程序里,业务逻辑意味着“为新任务设置一个默认的截止时间”,或者“仅显示未完成的任务”这些决策。业务逻辑的其它例子,包括“基于产品价格和税率计算总价”,或者“在游戏里检查一个玩家是否有足够的经验值升级”。
                        • +
                        • 存入和取出数据库中的数据。
                        • +
                        +

                        还是那句话,把所有这些东西写进一个单独的巨大的控制器是可行的,但这很快就会变得难以管理和测试。相反,常见的程序都把这些分割成两个、三个或更多的“层”或级,每个层级处理(且仅处理)一件事情。这有助于保持控制器尽量简单,并简化测试工作,以及后续的业务逻辑和数据库代码的修改。

                        +

                        把程序以这种方式分割,有时被称为 多级 或者 n级架构。在某些情况下,这些层级被隔离在完全分离的项目中,也有时候这仅仅意味着各个类之间组织和调用的方式。重点在于考量如何把你的程序分割成多个可管理的部分,以避免控制器或者某些臃肿的类试图去处理所有事情。

                        +

                        对当前这个项目而言,你将把程序分为两个层:一个由控制器和视图构成的 表示层,用来处理用户的交互,和一个包含了业务逻辑和数据库代码的 服务层。表示层已经有了,所以,接下来就应该构建一个服务,用来处理 待办事项 的业务逻辑,并把待办事项条目保存到数据库里去。

                        +
                        +

                        多数较大的项目使用一种 3级 架构:一个表示层,一个逻辑服务层,一个数据仓储层。仓储(repository) 是一个仅关注数据库操作(不处理业务逻辑)的类。咱们眼下的程序里,为简化操作,我们将把这些混进一个服务层里,不过你尽可尝试采用不同的方式去架构你的代码。

                        +
                        +

                        创建一个接口

                        +

                        C# 编程语言里有一个概念叫 接口(interface),在接口中,一个对象中方法和属性的定义与实际包含这些方法和属性的类分离开来。接口有助于解耦你的那些类,也有助于测试,如你接下来(以及在后续的 自动化测试 章节中)所见。你将用一个接口来表示一个服务,该服务负责就待办事项条目事宜与数据库交互。

                        +

                        习惯上,接口以大写字母“I”开头,在 Services 目录下新建一个文件:

                        +

                        Services/ITodoItemService.cs

                        +
                        using System;
                        +using System.Collections.Generic;
                        +using System.Threading.Tasks;
                        +using AspNetCoreTodo.Models;
                        +
                        +namespace AspNetCoreTodo.Services
                        +{
                        +    public interface ITodoItemService
                        +    {
                        +        Task<TodoItem[]> GetIncompleteItemsAsync();
                        +    }
                        +}
                        +
                        +

                        注意一下,这个文件的命名空间是 AspNetCoreTodo.Services。命名空间是一种组织 .NET 代码文件的方式,一般与存放该文件的目录名保持一致(Services目录下的文件,命名空间是AspNetCoreTodo.Services,以此类推)。

                        +

                        因为这个文件(在命名空间AspNetCoreTodo.Services中)引用了 TodoItem 类(在命名空间 AspNetCoreTodo.Models中),它需要在文件顶部包含一条 using 语句,引入那个命名空间。如果不写这个 using 语句,你会看到这样的报错:

                        +
                        The type or namespace name 'TodoItem' could not be found (are you missing a using directive or an assembly reference?)
                        +
                        +

                        因为这是一个接口,所以不包含任何实现相关的代码,只有 GetIncompleteItemsAsync 方法的定义(或者叫 方法签名(method signature))。该方法不需要任何参数,并且返回一个 Task<TodoItem[]>

                        +
                        +

                        如果这种语法让你看上去感到困惑,就这么理解:“一个 Task 里面装着一个 TodoItem 的数组”。

                        +
                        +

                        Task 类型类似于一个 future 或者 promise1,这里使用它的原因是,这将是个 异步的(asynchronous) 方法。换句话说,这个方法可能不会即时返回待办事项的列表,因为它需要先查询数据库。(详情见后续章节。)

                        +

                        创建服务类

                        +

                        现在接口已经定义好,你可开始创建具体的服务类了。在后续的 使用数据库 那章,我会深入讲解有关数据库的代码,但目前你可以造个假,直接返回硬编码的值:

                        +

                        Services/FakeTodoItemService.cs

                        +
                        using System;
                        +using System.Collections.Generic;
                        +using System.Threading.Tasks;
                        +using AspNetCoreTodo.Models;
                        +
                        +namespace AspNetCoreTodo.Services
                        +{
                        +    public class FakeTodoItemService : ITodoItemService
                        +    {
                        +        public Task<TodoItem[]> GetIncompleteItemsAsync()
                        +        {
                        +            var item1 = new TodoItem
                        +            {
                        +                Title = "Learn ASP.NET Core",
                        +                DueAt = DateTimeOffset.Now.AddDays(1)
                        +            };
                        +
                        +            var item2 = new TodoItem
                        +            {
                        +                Title = "Build awesome apps",
                        +                DueAt = DateTimeOffset.Now.AddDays(2)
                        +            };
                        +
                        +            return Task.FromResult(new[] { item1, item2 });
                        +        }
                        +    }
                        +}
                        +
                        +

                        FakeTodoItemService 实现了 ITodoItemService 接口,但总是返回这个包含两个 TodoItem 的数组。你可以用它去测试控制器和视图,然后在 使用数据库 那章添加真正的代码去访问数据库。

                        +
                        +1. 译者注:二者都是其它语言中,与异步编程相关的概念,它们是用于指代某个尚未就绪的值的对象。而这个值,往往是某个计算过程的结果。要了解详细,请参考 https://en.wikipedia.org/wiki/Futures_and_promises +
                        +
                        +

                        Add a service class

                        +

                        You've created a model, a view, and a controller. Before you use the model and view in the controller, you also need to write code that will get the user's to-do items from a database.

                        +

                        You could write this database code directly in the controller, but it's a better practice to keep your code separate. Why? In a big, real-world application, you'll have to juggle many concerns:

                        +
                          +
                        • Rendering views and handling incoming data: this is what your controller already does.
                        • +
                        • Performing business logic, or code and logic that's related to the purpose and "business" of your application. In a to-do list application, business logic means decisions like setting a default due date on new tasks, or only displaying tasks that are incomplete. Other examples of business logic include calculating a total cost based on product prices and tax rates, or checking whether a player has enough points to level up in a game.
                        • +
                        • Saving and retrieving items from a database.
                        • +
                        +

                        Again, it's possible to do all of these things in a single, massive controller, but that quickly becomes too hard to manage and test. Instead, it's common to see applications split up into two, three, or more "layers" or tiers that each handle one (and only one) concern. This helps keep the controllers as simple as possible, and makes it easier to test and change the business logic and database code later.

                        +

                        Separating your application this way is sometimes called a multi-tier or n-tier architecture. In some cases, the tiers (layers) are isolated in completely separate projects, but other times it just refers to how the classes are organized and used. The important thing is thinking about how to split your application into manageable pieces, and avoid having controllers or bloated classes that try to do everything.

                        +

                        For this project, you'll use two application layers: a presentation layer made up of the controllers and views that interact with the user, and a service layer that contains business logic and database code. The presentation layer already exists, so the next step is to build a service that handles to-do business logic and saves to-do items to a database.

                        +
                        +

                        Most larger projects use a 3-tier architecture: a presentation layer, a service logic layer, and a data repository layer. A repository is a class that's only focused on database code (no business logic). In this application, you'll combine these into a single service layer for simplicity, but feel free to experiment with different ways of architecting the code.

                        +
                        +

                        Create an interface

                        +

                        The C# language includes the concept of interfaces, where the definition of an object's methods and properties is separate from the class that actually contains the code for those methods and properties. Interfaces make it easy to keep your classes decoupled and easy to test, as you'll see here (and later in the Automated testing chapter). You'll use an interface to represent the service that can interact with to-do items in the database.

                        +

                        By convention, interfaces are prefixed with "I". Create a new file in the Services directory:

                        +

                        Services/ITodoItemService.cs

                        +
                        using System;
                        +using System.Collections.Generic;
                        +using System.Threading.Tasks;
                        +using AspNetCoreTodo.Models;
                        +
                        +namespace AspNetCoreTodo.Services
                        +{
                        +    public interface ITodoItemService
                        +    {
                        +        Task<TodoItem[]> GetIncompleteItemsAsync();
                        +    }
                        +}
                        +
                        +

                        Note that the namespace of this file is AspNetCoreTodo.Services. Namespaces are a way to organize .NET code files, and it's customary for the namespace to follow the directory the file is stored in (AspNetCoreTodo.Services for files in the Services directory, and so on).

                        +

                        Because this file (in the AspNetCoreTodo.Services namespace) references the TodoItem class (in the AspNetCoreTodo.Models namespace), it needs to include a using statement at the top of the file to import that namespace. Without the using statement, you'll see an error like:

                        +
                        The type or namespace name 'TodoItem' could not be found (are you missing a using directive or an assembly reference?)
                        +

                        Since this is an interface, there isn't any actual code here, just the definition (or method signature) of the GetIncompleteItemsAsync method. This method requires no parameters and returns a Task<TodoItem[]>.

                        +
                        +

                        If this syntax looks confusing, think: "a Task that contains an array of TodoItems".

                        +
                        +

                        The Task type is similar to a future or a promise, and it's used here because this method will be asynchronous. In other words, the method may not be able to return the list of to-do items right away because it needs to go talk to the database first. (More on this later.)

                        +

                        Create the service class

                        +

                        Now that the interface is defined, you're ready to create the actual service class. I'll cover database code in depth in the Use a database chapter, so for now you'll just fake it and always return two hard-coded items:

                        +

                        Services/FakeTodoItemService.cs

                        +
                        using System;
                        +using System.Collections.Generic;
                        +using System.Threading.Tasks;
                        +using AspNetCoreTodo.Models;
                        +
                        +namespace AspNetCoreTodo.Services
                        +{
                        +    public class FakeTodoItemService : ITodoItemService
                        +    {
                        +        public Task<TodoItem[]> GetIncompleteItemsAsync()
                        +        {
                        +            var item1 = new TodoItem
                        +            {
                        +                Title = "Learn ASP.NET Core",
                        +                DueAt = DateTimeOffset.Now.AddDays(1)
                        +            };
                        +
                        +            var item2 = new TodoItem
                        +            {
                        +                Title = "Build awesome apps",
                        +                DueAt = DateTimeOffset.Now.AddDays(2)
                        +            };
                        +
                        +            return Task.FromResult(new[] { item1, item2 });
                        +        }
                        +    }
                        +}
                        +
                        +

                        This FakeTodoItemService implements the ITodoItemService interface but always returns the same array of two TodoItems. You'll use this to test the controller and view, and then add real database code in Use a database.

                        + + +
                        + +
                        +
                        +
                        + +

                        results matching ""

                        +
                          + +
                          +
                          + +

                          No results matching ""

                          + +
                          +
                          +
                          + +
                          +
                          + +
                          + + + + + + + + + + + + + + +
                          + + +
                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/create-controller.html b/book/chapters/mvc-basics/create-controller.html new file mode 100644 index 0000000..02f89ac --- /dev/null +++ b/book/chapters/mvc-basics/create-controller.html @@ -0,0 +1,824 @@ + + + + + + + 创建控制器 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                          +
                          + + + + + + + + +
                          + +
                          + +
                          + + + + + + + + +
                          +
                          + +
                          +
                          + +
                          + +

                          创建控制器

                          +

                          在项目的 Controllers 目录里,已经预置了几个控制器,其中有渲染默认欢迎页的 HomeController,就是你访问 http://localhost:5000 看到的那个页面。暂时不用管这些控制器。

                          +

                          给待办清单功能创建一个新的控制器,取名叫 TodoController ,并添加如下代码:

                          +

                          Controllers/TodoController.cs

                          +
                          using System;
                          +using System.Collections.Generic;
                          +using System.Linq;
                          +using System.Threading.Tasks;
                          +using Microsoft.AspNetCore.Mvc;
                          +
                          +namespace AspNetCoreTodo.Controllers
                          +{
                          +    public class TodoController : Controller
                          +    {
                          +        // 在这里添加 Actions
                          +    }
                          +}
                          +
                          +

                          由控制器本身处理的路由叫 action ,在控制器类里用方法表示。比如,HomeController 包含三个 action 方法(IndexAbout,和 Contact),由 ASP.NET Core 分别映射到如下的 URL:

                          +
                          localhost:5000/Home         -> Index()
                          +localhost:5000/Home/About   -> About()
                          +localhost:5000/Home/Contact -> Contact()
                          +
                          +

                          ASP.NET Core 中有几个惯例(常见的模式),比如这个 FooController 映射到 /Foo 的模式,还有 Index 的 action名 可以在 URL 里省略。如果你有需要,可以自定义这些行为,不过就目前的情况,让我们暂且遵循这些惯例。

                          +

                          TodoController 里,添加一个名为 Index 的 action,把那句 // Actions go here 注释替换掉:

                          +
                          public class TodoController : Controller
                          +{
                          +    public IActionResult Index()
                          +    {
                          +        // 从数据库获取 to-do 条目
                          +
                          +        // 把条目置于 model 中
                          +
                          +        // 使用 model 渲染视图
                          +    }
                          +}
                          +
                          +

                          一个 action 方法可以返回视图、JSON数据,或者 200 OK404 Not Found 之类的状态码。返回类型 IActionResult 给了你足够的灵活性,以返回上面提到的任意一个。

                          +

                          使控制器尽可能保持轻量化,是一个良好的习惯。在当前的情形里,这个控制器应该仅仅完成这些事情:从数据库取出待办事项的记录,把这些事项包装在一个可用于视图的模型中,并把这个视图发送到用户的浏览器。

                          +

                          继续编码这个控制器之前,你需要创建 模型 和 视图。

                          +
                          +

                          Create a controller

                          +

                          There are already a few controllers in the project's Controllers directory, including the HomeController that renders the default welcome screen you see when you visit http://localhost:5000. You can ignore these controllers for now.

                          +

                          Create a new controller for the to-do list functionality, called TodoController, and add the following code:

                          +

                          Controllers/TodoController.cs

                          +
                          using System;
                          +using System.Collections.Generic;
                          +using System.Linq;
                          +using System.Threading.Tasks;
                          +using Microsoft.AspNetCore.Mvc;
                          +
                          +namespace AspNetCoreTodo.Controllers
                          +{
                          +    public class TodoController : Controller
                          +    {
                          +        // Actions go here
                          +    }
                          +}
                          +
                          +

                          Routes that are handled by controllers are called actions, and are represented by methods in the controller class. For example, the HomeController includes three action methods (Index, About, and Contact) which are mapped by ASP.NET Core to these route URLs:

                          +
                          localhost:5000/Home         -> Index()
                          +localhost:5000/Home/About   -> About()
                          +localhost:5000/Home/Contact -> Contact()
                          +

                          There are a number of conventions (common patterns) used by ASP.NET Core, such as the pattern that FooController becomes /Foo, and the Index action name can be left out of the URL. You can customize this behavior if you'd like, but for now, we'll stick to the default conventions.

                          +

                          Add a new action called Index to the TodoController, replacing the // Actions go here comment:

                          +
                          public class TodoController : Controller
                          +{
                          +    public IActionResult Index()
                          +    {
                          +        // Get to-do items from database
                          +
                          +        // Put items into a model
                          +
                          +        // Render view using the model
                          +    }
                          +}
                          +
                          +

                          Action methods can return views, JSON data, or HTTP status codes like 200 OK and 404 Not Found. The IActionResult return type gives you the flexibility to return any of these from the action.

                          +

                          It's a best practice to keep controllers as lightweight as possible. In this case, the controller will be responsible for getting the to-do items from the database, putting those items into a model the view can understand, and sending the view back to the user's browser.

                          +

                          Before you can write the rest of the controller code, you need to create a model and a view.

                          + + +
                          + +
                          +
                          +
                          + +

                          results matching ""

                          +
                            + +
                            +
                            + +

                            No results matching ""

                            + +
                            +
                            +
                            + +
                            +
                            + +
                            + + + + + + + + + + + + + + +
                            + + +
                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/create-models.html b/book/chapters/mvc-basics/create-models.html new file mode 100644 index 0000000..3c13431 --- /dev/null +++ b/book/chapters/mvc-basics/create-models.html @@ -0,0 +1,848 @@ + + + + + + + 创建模型 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                            +
                            + + + + + + + + +
                            + +
                            + +
                            + + + + + + + + +
                            +
                            + +
                            +
                            + +
                            + +

                            创建模型

                            +

                            我们需要创建两个独立的模型类:一个模型表示保存在数据库里的条目(有时候也称为一个 记录(entity)),另一个模型将与视图结合(MVC里的 MV)发送到用户的浏览器。因为他们都可以被称为模型,我将称后者为 视图模型(view model)

                            +

                            首先,在 Models 目录下,创建一个名为 TodoItem 的类:

                            +

                            Models/TodoItem.cs

                            +
                            using System;
                            +
                            +namespace AspNetCoreTodo.Models
                            +{
                            +    public class TodoItem
                            +    {
                            +        public Guid Id { get; set; }
                            +
                            +        public bool IsDone { get; set; }
                            +
                            +        [Required]
                            +        public string Title { get; set; }
                            +
                            +        public DateTimeOffset? DueAt { get; set; }
                            +    }
                            +}
                            +
                            +

                            这个类定义了每个待办事项都要保存的内容:一个 ID、一个标题或者名称、该事项是否已经完成,以及截至日期是什么时候。每行定义了这个类的一个属性:

                            +
                              +
                            • Id 属性是一个 guid,或者说是 全局(globally) 唯一(unique) 标识符(identifier). Guid(或者GUID)是一个由字母和数字组成的长长的字符串,看起来是这样的 43ec09f2-7f70-4f4b-9559-65011d5781bb。因为 guid 是随机的,并极少会有重复值,所以常被用作唯一标识。你也可以用数字(整形 integer)作为数据库记录的标识,但你需要在数据库里配置,以便这个数字在添加新条目的时候始终增长。因为 Guid 是随机生产的,所以就你不必再担心这个 自增 的问题了。

                              +
                            • +
                            • IsDone 属性是一个 布尔值(值为 true/false)。默认情况下,所有新建条目的该值为 false。你后面会编写代码,在用户在视图里点击某个条目的复选框时,修改这个属性为 true

                              +
                            • +
                            • Title 属性是一个字符串,用于保存待办事项的名称或者简述。

                              +
                            • +
                            • DueAt 属性是一个 DateTimeOffset,C# 用于这种类型保存一个 日期/时间 的戳记和一个与 UTC 偏移量表示的时区。把时期、时间和时区一起保存,有助于在不同时区的系统上准确地显示时间。

                              +
                            • +
                            +

                            看到 DateTimeOffset 类型后面那个问号 ? 了吗?它表示 DueAt 属性 可空(nullable),或者说是可选的。如果不加这个 ?,每个待办事项都必须带有一个截止日期。IdIsDone 属性没有标记为可空,所以是必须的,并可以确保始终有值(或者是一个缺省值)。

                            +
                            +

                            C#里的字符串总是可空的,所以没必要给 Title 属性添加可空标记。C# 字符串可以没有值,也可以是空白字符串或者包含任意文本。

                            +
                            +

                            每个属性后面都跟着 get; set; ,这是个简写,表示该属性 可读/可写(read/write)(或者,更确切地说,它有 getter 和 setter 方法各一个)。

                            +

                            现在,暂且不必关心底层数据库采用的是哪种实现。它可以是 SQL Server,MySQL,MongoDB,Redis,或者什么其它稀奇古怪的玩意儿。这个模型定义了数据库里的行或者记录在 C# 里看起来是什么样的,所以你无须在代码层面担心数据库层面的东西。这种模型简单的风格被称为“朴实可爱的 C# 对象(plain old C# object)” 或者 POCO。

                            +

                            视图模型

                            +

                            通常,你保存在数据库里的模型(实体),跟你在 MVC 里用的模型(视图模型)非常相似,但又不尽相同。在现在的情形下, TodoItem 模型代表单一的一个数据库里的条目,而视图则需要展示两个、十个,甚至是一百个待办事项(取决于用户拖延症的病情轻重)。

                            +

                            因此,视图模型应该是一个独立的类,里面包含着一个 TodoItem 的数组:

                            +

                            Models/TodoViewModel.cs

                            +
                            namespace AspNetCoreTodo.Models
                            +{
                            +    public class TodoViewModel
                            +    {
                            +        public TodoItem[] Items { get; set; }
                            +    }
                            +}
                            +
                            +

                            好了,现在模型也有了,是时候创建一个接收 TodoViewModel 并以 HTML 向用户展示待办事项列表的视图了。

                            +
                            +

                            Create models

                            +

                            There are two separate model classes that need to be created: a model that represents a to-do item stored in the database (sometimes called an entity), and the model that will be combined with a view (the MV in MVC) and sent back to the user's browser. Because both of them can be referred to as "models", I'll refer to the latter as a view model.

                            +

                            First, create a class called TodoItem in the Models directory:

                            +

                            Models/TodoItem.cs

                            +
                            using System;
                            +using System.ComponentModel.DataAnnotations;
                            +
                            +namespace AspNetCoreTodo.Models
                            +{
                            +    public class TodoItem
                            +    {
                            +        public Guid Id { get; set; }
                            +
                            +        public bool IsDone { get; set; }
                            +
                            +        [Required]
                            +        public string Title { get; set; }
                            +
                            +        public DateTimeOffset? DueAt { get; set; }
                            +    }
                            +}
                            +
                            +

                            This class defines what the database will need to store for each to-do item: an ID, a title or name, whether the item is complete, and what the due date is. Each line defines a property of the class:

                            +
                              +
                            • The Id property is a guid, or a globally unique identifier. Guids (or GUIDs) are long strings of letters and numbers, like 43ec09f2-7f70-4f4b-9559-65011d5781bb. Because guids are random and are extremely unlikely to be accidentally duplicated, they are commonly used as unique IDs. You could also use a number (integer) as a database entity ID, but you'd need to configure your database to always increment the number when new rows are added to the database. Guids are generated randomly, so you don't have to worry about auto-incrementing.

                              +
                            • +
                            • The IsDone property is a boolean (true/false value). By default, it will be false for all new items. Later you'll use write code to switch this property to true when the user clicks an item's checkbox in the view.

                              +
                            • +
                            • The Title property is a string (text value). This will hold the name or description of the to-do item. The [Required] attribute tells ASP.NET Core that this string can't be null or empty.

                              +
                            • +
                            • The DueAt property is a DateTimeOffset, which is a C# type that stores a date/time stamp along with a timezone offset from UTC. Storing the date, time, and timezone offset together makes it easy to render dates accurately on systems in different timezones.

                              +
                            • +
                            +

                            Notice the ? question mark after the DateTimeOffset type? That marks the DueAt property as nullable, or optional. If the ? wasn't included, every to-do item would need to have a due date. The Id and IsDone properties aren't marked as nullable, so they are required and will always have a value (or a default value).

                            +
                            +

                            Strings in C# are always nullable, so there's no need to mark the Title property as nullable. C# strings can be null, empty, or contain text.

                            +
                            +

                            Each property is followed by get; set;, which is a shorthand way of saying the property is read/write (or, more technically, it has a getter and setter methods).

                            +

                            At this point, it doesn't matter what the underlying database technology is. It could be SQL Server, MySQL, MongoDB, Redis, or something more exotic. This model defines what the database row or entry will look like in C# so you don't have to worry about the low-level database stuff in your code. This simple style of model is sometimes called a "plain old C# object" or POCO.

                            +

                            The view model

                            +

                            Often, the model (entity) you store in the database is similar but not exactly the same as the model you want to use in MVC (the view model). In this case, the TodoItem model represents a single item in the database, but the view might need to display two, ten, or a hundred to-do items (depending on how badly the user is procrastinating).

                            +

                            Because of this, the view model should be a separate class that holds an array of TodoItems:

                            +

                            Models/TodoViewModel.cs

                            +
                            namespace AspNetCoreTodo.Models
                            +{
                            +    public class TodoViewModel
                            +    {
                            +        public TodoItem[] Items { get; set; }
                            +    }
                            +}
                            +
                            +

                            Now that you have some models, it's time to create a view that will take a TodoViewModel and render the right HTML to show the user their to-do list.

                            + + +
                            + +
                            +
                            +
                            + +

                            results matching ""

                            +
                              + +
                              +
                              + +

                              No results matching ""

                              + +
                              +
                              +
                              + +
                              +
                              + +
                              + + + + + + + + + + + + + + +
                              + + +
                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/create-view.html b/book/chapters/mvc-basics/create-view.html new file mode 100644 index 0000000..5652997 --- /dev/null +++ b/book/chapters/mvc-basics/create-view.html @@ -0,0 +1,864 @@ + + + + + + + 创建视图 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                              +
                              + + + + + + + + +
                              + +
                              + +
                              + + + + + + + + +
                              +
                              + +
                              +
                              + +
                              + +

                              创建视图

                              +

                              ASP.NET Core 里的视图使用 Razor 模板语言编写,这种模板语言混合了 HTML 和 C# 的代码。(如果你在 JavaScript 下用 Jade、Pug 或者 Handlebars moustaches,在 Ruby on Rails 下用 ERB,在 Java 下用 Thymeleaf 写过页面,那你就已经了解其基本概念了.)

                              +

                              绝大多数视图代码就是 HTML,偶尔掺杂一点 C# 语句,用以从视图模型里抽取数据并转换为文本或者 HTML。这些 C# 语句以符号 @ 作为前缀。

                              +

                              TodoController 中的 action Index 生成的视图,需要从视图模型(一个待办事项的数组)获取数据,并用一个适当的表格展示给用户。按规定,视图要置于 Views 目录里,在一个与所属控制器同名的子目录下。视图文件的文件名就是 action 的名字加上一个 .cshtml 扩展名。

                              +

                              Views/Todo/Index.cshtml

                              +
                              @model TodoViewModel
                              +
                              +@{
                              +    ViewData["Title"] = "Manage your todo list";
                              +}
                              +
                              +<div class="panel panel-default todo-panel">
                              +  <div class="panel-heading">@ViewData["Title"]</div>
                              +
                              +  <table class="table table-hover">
                              +      <thead>
                              +          <tr>
                              +              <td>&#x2714;</td>
                              +              <td>Item</td>
                              +              <td>Due</td>
                              +          </tr>
                              +      </thead>
                              +
                              +      @foreach (var item in Model.Items)
                              +      {
                              +          <tr>
                              +              <td>
                              +                <input type="checkbox" class="done-checkbox">
                              +              </td>
                              +              <td>@item.Title</td>
                              +              <td>@item.DueAt</td>
                              +          </tr>
                              +      }
                              +  </table>
                              +
                              +  <div class="panel-footer add-item-form">
                              +    <!-- TODO: Add item form -->
                              +  </div>
                              +</div>
                              +
                              +

                              在文件顶端,@model 指令告诉 Razor 该视图要绑定到哪个模型。模型通过 Model 属性进行访问。

                              +

                              如果在 Model.Items 里有一些待办事项条目,则 foreach 语句将遍历到每个代办事项,并渲染成一个表格的行(<tr> 元素),改行包含条目的名字和截止日期。还会展示一个带有 ID 的复选框,可以在后续操作中把该条目标记为已完成。

                              +

                              布局文件

                              +

                              你可能会纳闷,其余的 HTML:<body> 标签,或者 页首 和 页脚 在哪儿?ASP.NET Core 使用一个布局视图,用以定义容纳视图的基础结构的其余部分。布局视图被保存在 Views/Shared/_Layout.cshtml

                              +

                              默认的 ASP.NET Core 模板在布局文件中包含了 Bootstrap 和 jQuery,便于你快捷地创建一个 web 应用程序。当然,只要你愿意,你可以使用自己的 CSS 和 JavaScript 库。

                              +

                              定制样式表

                              +

                              现在,请在 site.css 文件的底部添加以下这些 CSS 样式规则:

                              +

                              wwwroot/css/site.css

                              +
                              div.todo-panel {
                              +  margin-top: 15px;
                              +}
                              +
                              +table tr.done {
                              +  text-decoration: line-through;
                              +  color: #888;
                              +}
                              +
                              +

                              你可以用类似的规则完全自定义页面的外观和体验。

                              +

                              ASP.NET Core 和 Razor 还有更多功能,比如部分视图和后端渲染的视图组件,但你现在只需要一个简单的布局和视图。想要了解更多的内容,ASP.NET Core 的官方文档(位于 https://docs.asp.net)有几个示例可以参考。

                              +
                              +

                              Create a view

                              +

                              Views in ASP.NET Core are built using the Razor templating language, which combines HTML and C# code. (If you've written pages using Handlebars moustaches, ERB in Ruby on Rails, or Thymeleaf in Java, you've already got the basic idea.)

                              +

                              Most view code is just HTML, with the occasional C# statement added in to pull data out of the view model and turn it into text or HTML. The C# statements are prefixed with the @ symbol.

                              +

                              The view rendered by the Index action of the TodoController needs to take the data in the view model (a sequence of to-do items) and display it in a nice table for the user. By convention, views are placed in the Views directory, in a subdirectory corresponding to the controller name. The file name of the view is the name of the action with a .cshtml extension.

                              +

                              Create a Todo directory inside the Views directory, and add this file:

                              +

                              Views/Todo/Index.cshtml

                              +
                              @model TodoViewModel
                              +
                              +@{
                              +    ViewData["Title"] = "Manage your todo list";
                              +}
                              +
                              +<div class="panel panel-default todo-panel">
                              +  <div class="panel-heading">@ViewData["Title"]</div>
                              +
                              +  <table class="table table-hover">
                              +      <thead>
                              +          <tr>
                              +              <td>&#x2714;</td>
                              +              <td>Item</td>
                              +              <td>Due</td>
                              +          </tr>
                              +      </thead>
                              +
                              +      @foreach (var item in Model.Items)
                              +      {
                              +          <tr>
                              +              <td>
                              +                <input type="checkbox" class="done-checkbox">
                              +              </td>
                              +              <td>@item.Title</td>
                              +              <td>@item.DueAt</td>
                              +          </tr>
                              +      }
                              +  </table>
                              +
                              +  <div class="panel-footer add-item-form">
                              +    <!-- TODO: Add item form -->
                              +  </div>
                              +</div>
                              +
                              +

                              At the very top of the file, the @model directive tells Razor which model to expect this view to be bound to. The model is accessed through the Model property.

                              +

                              Assuming there are any to-do items in Model.Items, the foreach statement will loop over each to-do item and render a table row (<tr> element) containing the item's name and due date. A checkbox is also rendered that will let the user mark the item as complete.

                              +

                              The layout file

                              +

                              You might be wondering where the rest of the HTML is: what about the <body> tag, or the header and footer of the page? ASP.NET Core uses a layout view that defines the base structure that every other view is rendered inside of. It's stored in Views/Shared/_Layout.cshtml.

                              +

                              The default ASP.NET Core template includes Bootstrap and jQuery in this layout file, so you can quickly create a web application. Of course, you can use your own CSS and JavaScript libraries if you'd like.

                              +

                              Customizing the stylesheet

                              +

                              The default template also includes a stylesheet with some basic CSS rules. The stylesheet is stored in the wwwroot/css directory. Add a few new CSS style rules to the bottom of the site.css file:

                              +

                              wwwroot/css/site.css

                              +
                              div.todo-panel {
                              +  margin-top: 15px;
                              +}
                              +
                              +table tr.done {
                              +  text-decoration: line-through;
                              +  color: #888;
                              +}
                              +
                              +

                              You can use CSS rules like these to completely customize how your pages look and feel.

                              +

                              ASP.NET Core and Razor can do much more, such as partial views and server-rendered view components, but a simple layout and view is all you need for now. The official ASP.NET Core documentation (at https://docs.asp.net) contains a number of examples if you'd like to learn more.

                              + + +
                              + +
                              +
                              +
                              + +

                              results matching ""

                              +
                                + +
                                +
                                + +

                                No results matching ""

                                + +
                                +
                                +
                                + +
                                +
                                + +
                                + + + + + + + + + + + + + + +
                                + + +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/finish-controller.html b/book/chapters/mvc-basics/finish-controller.html new file mode 100644 index 0000000..786c8b1 --- /dev/null +++ b/book/chapters/mvc-basics/finish-controller.html @@ -0,0 +1,793 @@ + + + + + + + 完成控制器 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                +
                                + + + + + + + + +
                                + +
                                + +
                                + + + + + + + + +
                                +
                                + +
                                +
                                + +
                                + +

                                完成控制器

                                +

                                最后一步,让我们来完成控制器的编码。控制器现在已经从 服务层 获取到一个 待办事项 的列表,它应该把这些条目放进一个 TodoViewModel,并把该 模型 与你先前创建的 视图 绑定:

                                +

                                Controllers/TodoController.cs

                                +
                                public async Task<IActionResult> Index()
                                +{
                                +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                +
                                +    var model = new TodoViewModel()
                                +    {
                                +        Items = items
                                +    };
                                +
                                +    return View(model);
                                +}
                                +
                                +

                                如果你还没在文件顶部添加 using 语句,现在加上:

                                +
                                using AspNetCoreTodo.Services;
                                +using AspNetCoreTodo.Models;
                                +
                                +

                                如果你用的是 Visual Studio 或者 Visual Studio Code,当你鼠标指针指向一个红色波浪线时,编辑器会提示你添加这些 using 语句。

                                +

                                测试一下

                                +

                                按 F5 启动程序(如果你用的是 Visual Studio 或者 Visual Studio Code),或者在终端窗口里运行 dotnet run。如果代码通过编译而没有报错,服务器将在默认的 5000 端口上运行。

                                +

                                如果你的网络浏览器没自动弹出来,打开它,浏览 http://localhost:5000/todo 。你会看到自己创建的视图,展示着(暂时)从伪数据库层提取的数据。

                                +

                                尽管可以径直浏览 http://localhost:5000/todo,但如果导航栏上有一个 我的待办事项 条目就更好了。要达成这个目的,你可以去编辑共享的布局文件。

                                +
                                +

                                Finish the controller

                                +

                                The last step is to finish the controller code. The controller now has a list of to-do items from the service layer, and it needs to put those items into a TodoViewModel and bind that model to the view you created earlier:

                                +

                                Controllers/TodoController.cs

                                +
                                public async Task<IActionResult> Index()
                                +{
                                +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                +
                                +    var model = new TodoViewModel()
                                +    {
                                +        Items = items
                                +    };
                                +
                                +    return View(model);
                                +}
                                +
                                +

                                If you haven't already, make sure these using statements are at the top of the file:

                                +
                                using AspNetCoreTodo.Services;
                                +using AspNetCoreTodo.Models;
                                +
                                +

                                If you're using Visual Studio or Visual Studio Code, the editor will suggest these using statements when you put your cursor on a red squiggly line.

                                +

                                Test it out

                                +

                                To start the application, press F5 (if you're using Visual Studio or Visual Studio Code), or just type dotnet run in the terminal. If the code compiles without errors, the server will start up on port 5000 by default.

                                +

                                If your web browser didn't open automatically, open it and navigate to http://localhost:5000/todo. You'll see the view you created, with the data pulled from your fake database (for now).

                                +

                                Although it's possible to go directly to http://localhost:5000/todo, it would be nicer to add an item called My to-dos to the navbar. To do this, you can edit the shared layout file.

                                + + +
                                + +
                                +
                                +
                                + +

                                results matching ""

                                +
                                  + +
                                  +
                                  + +

                                  No results matching ""

                                  + +
                                  +
                                  +
                                  + +
                                  +
                                  + +
                                  + + + + + + + + + + + + + + +
                                  + + +
                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/index.html b/book/chapters/mvc-basics/index.html new file mode 100644 index 0000000..c3baeff --- /dev/null +++ b/book/chapters/mvc-basics/index.html @@ -0,0 +1,787 @@ + + + + + + + MVC 基础 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                  +
                                  + + + + + + + + +
                                  + +
                                  + +
                                  + + + + + + + + +
                                  +
                                  + +
                                  +
                                  + +
                                  + +

                                  MVC 基础

                                  +

                                  在这一章,你将探究 ASP.NET Core 中的 MVC 系统。 MVC(模型-视图-控制器,Model-View-Controller)是一个构建 web应用 的模式,其应用几乎遍及所有的 web框架(Ruby on Rails 和 Express 就是常见的范例)以及 Angular 这样的前端 JavaScript 框架。iOS 和 Android 上的移动应用也是 MVC 的一个变种。

                                  +

                                  正如其名字所示,MVC 有三个组件:模型、视图、和控制器。控制器处理从客户端浏览器传入的请求,并选定相应的代码进行处理。视图就是模板(一般是 HTML 外加某种 Handlebars、Pug、Razor 之类的模板语言),它接收传入的数据并展示给用户。模型则保管着数据,要么是准备发送给视图的,要么是用户输入的。

                                  +

                                  MVC 程序里常见的模式是:

                                  +
                                    +
                                  • 控制器接收请求,到数据库查找所需资料
                                  • +
                                  • 控制器使用查找到的信息创建模型,并使之与一个视图绑定
                                  • +
                                  • 视图在用户的浏览器里渲染并呈现
                                  • +
                                  • 用户点击一个按钮或者提交一个表单,从而发送一个新的请求给控制器,重复整个处理流程
                                  • +
                                  +

                                  如果你用其它开发语言写过 MVC,那你在 ASP.NET Core 里将如鱼得水。如果你是初次跟 MVC 打交道,这一章将教你基础知识,带你上道。

                                  +

                                  练习内容

                                  +

                                  MVC 练习里的 “Hello World”,就是创建一个待办事项清单应用程序。这是个很棒的练习,麻雀小,五脏俱全,它将涉及 MVC 的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。

                                  +

                                  通读本书,你将构建一个待办清单应用,允许用户添加待办项,并在事项完成之后勾掉它。具体来说,你将创建的是:

                                  +
                                    +
                                  • 一个 web 应用程序服务器(有时也被称为“后端”),使用 ASP.NET Core、C#和MVC模式
                                  • +
                                  • 一个用于存储用户待办事项条目的数据库,使用 SQLite 数据库引擎和一个被称为 Entity Framework Core 的系统创建
                                  • +
                                  • 让用户通过她们的浏览器进行交互的网页和界面(也被称为“前端”),使用HTML、CSS、JavaScript创建
                                  • +
                                  • 一个登录及安全检查表单,以便每个用户的待办事项列表都保持私密
                                  • +
                                  +

                                  听起来心动吗?那就整起来吧!你要是还没按上一章所讲,用 dotnet new mvc 创建一个新的 ASP.NET Core 项目。那你应该现在就创建并运行那个项目,直到看见默认的欢迎页面为止。

                                  +
                                  +

                                  MVC basics

                                  +

                                  In this chapter, you'll explore the MVC system in ASP.NET Core. MVC (Model-View-Controller) is a pattern for building web applications that's used in almost every web framework (Ruby on Rails and Express are popular examples), plus frontend JavaScript frameworks like Angular. Mobile apps on iOS and Android use a variation of MVC as well.

                                  +

                                  As the name suggests, MVC has three components: models, views, and controllers. Controllers handle incoming requests from a client or web browser and make decisions about what code to run. Views are templates (usually HTML plus a templating language like Handlebars, Pug, or Razor) that get data added to them and then are displayed to the user. Models hold the data that is added to views, or data that is entered by the user.

                                  +

                                  A common pattern for MVC code is:

                                  +
                                    +
                                  • The controller receives a request and looks up some information in a database
                                  • +
                                  • The controller creates a model with the information and attaches it to a view
                                  • +
                                  • The view is rendered and displayed in the user's browser
                                  • +
                                  • The user clicks a button or submits a form, which sends a new request to the controller, and the cycle repeats
                                  • +
                                  +

                                  If you've worked with MVC in other languages, you'll feel right at home in ASP.NET Core MVC. If you're new to MVC, this chapter will teach you the basics and will help get you started.

                                  +

                                  What you'll build

                                  +

                                  The "Hello World" exercise of MVC is building a to-do list application. It's a great project since it's small and simple in scope, but it touches each part of MVC and covers many of the concepts you'd use in a larger application.

                                  +

                                  In this book, you'll build a to-do app that lets the user add items to their to-do list and check them off once complete. More specifically, you'll be creating:

                                  +
                                    +
                                  • A web application server (sometimes called the "backend") using ASP.NET Core, C#, and the MVC pattern
                                  • +
                                  • A database to store the user's to-do items using the SQLite database engine and a system called Entity Framework Core
                                  • +
                                  • Web pages and an interface that the user will interact with via their browser, using HTML, CSS, and JavaScript (called the "frontend")
                                  • +
                                  • A login form and security checks so each user's to-do list is kept private
                                  • +
                                  +

                                  Sound good? Let's built it! If you haven't already created a new ASP.NET Core project using dotnet new mvc, follow the steps in the previous chapter. You should be able to build and run the project and see the default welcome screen.

                                  + + +
                                  + +
                                  +
                                  +
                                  + +

                                  results matching ""

                                  +
                                    + +
                                    +
                                    + +

                                    No results matching ""

                                    + +
                                    +
                                    +
                                    + +
                                    +
                                    + +
                                    + + + + + + + + + + + + + + +
                                    + + +
                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/update-the-layout.html b/book/chapters/mvc-basics/update-the-layout.html new file mode 100644 index 0000000..06bc3ba --- /dev/null +++ b/book/chapters/mvc-basics/update-the-layout.html @@ -0,0 +1,795 @@ + + + + + + + 修改布局 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                    +
                                    + + + + + + + + +
                                    + +
                                    + +
                                    + + + + + + + + +
                                    +
                                    + +
                                    +
                                    + +
                                    + +

                                    修改布局

                                    +

                                    位于 Views/Shared/_Layout.cshtml 的布局文件里面存放着所有视图的“基础”HTML。其中就包括导航栏,它被显示在每个页面的顶端。

                                    +

                                    为了向导航栏添加新条目,请先找到原有导航栏的 HTML 代码:

                                    +

                                    Views/Shared/_Layout.cshtml

                                    +
                                    <ul class="nav navbar-nav">
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="Index">
                                    +        Home
                                    +    </a></li>
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="About">
                                    +        About
                                    +    </a></li>
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="Contact">
                                    +        Contact
                                    +    </a></li>
                                    +</ul>
                                    +
                                    +

                                    添加你的条目,不要指向 Home 控制器,而要改为指向 Todo:

                                    +
                                    <li>
                                    +    <a asp-controller="Todo" asp-action="Index">My to-dos</a>
                                    +</li>
                                    +
                                    +

                                    <a> 元素中的属性 asp-controllerasp-action 被称为 tag helper。在视图被渲染之前,ASP.NET Core 会把这些 tag helper 替换成真正的 HTML 属性。在本例中,会生成一个指向路由 /Todo/Index 的 URL 并作为 href 添加到 <a> 元素中。这意味着你不必硬编码这个指向 TodoController 的路由。而是 ASP.NET Core 自动为你生成。

                                    +
                                    +

                                    如果你在 ASP.NET 4.x 中用过 Razor,应该会注意到一些语法的差异。生成一个指向 action 链接的时候,tag helper 是现在的建议的方式,而不是使用 @Html.ActionLink()。tag helper 对表单也很有用(你会在后续章节明白原委)。要学习其它的 tag helper,可以参考位于 https://docs.asp.net 的文档。

                                    +
                                    +
                                    +

                                    Update the layout

                                    +

                                    The layout file at Views/Shared/_Layout.cshtml contains the "base" HTML for each view. This includes the navbar, which is rendered at the top of each page.

                                    +

                                    To add a new item to the navbar, find the HTML code for the existing navbar items:

                                    +

                                    Views/Shared/_Layout.cshtml

                                    +
                                    <ul class="nav navbar-nav">
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="Index">
                                    +        Home
                                    +    </a></li>
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="About">
                                    +        About
                                    +    </a></li>
                                    +    <li><a asp-area="" asp-controller="Home" asp-action="Contact">
                                    +        Contact
                                    +    </a></li>
                                    +</ul>
                                    +
                                    +

                                    Add your own item that points to the Todo controller instead of Home:

                                    +
                                    <li>
                                    +    <a asp-controller="Todo" asp-action="Index">My to-dos</a>
                                    +</li>
                                    +
                                    +

                                    The asp-controller and asp-action attributes on the <a> element are called tag helpers. Before the view is rendered, ASP.NET Core replaces these tag helpers with real HTML attributes. In this case, a URL to the /Todo/Index route is generated and added to the <a> element as an href attribute. This means you don't have to hard-code the route to the TodoController. Instead, ASP.NET Core generates it for you automatically.

                                    +
                                    +

                                    If you've used Razor in ASP.NET 4.x, you'll notice some syntax changes. Instead of using @Html.ActionLink() to generate a link to an action, tag helpers are now the recommended way to create links in your views. Tag helpers are useful for forms, too (you'll see why in a later chapter). You can learn about other tag helpers in the documentation at https://docs.asp.net.

                                    +
                                    + + +
                                    + +
                                    +
                                    +
                                    + +

                                    results matching ""

                                    +
                                      + +
                                      +
                                      + +

                                      No results matching ""

                                      + +
                                      +
                                      +
                                      + +
                                      +
                                      + +
                                      + + + + + + + + + + + + + + +
                                      + + +
                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/mvc-basics/use-dependency-injection.html b/book/chapters/mvc-basics/use-dependency-injection.html new file mode 100644 index 0000000..3ad58cd --- /dev/null +++ b/book/chapters/mvc-basics/use-dependency-injection.html @@ -0,0 +1,883 @@ + + + + + + + 运用依赖注入 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                      +
                                      + + + + + + + + +
                                      + +
                                      + +
                                      + + + + + + + + +
                                      +
                                      + +
                                      +
                                      + +
                                      + +

                                      运用依赖注入

                                      +

                                      回到 TodoController,添加一些代码以使用 ITodoItemService:

                                      +
                                      public class TodoController : Controller
                                      +{
                                      +    private readonly ITodoItemService _todoItemService;
                                      +
                                      +    public TodoController(ITodoItemService todoItemService)
                                      +    {
                                      +        _todoItemService = todoItemService;
                                      +    }
                                      +
                                      +    public IActionResult Index()
                                      +    {
                                      +        // Get to-do items from database
                                      +
                                      +        // Put items into a model
                                      +
                                      +        // Pass the view to a model and render
                                      +    }
                                      +}
                                      +
                                      +

                                      既然 ITodoItemService 在命名空间 Services 里,你同样需要在文件顶部添加一个 using 语句:

                                      +
                                      using AspNetCoreTodo.Services;
                                      +
                                      +

                                      这个类的第一行声明了一个私有变量,保存 ITodoItemService 的引用。这个变量可以让你在后面的 Index 方法里使用该服务(具体方法,稍后便知)。

                                      +

                                      public TodoController(ITodoItemService todoItemService) 这一行给类定义了一个 构造函数(constructor)。构造函数是一个特殊的方法,它会在为(本例中是 TodoController)类创建一个新的实例的时候被调用。在构造函数中加入的 ITodoItemService 参数,表示你做出如下声明:要创建一个 TodoController,你必须提供一个能匹配 ITodoItemService 接口的对象。

                                      +
                                      +

                                      接口如此有用的原因就在于,因为它们有助于解耦(分离)你程序里的逻辑。既然这个控制器依赖于 ITodoItemService 接口,而不是任何 特定的 类,它就不知道也不必关心实际使用的是哪个具体的类。它可以是 FakeTodoItemService,或者是其它读写数据库的类,或者别的什么类。只要它符合该接口的要求,控制器就能工作。这使你可以轻而易举地,独立测试程序的各部分。(我会在 自动化测试 一章讲解测试相关的内容。)

                                      +
                                      +

                                      现在,你终于可以在 action 方法里,(通过你声明的那个私有变量)使用 ITodoItemService 从服务层获取 待办事项 了:

                                      +
                                      public IActionResult Index()
                                      +{
                                      +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                      +
                                      +    // ...
                                      +}
                                      +
                                      +

                                      还记得吗? GetIncompleteItemsAsync 方法返回一个 Task<TodoItem[]>。“返回一个 Task”的意思是说,该方法不能立刻给出一个结果,但是你可以使用关键字 await,以确保你的代码暂停,直到结果就绪才继续执行。

                                      +

                                      当你编写代码访问数据库或者外部 API 服务的时候,Task 模式是很常见的,因为在数据库(或者网络)响应之前,它不可能给出实际的结果。如果你在 JavaScript 或者其它语言里使用过 promise 或者 回调函数,Task 与之如出一辙:承诺你,肯定会给出一个结果——在未来的某个时候。

                                      +
                                      +

                                      如果你在老式 JavaScript 里应付过 “回调地狱”,那你现在走运了。在 .NET 里使用 Task 跟依附代码打交道要容易得多,这归功于神奇的关键字 awaitawait 把代码暂停在 异步(async) 操作上,而后,在底层数据库或者网络请求结束时,从暂停的地方恢复执行。就是说,你的程序并没有卡住或者阻塞住,因为它可以处理其它的请求。如果现在想不通也别担心,跟着做下去就行!

                                      +
                                      +

                                      目前的重点就是修改 Index 方法的签名,以返回一个 Task<IActionResult>,代替之前的 IActionResult,并标记为 async

                                      +
                                      public async Task<IActionResult> Index()
                                      +{
                                      +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                      +
                                      +    // Put items into a model
                                      +
                                      +    // Pass the view to a model and render
                                      +}
                                      +
                                      +

                                      胜利在望!你已经让 TodoController 依赖于 ITodoItemService 接口,但你还没告诉 ASP.NET Core,你想把 FakeTodoItemService 作为幕后的实际服务。可能你觉得这是理所当然的,因为你的ITodoItemService仅有这一个实现,但你后面会为同一个接口提供多个实现,所以,有必要明确指定实现。

                                      +

                                      要声明(或者“关联”)具体的类到每个接口上,需要写在 StartUp 类的 ConfigureServices 方法里,在当前情况里,应该这么写:

                                      +

                                      Startup.cs

                                      +
                                      public void ConfigureServices(IServiceCollection services)
                                      +{
                                      +    // (... some code)
                                      +
                                      +    services.AddMvc();
                                      +}
                                      +
                                      +

                                      ConfigureServices 方法负责的是把东西添加到 服务容器 里,或者 ASP.NET Core 的说法是服务的集合。 services.AddMvc 这行添加了一些服务,它们是 ASP.NET Core 系统内部依赖的(你可以试试,把这行代码注释掉)。你在应用里所需的任何其它服务,也都要在这个地方添加到服务容器里。

                                      +

                                      把下面这行添加到ConfigureServices中的任意位置:

                                      +
                                      services.AddSingleton<ITodoItemService, FakeTodoItemService>();
                                      +
                                      +

                                      这一行告知 ASP.NET Core,在任何时候,只要 ITodoItemService 被一个构造函数(或其它什么地方)被请求,就用这个 FakeTodoItemService

                                      +

                                      AddSingleton 把你的服务作为 singleton 添加进服务容器。这意味着,只有一个FakeTodoItemService的实例被创建,并在每次被请求的时候都被复用。在后面,当你写另一个服务去跟数据库交互时,你会采用一个不同的方式(叫做 scoped)。我会在 运用数据库 一章里说明原因。

                                      +

                                      好了,当一个请求进来,将会被发送到 TodoController,当控制器需要一个ITodoItemService 时,ASP.NET Core 会在 可用服务集合 里查找并自动给出 FakeTodoItemService。因为服务是从服务容器里“注入(injected)”的,这个模式被称为 依赖注入(dependency injection)

                                      +
                                      +

                                      Use dependency injection

                                      +

                                      Back in the TodoController, add some code to work with the ITodoItemService:

                                      +
                                      public class TodoController : Controller
                                      +{
                                      +    private readonly ITodoItemService _todoItemService;
                                      +
                                      +    public TodoController(ITodoItemService todoItemService)
                                      +    {
                                      +        _todoItemService = todoItemService;
                                      +    }
                                      +
                                      +    public IActionResult Index()
                                      +    {
                                      +        // Get to-do items from database
                                      +
                                      +        // Put items into a model
                                      +
                                      +        // Pass the view to a model and render
                                      +    }
                                      +}
                                      +
                                      +

                                      Since ITodoItemService is in the Services namespace, you'll also need to add a using statement at the top:

                                      +
                                      using AspNetCoreTodo.Services;
                                      +
                                      +

                                      The first line of the class declares a private variable to hold a reference to the ITodoItemService. This variable lets you use the service from the Index action method later (you'll see how in a minute).

                                      +

                                      The public TodoController(ITodoItemService todoItemService) line defines a constructor for the class. The constructor is a special method that is called when you want to create a new instance of a class (the TodoController class, in this case). By adding an ITodoItemService parameter to the constructor, you've declared that in order to create the TodoController, you'll need to provide an object that matches the ITodoItemService interface.

                                      +
                                      +

                                      Interfaces are awesome because they help decouple (separate) the logic of your application. Since the controller depends on the ITodoItemService interface, and not on any specific class, it doesn't know or care which class it's actually given. It could be the FakeTodoItemService, a different one that talks to a live database, or something else! As long as it matches the interface, the controller can use it. This makes it really easy to test parts of your application separately. I'll cover testing in detail in the Automated testing chapter.

                                      +
                                      +

                                      Now you can finally use the ITodoItemService (via the private variable you declared) in your action method to get to-do items from the service layer:

                                      +
                                      public IActionResult Index()
                                      +{
                                      +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                      +
                                      +    // ...
                                      +}
                                      +
                                      +

                                      Remember that the GetIncompleteItemsAsync method returned a Task<TodoItem[]>? Returning a Task means that the method won't necessarily have a result right away, but you can use the await keyword to make sure your code waits until the result is ready before continuing on.

                                      +

                                      The Task pattern is common when your code calls out to a database or an API service, because it won't be able to return a real result until the database (or network) responds. If you've used promises or callbacks in JavaScript or other languages, Task is the same idea: the promise that there will be a result - sometime in the future.

                                      +
                                      +

                                      If you've had to deal with "callback hell" in older JavaScript code, you're in luck. Dealing with asynchronous code in .NET is much easier thanks to the magic of the await keyword! await lets your code pause on an async operation, and then pick up where it left off when the underlying database or network request finishes. In the meantime, your application isn't blocked, because it can process other requests as needed. This pattern is simple but takes a little getting used to, so don't worry if this doesn't make sense right away. Just keep following along!

                                      +
                                      +

                                      The only catch is that you need to update the Index method signature to return a Task<IActionResult> instead of just IActionResult, and mark it as async:

                                      +
                                      public async Task<IActionResult> Index()
                                      +{
                                      +    var items = await _todoItemService.GetIncompleteItemsAsync();
                                      +
                                      +    // Put items into a model
                                      +
                                      +    // Pass the view to a model and render
                                      +}
                                      +
                                      +

                                      You're almost there! You've made the TodoController depend on the ITodoItemService interface, but you haven't yet told ASP.NET Core that you want the FakeTodoItemService to be the actual service that's used under the hood. It might seem obvious right now since you only have one class that implements ITodoItemService, but later you'll have multiple classes that implement the same interface, so being explicit is necessary.

                                      +

                                      Declaring (or "wiring up") which concrete class to use for each interface is done in the ConfigureServices method of the Startup class. Right now, it looks something like this:

                                      +

                                      Startup.cs

                                      +
                                      public void ConfigureServices(IServiceCollection services)
                                      +{
                                      +    // (... some code)
                                      +
                                      +    services.AddMvc();
                                      +}
                                      +
                                      +

                                      The job of the ConfigureServices method is adding things to the service container, or the collection of services that ASP.NET Core knows about. The services.AddMvc line adds the services that the internal ASP.NET Core systems need (as an experiment, try commenting out this line). Any other services you want to use in your application must be added to the service container here in ConfigureServices.

                                      +

                                      Add the following line anywhere inside the ConfigureServices method:

                                      +
                                      services.AddSingleton<ITodoItemService, FakeTodoItemService>();
                                      +
                                      +

                                      This line tells ASP.NET Core to use the FakeTodoItemService whenever the ITodoItemService interface is requested in a constructor (or anywhere else).

                                      +

                                      AddSingleton adds your service to the service container as a singleton. This means that only one copy of the FakeTodoItemService is created, and it's reused whenever the service is requested. Later, when you write a different service class that talks to a database, you'll use a different approach (called scoped) instead. I'll explain why in the Use a database chapter.

                                      +

                                      That's it! When a request comes in and is routed to the TodoController, ASP.NET Core will look at the available services and automatically supply the FakeTodoItemService when the controller asks for an ITodoItemService. Because the services are "injected" from the service container, this pattern is called dependency injection.

                                      + + +
                                      + +
                                      +
                                      +
                                      + +

                                      results matching ""

                                      +
                                        + +
                                        +
                                        + +

                                        No results matching ""

                                        + +
                                        +
                                        +
                                        + +
                                        +
                                        + +
                                        + + + + + + + + + + + + + + +
                                        + + +
                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/security-and-identity/access-denied.png b/book/chapters/security-and-identity/access-denied.png new file mode 100644 index 0000000..b534e96 Binary files /dev/null and b/book/chapters/security-and-identity/access-denied.png differ diff --git a/book/chapters/security-and-identity/add-facebook-login.md b/book/chapters/security-and-identity/add-facebook-login.md new file mode 100644 index 0000000..44c5534 --- /dev/null +++ b/book/chapters/security-and-identity/add-facebook-login.md @@ -0,0 +1,133 @@ +## 添加 Facebook 登录功能 + +Individual Auth 项目模板包括了“开箱即用”式的“使用电子邮件地址和密码注册”的功能。你可以添加额外的身份供应者(比如 Google 和 Facebook)来扩展这个功能。 + +要接入任何一个身份供应商,你通常需要做这两件事: + +1. 在供应商那里创建一个 应用(有时候也叫*客户(client)*),以此代表你的程序 +1. 复制供应商生成的 ID 和 密码,放进你的代码里 + +### 在 Facebook 创建一个应用 + +你可以使用位于 https://developers.facebook.com/apps 的 Facebook 开发者控制台创建一个新的 Facebook 应用。点击 **Add a New App** 并按提示创建一个应用 ID。 + +> 如果你没有 Facebook 账号,可以换成 Google 或者 Twitter 登录功能。在供应商网站上的操作会有些差异,但在代码里基本一致。 + +下一步,设置 Facebook Login 然后点击左边栏的 Settings —— 在 Facebook Login 下面: + +![Settings button](facebook-login-settings.png) + +把以下 URL 添加到 **Valid OAuth redirect URIs** 文本框里。 + +``` +http://localhost:5000/signin-facebook +``` + +> 你程序运行的时候,监听的端口可能不一样。如果你使用 `dotnet start` 通常是 5000 端口,但如果你在 Windows 上,可能是个随机的端口比如 54574。无论如何,当程序运行的时候,你总是可以在浏览器的地址栏里看到程序监听的端口。 + +点击 **Save Changes**,然后打开 Dashboard 页面。在这里你可以看到由 Facebook 创建的 应用ID 和 密码,这些稍后就会用到(请保持这个页面开启)。 + +要在 ASP.NET Core Identity 里启用 Facebook 登录功能,把下面这段代码添加到 `Startup` 类里 `ConfigureServices` 方法中的任意位置: + +```csharp +services + .AddAuthentication() + .AddFacebook(options => + { + options.AppId = Configuration["Facebook:AppId"]; + options.AppSecret = Configuration["Facebook:AppSecret"]; + }); +``` + +为免把 Facebook 应用ID 和 密码 硬编码在程序里,这些值应该从配置系统里获取。一般情况下 `appsettings.json` 文件是保存项目配置信息的地方。尽管如此,既然它会被提交到版本控制系统里,就不太适合 应用ID 和 密码 这些敏感信息。(比方说,你的密码推送到了 GitHub,任何人都可能窃取它,并滥用它来损害你的利益。) + +### 通过 Secrets Manager 来安全地保存密码 + +你可以把 Secrets Manager 工具用于 应用密码 这种敏感信息。在终端窗口里执行这一行以确保它安装过了(先确保你当前位于项目目录中): + +``` +dotnet user-secrets --help +``` + +从 Facebook 应用管理页面复制 应用ID 和 密码,并使用 `set` 命令将它们的值保存在 Secrets Manager 里: + +``` +dotnet user-secrets set Facebook:AppId <粘贴 应用ID> +dotnet user-secrets set Facebook:AppSecret <粘贴 应用密码> +``` + +当你的程序启动的时候,Secrets Manager 里的值会加载到 `Configuration` 属性中,所以你刚才在 `ConfigureServices` 中添加的代码能够访问到它们。 + +运行程序,在导航条上点击 Login,你会看到一个新的按钮,用于 Facebook 登录功能: + +![Facebook login button](facebook-login-button.png) + +试一下 Facebook 登录功能。你会被重定向到 Facebook 并被提示向你的应用授权,然后重定向回来再登录进去。 + +--- + +## Add Facebook login + +Out of the box, the Individual Auth template includes functionality for registering using an email and password. You can extend this by plugging in additional identity providers like Google and Facebook. + +For any external provider, you typically need to do two things: + +1. Create an app (sometimes called a *client*) on the external provider that represents your application +1. Copy the ID and secret generated by the provider and put them in your code + +### Create an app in Facebook + +You can create new Facebook apps using the Facebook Developer console at https://developers.facebook.com/apps. Click **Add a New App** and follow the instructions to create an app ID. + +> If you don't have a Facebook account, you can set up Google or Twitter login instead. The steps on the provider's site will be different, but the code is almost identical. + +Next, set up Facebook Login and then click Settings on the left side, under Facebook Login: + +![Settings button](facebook-login-settings.png) + +Add the following URL to the **Valid OAuth redirect URIs** box: + +``` +http://localhost:5000/signin-facebook +``` + +> The port that your application runs on may differ. It's typically port 5000 if you use `dotnet start`, but if you're on Windows, it could be a random port like 54574. Either way, you can always see the port your application is running on in the address bar of your web browser. + +Click **Save Changes** and then head over to the Dashboard page. Here you can see the app ID and secret generated by Facebook, which you'll need in a moment (keep this tab open). + +To enable Facebook login in ASP.NET Core Identity, add this code anywhere in the `ConfigureServices` method in the `Startup` class: + +```csharp +services + .AddAuthentication() + .AddFacebook(options => + { + options.AppId = Configuration["Facebook:AppId"]; + options.AppSecret = Configuration["Facebook:AppSecret"]; + }); +``` + +Instead of hardcoding the Facebook app ID and secret in your code, the values are pulled from the configuration system. The `appsettings.json` file is normally the place to store configuration data for your project. However, since it's checked into source control, it's not good for sensitive data like an app secret. (If your app secret was pushed to GitHub, for example, anyone could steal it and do bad things on your behalf.) + +### Store secrets safely with the Secrets Manager + +You can use the Secrets Manager tool for sensitive data like an app secret. Run this line in the terminal to make sure it's installed (make sure you're currently in the project directory): + +``` +dotnet user-secrets --help +``` + +Copy the app ID and secret from the Facebook app dashboard and use the `set` command to save the values in the Secrets Manager: + +``` +dotnet user-secrets set Facebook:AppId +dotnet user-secrets set Facebook:AppSecret +``` + +The values from the Secrets Manager are loaded into the `Configuration` property when your application starts up, so they're available to the code in `ConfigureServices` you added before. + +Run your application and click the Login link in the navbar. You'll see a new button for logging in with Facebook: + +![Facebook login button](facebook-login-button.png) + +Try logging in with Facebook. You'll be redirected and prompted to give your app permission in Facebook, then redirected back and logged in. diff --git a/book/chapters/security-and-identity/authorization-with-roles.html b/book/chapters/security-and-identity/authorization-with-roles.html new file mode 100644 index 0000000..d3748ac --- /dev/null +++ b/book/chapters/security-and-identity/authorization-with-roles.html @@ -0,0 +1,1313 @@ + + + + + + + 按角色进行授权 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                        +
                                        + + + + + + + + +
                                        + +
                                        + +
                                        + + + + + + + + +
                                        +
                                        + +
                                        +
                                        + +
                                        + +

                                        按角色进行授权

                                        +

                                        在网络应用里,角色是用于处理 授权 和 许可 的常见方法。例如,通常会为管理员创建一个 Administrator 角色,相对于普通用户,他们拥有更多的权限和能力。

                                        +

                                        在此项目中,你将添加一个 用户管理 页面,仅对管理员们可见。如果普通用户试图访问它,将会看到错误提示。

                                        +

                                        添加用户管理页面

                                        +

                                        首先,创建一个新控制器:

                                        +

                                        Controllers/ManageUsersController.cs

                                        +
                                        using System;
                                        +using System.Linq;
                                        +using System.Threading.Tasks;
                                        +using Microsoft.AspNetCore.Mvc;
                                        +using Microsoft.AspNetCore.Authorization;
                                        +using Microsoft.AspNetCore.Identity;
                                        +using AspNetCoreTodo.Models;
                                        +using Microsoft.EntityFrameworkCore;
                                        +
                                        +namespace AspNetCoreTodo.Controllers
                                        +{
                                        +    [Authorize(Roles = "Administrator")]
                                        +    public class ManageUsersController : Controller
                                        +    {
                                        +        private readonly UserManager<ApplicationUser>
                                        +            _userManager;
                                        +
                                        +        public ManageUsersController(
                                        +            UserManager<ApplicationUser> userManager)
                                        +        {
                                        +            _userManager = userManager;
                                        +        }
                                        +
                                        +        public async Task<IActionResult> Index()
                                        +        {
                                        +            var admins = (await _userManager
                                        +                .GetUsersInRoleAsync("Administrator"))
                                        +                .ToArray();
                                        +
                                        +            var everyone = await _userManager.Users
                                        +                .ToArrayAsync();
                                        +
                                        +            var model = new ManageUsersViewModel
                                        +            {
                                        +                Administrators = admins,
                                        +                Everyone = everyone
                                        +            };
                                        +
                                        +            return View(model);
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        [Authorize] 属性里加入 Roles 字段,可以确保用户必须已经登录 并且 被分配了 Administrator 角色才能查看这个页面。

                                        +

                                        接下来,创建一个视图模型:

                                        +

                                        Models/ManageUsersViewModel.cs

                                        +
                                        using System.Collections.Generic;
                                        +
                                        +namespace AspNetCoreTodo.Models
                                        +{
                                        +    public class ManageUsersViewModel
                                        +    {
                                        +        public ApplicationUser[] Administrators { get; set; }
                                        +
                                        +        public ApplicationUser[] Everyone { get; set;}
                                        +    }
                                        +}
                                        +
                                        +

                                        最后,为 action Index 创建一个名为Views/ManageUsers的文件夹和一个视图:

                                        +

                                        Views/ManageUsers/Index.cshtml

                                        +
                                        @model ManageUsersViewModel
                                        +
                                        +@{
                                        +    ViewData["Title"] = "Manage users";
                                        +}
                                        +
                                        +<h2>@ViewData["Title"]</h2>
                                        +
                                        +<h3>Administrators</h3>
                                        +
                                        +<table class="table">
                                        +    <thead>
                                        +        <tr>
                                        +            <td>Id</td>
                                        +            <td>Email</td>
                                        +        </tr>
                                        +    </thead>
                                        +
                                        +    @foreach (var user in Model.Administrators)
                                        +    {
                                        +        <tr>
                                        +            <td>@user.Id</td>
                                        +            <td>@user.Email</td>
                                        +        </tr>
                                        +    }
                                        +</table>
                                        +
                                        +<h3>Everyone</h3>
                                        +
                                        +<table class="table">
                                        +    <thead>
                                        +        <tr>
                                        +            <td>Id</td>
                                        +            <td>Email</td>
                                        +        </tr>
                                        +    </thead>
                                        +
                                        +    @foreach (var user in Model.Everyone)
                                        +    {
                                        +        <tr>
                                        +            <td>@user.Id</td>
                                        +            <td>@user.Email</td>
                                        +        </tr>
                                        +    }
                                        +</table>
                                        +
                                        +

                                        启动程序,并以普通用户身份登录,尝试去访问一下 /ManageUsers 路径。你会见到这样的 拒绝访问 页面:

                                        +

                                        Access denied error

                                        +

                                        这是因为注册用户不会自动获得 Administrator 这个角色。

                                        +

                                        创建一个测试用的管理员账号

                                        +

                                        出于显而易见的安全因素,对于任何人来说,都不能自主的注册成为一个管理员账号。事实上,Administrator 这个角色,在数据库中尚不存在。

                                        +

                                        你可以在该应用程序第一次启动的时候,将这个 Administrator 角色外加一个测试用的管理员账号添加到数据库中。向数据库添加初始数据的行为,被称为初始化,或者 填充(seeding) 数据库。

                                        +

                                        在项目的根目录创建一个新类,取名为 SeedData

                                        +

                                        SeedData.cs

                                        +
                                        using System;
                                        +using System.Linq;
                                        +using System.Threading.Tasks;
                                        +using AspNetCoreTodo.Models;
                                        +using Microsoft.AspNetCore.Identity;
                                        +using Microsoft.EntityFrameworkCore;
                                        +using Microsoft.Extensions.DependencyInjection;
                                        +
                                        +namespace AspNetCoreTodo
                                        +{
                                        +    public static class SeedData
                                        +    {
                                        +        public static async Task InitializeAsync(
                                        +            IServiceProvider services)
                                        +        {
                                        +            var roleManager = services
                                        +                .GetRequiredService<RoleManager<IdentityRole>>();
                                        +            await EnsureRolesAsync(roleManager);
                                        +
                                        +            var userManager = services
                                        +                .GetRequiredService<UserManager<ApplicationUser>>();
                                        +            await EnsureTestAdminAsync(userManager);
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        InitializeAsync() 方法使用一个 IServiceProvider(在Startup.ConfigureServices()方法中设置过的服务集合)从 ASP.NET Core Identity 中获取RoleManagerUserManager

                                        +

                                        InitializeAsync()方法下面再添加两个方法,第一个,EnsureRolesAsync()方法:

                                        +
                                        private static async Task EnsureRolesAsync(
                                        +    RoleManager<IdentityRole> roleManager)
                                        +{
                                        +    var alreadyExists = await roleManager
                                        +        .RoleExistsAsync(Constants.AdministratorRole);
                                        +
                                        +    if (alreadyExists) return;
                                        +
                                        +    await roleManager.CreateAsync(
                                        +        new IdentityRole(Constants.AdministratorRole));
                                        +}
                                        +
                                        +

                                        此方法查看数据库里是否存在一个 Administrator 角色。如果没有,它就创建一个。为免反复地输入字符串 "Administrator",创建一个名为 Constants 的小类以保存它的值:

                                        +

                                        Constants.cs

                                        +
                                        namespace AspNetCoreTodo
                                        +{
                                        +    public static class Constants
                                        +    {
                                        +        public const string AdministratorRole = "Administrator";
                                        +    }
                                        +}
                                        +
                                        +
                                        +

                                        如果你愿意,也可以修改之前创建的 ManageUsersController 使用这个常量值。

                                        +
                                        +

                                        接下来是 EnsureTestAdminAsync() 方法:

                                        +

                                        SeedData.cs

                                        +
                                        private static async Task EnsureTestAdminAsync(
                                        +    UserManager<ApplicationUser> userManager)
                                        +{
                                        +    var testAdmin = await userManager.Users
                                        +        .Where(x => x.UserName == "admin@todo.local")
                                        +        .SingleOrDefaultAsync();
                                        +
                                        +    if (testAdmin != null) return;
                                        +
                                        +    testAdmin = new ApplicationUser
                                        +    {
                                        +        UserName = "admin@todo.local",
                                        +        Email = "admin@todo.local"
                                        +    };
                                        +    await userManager.CreateAsync(
                                        +        testAdmin, "NotSecure123!!");
                                        +    await userManager.AddToRoleAsync(
                                        +        testAdmin, Constants.AdministratorRole);
                                        +}
                                        +
                                        +

                                        如果数据库里不存在一个用户名为 admin@todo.local 的用户,这个方法将创建它并给它一个临时的密码。在你初次登录之后,就应该改为一个更安全的密码。

                                        +

                                        接下来,你需要提醒你的程序,在它启动的时候,执行这个逻辑。修改Program.cs,并更新Main()去调用一个新的方法InitializeDatabase()

                                        +

                                        Program.cs

                                        +
                                        public static void Main(string[] args)
                                        +{
                                        +    var host = BuildWebHost(args);
                                        +    InitializeDatabase(host);
                                        +    host.Run();
                                        +}
                                        +
                                        +

                                        然后,在Main()的下面添加这个新方法:

                                        +
                                        private static void InitializeDatabase(IWebHost host)
                                        +{
                                        +    using (var scope = host.Services.CreateScope())
                                        +    {
                                        +        var services = scope.ServiceProvider;
                                        +
                                        +        try
                                        +        {
                                        +            SeedData.InitializeAsync(services).Wait();
                                        +        }
                                        +        catch (Exception ex)
                                        +        {
                                        +            var logger = services
                                        +                .GetRequiredService<ILogger<Program>>();
                                        +            logger.LogError(ex, "Error occurred seeding the DB.");
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        并把这个 using 语句添加到文件顶部:

                                        +
                                        using Microsoft.Extensions.DependencyInjection;
                                        +
                                        +

                                        此方法获取SeedData.InitializeAsync()所需的服务集合,然后执行它以便初始化数据库。如果出现错误,将会记录一条错误日志。

                                        +
                                        +

                                        因为InitializeAsync()返回一个 Task,就必须使用 Wait() 方法以确保它在应用程序启动前完成。你一般是用 await 做这件事,但是因为某些技术原因,你无法在 Program 方法中使用 await。这是个罕见的例外 —— 所有其它地方你都应该用 await

                                        +
                                        +

                                        当你再次启动程序,admin@todo.local 这个账号会被创建并被赋予 Administrator 角色。请尝试用这个账号登录,并浏览位于 http://localhost:5000/ManageUsers 的页面,你将看到一个列表,列出了本程序的所有注册用户。

                                        +
                                        +

                                        作为练习,请在这个页面添加更多管理功能特性。例如,添加一个按钮,为管理员提供 删除一个用户 的功能。

                                        +
                                        +

                                        在视图里查看认证状态

                                        +

                                        [Authorize] 属性让控制器里执行认证操作变得很方便,但是如果你需要在视图里进行认证操作呢?比如,在导航条上为登入的管理员用户显示一个“管理用户”的链接。

                                        +

                                        你可以把 UserManager 直接注入到视图里来进行这些操作。为保持你视图整洁有序,创建一个新的局部视图(partial view),以便在布局中的导航条里添加一个项目:

                                        +

                                        Views/Shared/_AdminActionsPartial.cshtml

                                        +
                                        @using Microsoft.AspNetCore.Identity
                                        +@using AspNetCoreTodo.Models
                                        +
                                        +@inject SignInManager<ApplicationUser> signInManager
                                        +@inject UserManager<ApplicationUser> userManager
                                        +
                                        +@if (signInManager.IsSignedIn(User))
                                        +{
                                        +    var currentUser = await userManager.GetUserAsync(User);
                                        +
                                        +    var isAdmin = currentUser != null
                                        +        && await userManager.IsInRoleAsync(
                                        +            currentUser,
                                        +            Constants.AdministratorRole);
                                        +
                                        +    if (isAdmin)
                                        +    {
                                        +        <ul class="nav navbar-nav navbar-right">
                                        +            <li>
                                        +                <a asp-controller="ManageUsers" 
                                        +                   asp-action="Index">
                                        +                   Manage Users
                                        +                </a>
                                        +            </li>
                                        +        </ul>
                                        +    }
                                        +}
                                        +
                                        +
                                        +

                                        按惯例,通常把局部视图的名字以 _ 下划线开始,但这不是强制性的。

                                        +
                                        +

                                        这个局部视图首先使用 SignInManager 判断用户是否已经登录。如果没有登录,其余的代码就都被跳过。如果这 个已登录用户,UserManager 就被用于查找用户详细信息,并用 IsInRoleAsync() 进行认证检查。如果所有检查都通过了,并且该用户是一个管理员,导航条上就会加入一个 Manage Users 链接。

                                        +

                                        要在主布局中包含这个局部视图,编辑 _Layout.cshtml 并在导航条部分添加:

                                        +

                                        Views/Shared/_Layout.cshtml

                                        +
                                        <div class="navbar-collapse collapse">
                                        +    <ul class="nav navbar-nav">
                                        +        <!-- existing code here -->
                                        +    </ul>
                                        +    @await Html.PartialAsync("_LoginPartial")
                                        +    @await Html.PartialAsync("_AdminActionsPartial")
                                        +</div>
                                        +
                                        +

                                        如果你用管理员账号登录,将在右上角见到一个新的导航项:

                                        +

                                        Manage Users link

                                        +
                                        +

                                        Authorization with roles

                                        +

                                        Roles are a common approach to handling authorization and permissions in a web application. For example, it's common to create an Administrator role that gives admin users more permissions or power than normal users.

                                        +

                                        In this project, you'll add a Manage Users page that only administrators can see. If normal users try to access it, they'll see an error.

                                        +

                                        Add a Manage Users page

                                        +

                                        First, create a new controller:

                                        +

                                        Controllers/ManageUsersController.cs

                                        +
                                        using System;
                                        +using System.Linq;
                                        +using System.Threading.Tasks;
                                        +using Microsoft.AspNetCore.Mvc;
                                        +using Microsoft.AspNetCore.Authorization;
                                        +using Microsoft.AspNetCore.Identity;
                                        +using AspNetCoreTodo.Models;
                                        +using Microsoft.EntityFrameworkCore;
                                        +
                                        +namespace AspNetCoreTodo.Controllers
                                        +{
                                        +    [Authorize(Roles = "Administrator")]
                                        +    public class ManageUsersController : Controller
                                        +    {
                                        +        private readonly UserManager<ApplicationUser>
                                        +            _userManager;
                                        +
                                        +        public ManageUsersController(
                                        +            UserManager<ApplicationUser> userManager)
                                        +        {
                                        +            _userManager = userManager;
                                        +        }
                                        +
                                        +        public async Task<IActionResult> Index()
                                        +        {
                                        +            var admins = (await _userManager
                                        +                .GetUsersInRoleAsync("Administrator"))
                                        +                .ToArray();
                                        +
                                        +            var everyone = await _userManager.Users
                                        +                .ToArrayAsync();
                                        +
                                        +            var model = new ManageUsersViewModel
                                        +            {
                                        +                Administrators = admins,
                                        +                Everyone = everyone
                                        +            };
                                        +
                                        +            return View(model);
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        Setting the Roles property on the [Authorize] attribute will ensure that the user must be logged in and assigned the Administrator role in order to view the page.

                                        +

                                        Next, create a view model:

                                        +

                                        Models/ManageUsersViewModel.cs

                                        +
                                        using System.Collections.Generic;
                                        +
                                        +namespace AspNetCoreTodo.Models
                                        +{
                                        +    public class ManageUsersViewModel
                                        +    {
                                        +        public ApplicationUser[] Administrators { get; set; }
                                        +
                                        +        public ApplicationUser[] Everyone { get; set;}
                                        +    }
                                        +}
                                        +
                                        +

                                        Finally, create a Views/ManageUsers folder and a view for the Index action:

                                        +

                                        Views/ManageUsers/Index.cshtml

                                        +
                                        @model ManageUsersViewModel
                                        +
                                        +@{
                                        +    ViewData["Title"] = "Manage users";
                                        +}
                                        +
                                        +<h2>@ViewData["Title"]</h2>
                                        +
                                        +<h3>Administrators</h3>
                                        +
                                        +<table class="table">
                                        +    <thead>
                                        +        <tr>
                                        +            <td>Id</td>
                                        +            <td>Email</td>
                                        +        </tr>
                                        +    </thead>
                                        +
                                        +    @foreach (var user in Model.Administrators)
                                        +    {
                                        +        <tr>
                                        +            <td>@user.Id</td>
                                        +            <td>@user.Email</td>
                                        +        </tr>
                                        +    }
                                        +</table>
                                        +
                                        +<h3>Everyone</h3>
                                        +
                                        +<table class="table">
                                        +    <thead>
                                        +        <tr>
                                        +            <td>Id</td>
                                        +            <td>Email</td>
                                        +        </tr>
                                        +    </thead>
                                        +
                                        +    @foreach (var user in Model.Everyone)
                                        +    {
                                        +        <tr>
                                        +            <td>@user.Id</td>
                                        +            <td>@user.Email</td>
                                        +        </tr>
                                        +    }
                                        +</table>
                                        +
                                        +

                                        Start up the application and try to access the /ManageUsers route while logged in as a normal user. You'll see this access denied page:

                                        +

                                        Access denied error

                                        +

                                        That's because users aren't assigned the Administrator role automatically.

                                        +

                                        Create a test administrator account

                                        +

                                        For obvious security reasons, it isn't possible for anyone to register a new administrator account themselves. In fact, the Administrator role doesn't even exist in the database yet!

                                        +

                                        You can add the Administrator role plus a test administrator account to the database the first time the application starts up. Adding first-time data to the database is called initializing or seeding the database.

                                        +

                                        Create a new class in the root of the project called SeedData:

                                        +

                                        SeedData.cs

                                        +
                                        using System;
                                        +using System.Linq;
                                        +using System.Threading.Tasks;
                                        +using AspNetCoreTodo.Models;
                                        +using Microsoft.AspNetCore.Identity;
                                        +using Microsoft.EntityFrameworkCore;
                                        +using Microsoft.Extensions.DependencyInjection;
                                        +
                                        +namespace AspNetCoreTodo
                                        +{
                                        +    public static class SeedData
                                        +    {
                                        +        public static async Task InitializeAsync(
                                        +            IServiceProvider services)
                                        +        {
                                        +            var roleManager = services
                                        +                .GetRequiredService<RoleManager<IdentityRole>>();
                                        +            await EnsureRolesAsync(roleManager);
                                        +
                                        +            var userManager = services
                                        +                .GetRequiredService<UserManager<ApplicationUser>>();
                                        +            await EnsureTestAdminAsync(userManager);
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        The InitializeAsync() method uses an IServiceProvider (the collection of services that is set up in the Startup.ConfigureServices() method) to get the RoleManager and UserManager from ASP.NET Core Identity.

                                        +

                                        Add two more methods below the InitializeAsync() method. First, the EnsureRolesAsync() method:

                                        +
                                        private static async Task EnsureRolesAsync(
                                        +    RoleManager<IdentityRole> roleManager)
                                        +{
                                        +    var alreadyExists = await roleManager
                                        +        .RoleExistsAsync(Constants.AdministratorRole);
                                        +
                                        +    if (alreadyExists) return;
                                        +
                                        +    await roleManager.CreateAsync(
                                        +        new IdentityRole(Constants.AdministratorRole));
                                        +}
                                        +
                                        +

                                        This method checks to see if an Administrator role exists in the database. If not, it creates one. Instead of repeatedly typing the string "Administrator", create a small class called Constants to hold the value:

                                        +

                                        Constants.cs

                                        +
                                        namespace AspNetCoreTodo
                                        +{
                                        +    public static class Constants
                                        +    {
                                        +        public const string AdministratorRole = "Administrator";
                                        +    }
                                        +}
                                        +
                                        +
                                        +

                                        If you want, you can update the ManageUsersController to use this constant value as well.

                                        +
                                        +

                                        Next, write the EnsureTestAdminAsync() method:

                                        +

                                        SeedData.cs

                                        +
                                        private static async Task EnsureTestAdminAsync(
                                        +    UserManager<ApplicationUser> userManager)
                                        +{
                                        +    var testAdmin = await userManager.Users
                                        +        .Where(x => x.UserName == "admin@todo.local")
                                        +        .SingleOrDefaultAsync();
                                        +
                                        +    if (testAdmin != null) return;
                                        +
                                        +    testAdmin = new ApplicationUser
                                        +    {
                                        +        UserName = "admin@todo.local",
                                        +        Email = "admin@todo.local"
                                        +    };
                                        +    await userManager.CreateAsync(
                                        +        testAdmin, "NotSecure123!!");
                                        +    await userManager.AddToRoleAsync(
                                        +        testAdmin, Constants.AdministratorRole);
                                        +}
                                        +
                                        +

                                        If there isn't already a user with the username admin@todo.local in the database, this method will create one and assign a temporary password. After you log in for the first time, you should change the account's password to something secure!

                                        +

                                        Next, you need to tell your application to run this logic when it starts up. Modify Program.cs and update Main() to call a new method, InitializeDatabase():

                                        +

                                        Program.cs

                                        +
                                        public static void Main(string[] args)
                                        +{
                                        +    var host = BuildWebHost(args);
                                        +    InitializeDatabase(host);
                                        +    host.Run();
                                        +}
                                        +
                                        +

                                        Then, add the new method to the class below Main():

                                        +
                                        private static void InitializeDatabase(IWebHost host)
                                        +{
                                        +    using (var scope = host.Services.CreateScope())
                                        +    {
                                        +        var services = scope.ServiceProvider;
                                        +
                                        +        try
                                        +        {
                                        +            SeedData.InitializeAsync(services).Wait();
                                        +        }
                                        +        catch (Exception ex)
                                        +        {
                                        +            var logger = services
                                        +                .GetRequiredService<ILogger<Program>>();
                                        +            logger.LogError(ex, "Error occurred seeding the DB.");
                                        +        }
                                        +    }
                                        +}
                                        +
                                        +

                                        Add this using statement to the top of the file:

                                        +
                                        using Microsoft.Extensions.DependencyInjection;
                                        +
                                        +

                                        This method gets the service collection that SeedData.InitializeAsync() needs and then runs the method to seed the database. If something goes wrong, an error is logged.

                                        +
                                        +

                                        Because InitializeAsync() returns a Task, the Wait() method must be used to make sure it finishes before the application starts up. You'd normally use await for this, but for technical reasons you can't use await in the Program class. This is a rare exception. You should use await everywhere else!

                                        +
                                        +

                                        When you start the application next, the admin@todo.local account will be created and assigned the Administrator role. Try logging in with this account, and navigating to http://localhost:5000/ManageUsers. You'll see a list of all users registered for the application.

                                        +
                                        +

                                        As an extra challenge, try adding more administration features to this page. For example, you could add a button that gives an administrator the ability to delete a user account.

                                        +
                                        +

                                        Check for authorization in a view

                                        +

                                        The [Authorize] attribute makes it easy to perform an authorization check in a controller or action method, but what if you need to check authorization in a view? For example, it would be nice to display a "Manage users" link in the navigation bar if the logged-in user is an administrator.

                                        +

                                        You can inject the UserManager directly into a view to do these types of authorization checks. To keep your views clean and organized, create a new partial view that will add an item to the navbar in the layout:

                                        +

                                        Views/Shared/_AdminActionsPartial.cshtml

                                        +
                                        @using Microsoft.AspNetCore.Identity
                                        +@using AspNetCoreTodo.Models
                                        +
                                        +@inject SignInManager<ApplicationUser> signInManager
                                        +@inject UserManager<ApplicationUser> userManager
                                        +
                                        +@if (signInManager.IsSignedIn(User))
                                        +{
                                        +    var currentUser = await userManager.GetUserAsync(User);
                                        +
                                        +    var isAdmin = currentUser != null
                                        +        && await userManager.IsInRoleAsync(
                                        +            currentUser,
                                        +            Constants.AdministratorRole);
                                        +
                                        +    if (isAdmin)
                                        +    {
                                        +        <ul class="nav navbar-nav navbar-right">
                                        +            <li>
                                        +                <a asp-controller="ManageUsers" 
                                        +                   asp-action="Index">
                                        +                   Manage Users
                                        +                </a>
                                        +            </li>
                                        +        </ul>
                                        +    }
                                        +}
                                        +
                                        +
                                        +

                                        It's conventional to name shared partial views starting with an _ underscore, but it's not required.

                                        +
                                        +

                                        This partial view first uses the SignInManager to quickly determine whether the user is logged in. If they aren't, the rest of the view code can be skipped. If there is a logged-in user, the UserManager is used to look up their details and perform an authorization check with IsInRoleAsync(). If all checks succeed and the user is an adminstrator, a Manage users link is added to the navbar.

                                        +

                                        To include this partial in the main layout, edit _Layout.cshtml and add it in the navbar section:

                                        +

                                        Views/Shared/_Layout.cshtml

                                        +
                                        <div class="navbar-collapse collapse">
                                        +    <ul class="nav navbar-nav">
                                        +        <!-- existing code here -->
                                        +    </ul>
                                        +    @await Html.PartialAsync("_LoginPartial")
                                        +    @await Html.PartialAsync("_AdminActionsPartial")
                                        +</div>
                                        +
                                        +

                                        When you log in with an administrator account, you'll now see a new item on the top right:

                                        +

                                        Manage Users link

                                        + + +
                                        + +
                                        +
                                        +
                                        + +

                                        results matching ""

                                        +
                                          + +
                                          +
                                          + +

                                          No results matching ""

                                          + +
                                          +
                                          +
                                          + +
                                          +
                                          + +
                                          + + + + + + + + + + + + + + +
                                          + + +
                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/security-and-identity/index.html b/book/chapters/security-and-identity/index.html new file mode 100644 index 0000000..1fdaf44 --- /dev/null +++ b/book/chapters/security-and-identity/index.html @@ -0,0 +1,781 @@ + + + + + + + 安全和身份 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                          +
                                          + + + + + + + + +
                                          + +
                                          + +
                                          + + + + + + + + +
                                          +
                                          + +
                                          +
                                          + +
                                          + +

                                          安全和身份

                                          +

                                          安全性是任何现代 Web 应用或 API 都要重点关注的。确保用户或顾客的数据安全并免遭黑客染指,是非常重要的。这个话题所涉甚广,包括了:

                                          +
                                            +
                                          • 过滤输入数据,避免 SQL注入
                                          • +
                                          • 防止利用表单(form)进行的跨域(CSRF)攻击
                                          • +
                                          • 使用 HTTPS(TLS),避免在 Internet 上传输的数据被窃取
                                          • +
                                          • 确保用户 输入密码 或者 通过社交媒体授权 登录时的安全性
                                          • +
                                          • 设计 密码重置 或 多重身份认证流程 时,考虑到安全性的因素
                                          • +
                                          +

                                          ASP.NET Core 有助于实现这些功能。前两个(防止SQL注入和跨域攻击)功能已经内置了,要开启 HTTPS,只需寥寥数行代码即可。本章主要关注安全性的 身份验证(identity) 方面:管理用户的账号(注册、登录),安全地验证用户(登录),并在验证后做出授权决策。

                                          +
                                          +

                                          验证 和 授权 二者常被混淆。验证 关心的是用户登录与否,而 授权 关心“用户在登录 能否做某些事”。你可以认为 验证 是在问:“我知道这个用户是谁吗?”,而 授权 问的是:“这个用户有权限做某件事吗?”

                                          +
                                          +

                                          你搭建项目的时候,应用了 MVC + Individual验证 项目模板,该模板中带有几个类,构建在 ASP.NET Core Identity(一个验证和身份系统,属于 ASP.NET Core 的一部分)之上。安装后,默认添加了通过 email 和密码进行登录的功能。

                                          +

                                          ASP.NET Core Identity 是什么?

                                          +

                                          ASP.NET Core Identity 是 ASP.NET Core 带来的身份系统,就像 ASP.NET Core 生态圈中的其它部分,它也是一组 NuGet 包,可以被安装在任何项目中(并且包括在默认的模板中了)。

                                          +

                                          ASP.NET Core Identity 处理用户账号的存储、散列并保存密码、还负责管理用户的角色。它支持 邮箱地址/密码 登录、多重身份验证、集成以 Google 和 Facebook 之类的身份提供者的 社交账号登录、以及借助 OAuth 2.0 和 OpenID Connect 等协议连接到其它的服务。

                                          +

                                          MVC + Individual验证 项目模板中的 Register 和 Login 视图 已经从 ASP.NET Core Identity 中受益,而且已经正常工作了,请试着注册一个账号并用它登录。

                                          +
                                          +

                                          Security and identity

                                          +

                                          Security is a major concern of any modern web application or API. It's important to keep your user or customer data safe and out of the hands of attackers. This is a very broad topic, involving things like:

                                          +
                                            +
                                          • Sanitizing data input to prevent SQL injection attacks
                                          • +
                                          • Preventing cross-domain (CSRF) attacks in forms
                                          • +
                                          • Using HTTPS (connection encryption) so data can't be intercepted as it travels over the Internet
                                          • +
                                          • Giving users a way to securely sign in with a password or other credentials
                                          • +
                                          • Designing password reset, account recovery, and multi-factor authentication flows
                                          • +
                                          +

                                          ASP.NET Core can help make all of this easier to implement. The first two (protection against SQL injection and cross-domain attacks) are already built-in, and you can add a few lines of code to enable HTTPS support. This chapter will mainly focus on the identity aspects of security: handling user accounts, authenticating (logging in) your users securely, and making authorization decisions once they are authenticated.

                                          +
                                          +

                                          Authentication and authorization are distinct ideas that are often confused. Authentication deals with whether a user is logged in, while authorization deals with what they are allowed to do after they log in. You can think of authentication as asking the question, "Do I know who this user is?" While authorization asks, "Does this user have permission to do X?"

                                          +
                                          +

                                          The MVC + Individual Authentication template you used to scaffold the project includes a number of classes built on top of ASP.NET Core Identity, an authentication and identity system that's part of ASP.NET Core. Out of the box, this adds the ability to log in with an email and password.

                                          +

                                          What is ASP.NET Core Identity?

                                          +

                                          ASP.NET Core Identity is the identity system that ships with ASP.NET Core. Like everything else in the ASP.NET Core ecosystem, it's a set of NuGet packages that can be installed in any project (and are already included if you use the default template).

                                          +

                                          ASP.NET Core Identity takes care of storing user accounts, hashing and storing passwords, and managing roles for users. It supports email/password login, multi-factor authentication, social login with providers like Google and Facebook, as well as connecting to other services using protocols like OAuth 2.0 and OpenID Connect.

                                          +

                                          The Register and Login views that ship with the MVC + Individual Authentication template already take advantage of ASP.NET Core Identity, and they already work! Try registering for an account and logging in.

                                          + + +
                                          + +
                                          +
                                          +
                                          + +

                                          results matching ""

                                          +
                                            + +
                                            +
                                            + +

                                            No results matching ""

                                            + +
                                            +
                                            +
                                            + +
                                            +
                                            + +
                                            + + + + + + + + + + + + + + +
                                            + + +
                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/security-and-identity/manage-users.png b/book/chapters/security-and-identity/manage-users.png new file mode 100644 index 0000000..fd7cff2 Binary files /dev/null and b/book/chapters/security-and-identity/manage-users.png differ diff --git a/book/chapters/security-and-identity/more-resources.html b/book/chapters/security-and-identity/more-resources.html new file mode 100644 index 0000000..803b942 --- /dev/null +++ b/book/chapters/security-and-identity/more-resources.html @@ -0,0 +1,767 @@ + + + + + + + 附加资源 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                            +
                                            + + + + + + + + +
                                            + +
                                            + +
                                            + + + + + + + + +
                                            +
                                            + +
                                            +
                                            + +
                                            + +

                                            附加资源

                                            +

                                            ASP.NET Core Identity 帮助你添加诸如 登录、注册 这些安全及身份鉴别的特性到程序里。dotnet new 指定的模板带给你预先构建好的视图和控制器,用以处理这些常见情景,以便你快速上手和运行。

                                            +

                                            ASP.NET Core Identity 还有很多其它功能,例如密码重置以及社交账户登录。位于 http://docs.asp.net 的文档非常适合用来学习这些特性。

                                            +

                                            ASP.NET Core Identity 的替代品

                                            +

                                            ASP.NET Core Identity 并非添加身份鉴别的唯一方式。另外一种选择是使用诸如 Azure Active Directory 以及 Okta 这种云端的服务为你的程序处理身份验证。你可以把这些选项看作发展的各个环节:

                                            +
                                              +
                                            • 自己处理安全性:不推荐,除非你是一个安全性方面的专家!
                                            • +
                                            • ASP.NET Core Identity:你免费获得随模板而来的大量代码,易于上手。对于进阶的情形,你依然需要写一部分代码,并维护一个数据库以存储用户信息。
                                            • +
                                            • 基于云的身份鉴别服务:这种服务既处理简单情况也处理复杂情况(多步验证、账号找回,),并且能极大地缩减你需要编写的代码量,和维护程序的工作量。另外,用户数据的敏感部分并不会保存在你的数据库里。
                                            • +
                                            +

                                            在本项目里,ASP.NET Core Identity 非常适合。对于更复杂的项目,我建议对各选项都作一些研究和尝试,以便找到你所需的最佳方案。

                                            +
                                            +

                                            More resources

                                            +

                                            ASP.NET Core Identity helps you add security and identity features like login and registration to your application. The dotnet new templates give you pre-built views and controllers that handle these common scenarios so you can get up and running quickly.

                                            +

                                            There's much more that ASP.NET Core Identity can do, such as password reset and social login. The documentation available at http://docs.asp.net is a fantastic resource for learning how to add these features.

                                            +

                                            Alternatives to ASP.NET Core Identity

                                            +

                                            ASP.NET Core Identity isn't the only way to add identity functionality. Another approach is to use a cloud-hosted identity service like Azure Active Directory B2C or Okta to handle identity for your application. You can think of these options as part of a progression:

                                            +
                                              +
                                            • Do-it-yourself security: Not recommended, unless you are a security expert!
                                            • +
                                            • ASP.NET Core Identity: You get a lot of code for free with the templates, which makes it pretty easy to get started. You'll still need to write some code for more advanced scenarios, and maintain a database to store user information.
                                            • +
                                            • Cloud-hosted identity services. The service handles both simple and advanced scenarios (multi-factor authentication, account recovery, federation), and significantly reduces the amount of code you need to write and maintain in your application. Plus, sensitive user data isn't stored in your own database.
                                            • +
                                            +

                                            For this project, ASP.NET Core Identity is a great fit. For more complex projects, I'd recommend doing some research and experimenting with both options to understand which is best for your use case.

                                            + + +
                                            + +
                                            +
                                            +
                                            + +

                                            results matching ""

                                            +
                                              + +
                                              +
                                              + +

                                              No results matching ""

                                              + +
                                              +
                                              +
                                              + +
                                              +
                                              + +
                                              + + + + + + + + + + + + + + +
                                              + + +
                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/security-and-identity/require-authentication.html b/book/chapters/security-and-identity/require-authentication.html new file mode 100644 index 0000000..990a77c --- /dev/null +++ b/book/chapters/security-and-identity/require-authentication.html @@ -0,0 +1,778 @@ + + + + + + + 提示认证 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                              +
                                              + + + + + + + + +
                                              + +
                                              + +
                                              + + + + + + + + +
                                              +
                                              + +
                                              +
                                              + +
                                              + +

                                              提示认证

                                              +

                                              在用户访问你程序中某些特定内容时,你通常都会要求他们登录。比如说,把主页向所有人展示是合理的(不管你有没有登录),但只在登录之后才向你展示待办事项列表。

                                              +

                                              ASP.NET Core 里,你可以使用 [Authorize] 属性,要求用户在访问指定的 action 或整个控制器时,要事先登录过。要为 TodoController 里的所有 action 添加认证提示,在这个控制器的第一行上面添加这个属性:

                                              +
                                              [Authorize]
                                              +public class TodoController : Controller
                                              +{
                                              +    // ...
                                              +}
                                              +
                                              +

                                              在文件顶部添加这条 using 语句:

                                              +
                                              using Microsoft.AspNetCore.Authorization;
                                              +
                                              +

                                              试着运行程序并在未登录的情况下访问 /todo。你会被自动重定向到登录页面:

                                              +
                                              +

                                              尽管属性的名字是授权(Authorize),我们在这里检查的其实是认证(authorization),而非检查授权,很抱歉会有这样的混淆。

                                              +
                                              +
                                              +

                                              Require authentication

                                              +

                                              Often you'll want to require the user to log in before they can access certain parts of your application. For example, it makes sense to show the home page to everyone (whether you're logged in or not), but only show your to-do list after you've logged in.

                                              +

                                              You can use the [Authorize] attribute in ASP.NET Core to require a logged-in user for a particular action, or an entire controller. To require authentication for all actions of the TodoController, add the attribute above the first line of the controller:

                                              +

                                              Controllers/TodoController.cs

                                              +
                                              [Authorize]
                                              +public class TodoController : Controller
                                              +{
                                              +    // ...
                                              +}
                                              +
                                              +

                                              Add this using statement at the top of the file:

                                              +
                                              using Microsoft.AspNetCore.Authorization;
                                              +
                                              +

                                              Try running the application and accessing /todo without being logged in. You'll be redirected to the login page automatically.

                                              +
                                              +

                                              The [Authorize] attribute is actually doing an authentication check here, not an authorization check (despite the name of the attribute). Later, you'll use the attribute to check both authentication and authorization.

                                              +
                                              + + +
                                              + +
                                              +
                                              +
                                              + +

                                              results matching ""

                                              +
                                                + +
                                                +
                                                + +

                                                No results matching ""

                                                + +
                                                +
                                                +
                                                + +
                                                +
                                                + +
                                                + + + + + + + + + + + + + + +
                                                + + +
                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/security-and-identity/using-identity-in-the-application.html b/book/chapters/security-and-identity/using-identity-in-the-application.html new file mode 100644 index 0000000..5cedad9 --- /dev/null +++ b/book/chapters/security-and-identity/using-identity-in-the-application.html @@ -0,0 +1,1069 @@ + + + + + + + 在程序中使用身份 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                +
                                                + + + + + + + + +
                                                + +
                                                + +
                                                + + + + + + + + +
                                                +
                                                + +
                                                +
                                                + +
                                                + +

                                                在程序中使用身份

                                                +

                                                待办事项列表依然由所有用户共享,因为 待办事项条目 并未关联到特定的用户。现在,[Authorize] 属性确保了见到 待办事项视图 的人一定登录过,在查询数据库的时候,你就可以按照登录者的身份进行过滤了。

                                                +

                                                首先,在 TodoController 中注入一个 UserManager<ApplicationUser>

                                                +

                                                Controllers/TodoController.cs

                                                +
                                                [Authorize]
                                                +public class TodoController : Controller
                                                +{
                                                +    private readonly ITodoItemService _todoItemService;
                                                +    private readonly UserManager<ApplicationUser> _userManager;
                                                +
                                                +    public TodoController(ITodoItemService todoItemService,
                                                +        UserManager<ApplicationUser> userManager)
                                                +    {
                                                +        _todoItemService = todoItemService;
                                                +        _userManager = userManager;
                                                +    }
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                还要在文件顶部加一个新的 using 语句:

                                                +
                                                using Microsoft.AspNetCore.Identity;
                                                +
                                                +

                                                UserManager 包含在 ASP.NET Core Identity 里。你可以用它在 Index action 里查找当前用户:

                                                +
                                                public async Task<IActionResult> Index()
                                                +{
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var items = await _todoItemService
                                                +        .GetIncompleteItemsAsync(currentUser);
                                                +
                                                +    var model = new TodoViewModel()
                                                +    {
                                                +        Items = items
                                                +    };
                                                +
                                                +    return View(model);
                                                +}
                                                +
                                                +

                                                这个 action 方法的顶部添加了新代码,这行代码用 UserManagerUser 属性中获取当前登录的用户——该属性在当前的 action 中有效:

                                                +
                                                var currentUser = await _userManager.GetUserAsync(User);
                                                +
                                                +

                                                如果当前用户已经登录, User 属性就持有一个轻量级的对象,包括了用户的一些(并非全部)信息。UserManager 使用它,通过 GetUserAsync() 方法在数据库里查找该用户的详细信息。

                                                +

                                                因为控制器使用了 [Authorize] 属性,currentUser 的值绝不应该是 null。无论如何,做个明智的检查都没错,以防万一嘛。如果用户信息没找到,你可以用 Challenge() 方法强制用户再次登录:

                                                +
                                                if (currentUser == null) return Challenge();
                                                +
                                                +

                                                既然你现在把一个 ApplicationUser 参数传给了 GetIncompleteItemsAsync(),就该修改 ITodoItemService 接口了:

                                                +

                                                Services/ITodoItemService.cs

                                                +
                                                public interface ITodoItemService
                                                +{
                                                +    Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +        ApplicationUser user);
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                而既然你修改了 ITodoItemService 接口,也就同样需要修改 TodoItemServiceGetIncompleteItemsAsync() 方法的签名:

                                                +

                                                Services/TodoItemService

                                                +
                                                public async Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +    ApplicationUser user)
                                                +
                                                +

                                                下一步是修改数据库查询,并添加一层过滤,仅显示当前用户创建的条目。但在做这些之前,你需要在数据库里添加一个新的字段。

                                                +

                                                修改数据库

                                                +

                                                你需要在 TodoItem 实体上添加一个新的属性,让每个条目都能够“记住”拥有它的用户:

                                                +

                                                Models/TodoItem.cs

                                                +
                                                public string UserId { get; set; }
                                                +
                                                +

                                                既然你修改了数据库上下文里的实体模型,就应该同步修改数据库。在终端窗口里用 dotnet ef 指令创建一个新的变更:

                                                +
                                                dotnet ef migrations add AddItemUserId
                                                +

                                                这个命令新建了一个名为 AddItemUserId 的变更,它将给 Items 表新添一个列,以反映你在 TodoItem 实体模型上所做的修改:

                                                +

                                                再通过 dotnet ef 指令应用到数据库:

                                                +
                                                dotnet ef database update
                                                +

                                                修改服务类

                                                +

                                                修改了数据库和数据库上下文,你就可以修改 TodoItemService 里的 GetIncompleteItemsAsync() 方法和其中的 Where 查询子句了:

                                                +

                                                Services/TodoItemService.cs

                                                +
                                                public async Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +    ApplicationUser user)
                                                +{
                                                +    return await _context.Items
                                                +        .Where(x => x.IsDone == false && x.UserId == user.Id)
                                                +        .ToArrayAsync();
                                                +}
                                                +
                                                +

                                                如果你现在运行程序并注册或者登录,你将又一次见到一个空的 待办事项列表。糟糕的是,你尝试添加的任何条目也都会凭空消失,因为你还没修改 添加条目 的操作,并把用户信息存储到条目里:

                                                +

                                                修改 添加条目 和 完成事项 操作

                                                +

                                                你需要在 AddItemMarkDone 这两个 action 的方法里,使用 UserManager 以获取当前用户,如同在 Index 里那样。

                                                +

                                                下面是 TodoController 控制器里对这两个方法的修改:

                                                +

                                                Controllers/TodoController.cs

                                                +
                                                [ValidateAntiForgeryToken]
                                                +public async Task<IActionResult> AddItem(TodoItem newItem)
                                                +{
                                                +    if (!ModelState.IsValid)
                                                +    {
                                                +        return RedirectToAction("Index");
                                                +    }
                                                +
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var successful = await _todoItemService
                                                +        .AddItemAsync(newItem, currentUser);
                                                +
                                                +    if (!successful)
                                                +    {
                                                +        return BadRequest("Could not add item.");
                                                +    }
                                                +
                                                +    return RedirectToAction("Index");
                                                +}
                                                +
                                                +[ValidateAntiForgeryToken]
                                                +public async Task<IActionResult> MarkDone(Guid id)
                                                +{
                                                +    if (id == Guid.Empty)
                                                +    {
                                                +        return RedirectToAction("Index");
                                                +    }
                                                +
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var successful = await _todoItemService
                                                +        .MarkDoneAsync(id, currentUser);
                                                +
                                                +    if (!successful)
                                                +    {
                                                +        return BadRequest("Could not mark item as done.");
                                                +    }
                                                +
                                                +    return RedirectToAction("Index");
                                                +}
                                                +
                                                +

                                                这两个服务方法现在也必须接受 ApplicationUser 参数了,修改 ITodoItemService 里定义的接口:

                                                +
                                                Task<bool> AddItemAsync(NewTodoItem newItem, ApplicationUser user);
                                                +
                                                +Task<bool> MarkDoneAsync(Guid id, ApplicationUser user);
                                                +
                                                +

                                                最后,修改 TodoItemService 里面的实现方法。在 AddItemAsync 方法里,构造一个 new TodoItem 的时候,设置 UserId 属性:

                                                +
                                                public async Task<bool> AddItemAsync(
                                                +    TodoItem newItem, ApplicationUser user)
                                                +{
                                                +    newItem.Id = Guid.NewGuid();
                                                +    newItem.IsDone = false;
                                                +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
                                                +    newItem.UserId = user.Id;
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                MarkDoneAsync 方法里的 Where 查询子句也需要检查用户的 ID,以防止恶意的用户通过猜测 ID 的方法把其他用户的事项标记为完成状态。

                                                +
                                                public async Task<bool> MarkDoneAsync(
                                                +    Guid id, ApplicationUser user)
                                                +{
                                                +    var item = await _context.Items
                                                +        .Where(x => x.Id == id && x.UserId == user.Id)
                                                +        .SingleOrDefaultAsync();
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                搞定!请用两个不同的账号尝试一下。待办事项条目现在是每个账户的私密信息了。

                                                +
                                                +

                                                Using identity in the application

                                                +

                                                The to-do list items themselves are still shared between all users, because the stored to-do entities aren't tied to a particular user. Now that the [Authorize] attribute ensures that you must be logged in to see the to-do view, you can filter the database query based on who is logged in.

                                                +

                                                First, inject a UserManager<ApplicationUser> into the TodoController:

                                                +

                                                Controllers/TodoController.cs

                                                +
                                                [Authorize]
                                                +public class TodoController : Controller
                                                +{
                                                +    private readonly ITodoItemService _todoItemService;
                                                +    private readonly UserManager<ApplicationUser> _userManager;
                                                +
                                                +    public TodoController(ITodoItemService todoItemService,
                                                +        UserManager<ApplicationUser> userManager)
                                                +    {
                                                +        _todoItemService = todoItemService;
                                                +        _userManager = userManager;
                                                +    }
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                You'll need to add a new using statement at the top:

                                                +
                                                using Microsoft.AspNetCore.Identity;
                                                +
                                                +

                                                The UserManager class is part of ASP.NET Core Identity. You can use it to get the current user in the Index action:

                                                +
                                                public async Task<IActionResult> Index()
                                                +{
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var items = await _todoItemService
                                                +        .GetIncompleteItemsAsync(currentUser);
                                                +
                                                +    var model = new TodoViewModel()
                                                +    {
                                                +        Items = items
                                                +    };
                                                +
                                                +    return View(model);
                                                +}
                                                +
                                                +

                                                The new code at the top of the action method uses the UserManager to look up the current user from the User property available in the action:

                                                +
                                                var currentUser = await _userManager.GetUserAsync(User);
                                                +
                                                +

                                                If there is a logged-in user, the User property contains a lightweight object with some (but not all) of the user's information. The UserManager uses this to look up the full user details in the database via the GetUserAsync() method.

                                                +

                                                The value of currentUser should never be null, because the [Authorize] attribute is present on the controller. However, it's a good idea to do a sanity check, just in case. You can use the Challenge() method to force the user to log in again if their information is missing:

                                                +
                                                if (currentUser == null) return Challenge();
                                                +
                                                +

                                                Since you're now passing an ApplicationUser parameter to GetIncompleteItemsAsync(), you'll need to update the ITodoItemService interface:

                                                +

                                                Services/ITodoItemService.cs

                                                +
                                                public interface ITodoItemService
                                                +{
                                                +    Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +        ApplicationUser user);
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                Since you changed the ITodoItemService interface, you also need to update the signature of the GetIncompleteItemsAsync() method in the TodoItemService:

                                                +

                                                Services/TodoItemService

                                                +
                                                public async Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +    ApplicationUser user)
                                                +
                                                +

                                                The next step is to update the database query and add a filter to show only the items created by the current user. Before you can do that, you need to add a new property to the database.

                                                +

                                                Update the database

                                                +

                                                You'll need to add a new property to the TodoItem entity model so each item can "remember" the user that owns it:

                                                +

                                                Models/TodoItem.cs

                                                +
                                                public string UserId { get; set; }
                                                +
                                                +

                                                Since you updated the entity model used by the database context, you also need to migrate the database. Create a new migration using dotnet ef in the terminal:

                                                +
                                                dotnet ef migrations add AddItemUserId
                                                +

                                                This creates a new migration called AddItemUserId which will add a new column to the Items table, mirroring the change you made to the TodoItem model.

                                                +

                                                Use dotnet ef again to apply it to the database:

                                                +
                                                dotnet ef database update
                                                +

                                                Update the service class

                                                +

                                                With the database and the database context updated, you can now update the GetIncompleteItemsAsync() method in the TodoItemService and add another clause to the Where statement:

                                                +

                                                Services/TodoItemService.cs

                                                +
                                                public async Task<TodoItem[]> GetIncompleteItemsAsync(
                                                +    ApplicationUser user)
                                                +{
                                                +    return await _context.Items
                                                +        .Where(x => x.IsDone == false && x.UserId == user.Id)
                                                +        .ToArrayAsync();
                                                +}
                                                +
                                                +

                                                If you run the application and register or log in, you'll see an empty to-do list once again. Unfortunately, any items you try to add disappear into the ether, because you haven't updated the AddItem action to be user-aware yet.

                                                +

                                                Update the AddItem and MarkDone actions

                                                +

                                                You'll need to use the UserManager to get the current user in the AddItem and MarkDone action methods, just like you did in Index.

                                                +

                                                Here are both updated methods:

                                                +

                                                Controllers/TodoController.cs

                                                +
                                                [ValidateAntiForgeryToken]
                                                +public async Task<IActionResult> AddItem(TodoItem newItem)
                                                +{
                                                +    if (!ModelState.IsValid)
                                                +    {
                                                +        return RedirectToAction("Index");
                                                +    }
                                                +
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var successful = await _todoItemService
                                                +        .AddItemAsync(newItem, currentUser);
                                                +
                                                +    if (!successful)
                                                +    {
                                                +        return BadRequest("Could not add item.");
                                                +    }
                                                +
                                                +    return RedirectToAction("Index");
                                                +}
                                                +
                                                +[ValidateAntiForgeryToken]
                                                +public async Task<IActionResult> MarkDone(Guid id)
                                                +{
                                                +    if (id == Guid.Empty)
                                                +    {
                                                +        return RedirectToAction("Index");
                                                +    }
                                                +
                                                +    var currentUser = await _userManager.GetUserAsync(User);
                                                +    if (currentUser == null) return Challenge();
                                                +
                                                +    var successful = await _todoItemService
                                                +        .MarkDoneAsync(id, currentUser);
                                                +
                                                +    if (!successful)
                                                +    {
                                                +        return BadRequest("Could not mark item as done.");
                                                +    }
                                                +
                                                +    return RedirectToAction("Index");
                                                +}
                                                +
                                                +

                                                Both service methods must now accept an ApplicationUser parameter. Update the interface definition in ITodoItemService:

                                                +
                                                Task<bool> AddItemAsync(TodoItem newItem, ApplicationUser user);
                                                +
                                                +Task<bool> MarkDoneAsync(Guid id, ApplicationUser user);
                                                +
                                                +

                                                And finally, update the service method implementations in the TodoItemService. In AddItemAsync method, set the UserId property when you construct a new TodoItem:

                                                +
                                                public async Task<bool> AddItemAsync(
                                                +    TodoItem newItem, ApplicationUser user)
                                                +{
                                                +    newItem.Id = Guid.NewGuid();
                                                +    newItem.IsDone = false;
                                                +    newItem.DueAt = DateTimeOffset.Now.AddDays(3);
                                                +    newItem.UserId = user.Id;
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                The Where clause in the MarkDoneAsync method also needs to check for the user's ID, so a rogue user can't complete someone else's items by guessing their IDs:

                                                +
                                                public async Task<bool> MarkDoneAsync(
                                                +    Guid id, ApplicationUser user)
                                                +{
                                                +    var item = await _context.Items
                                                +        .Where(x => x.Id == id && x.UserId == user.Id)
                                                +        .SingleOrDefaultAsync();
                                                +
                                                +    // ...
                                                +}
                                                +
                                                +

                                                All done! Try using the application with two different user accounts. The to-do items stay private for each account.

                                                + + +
                                                + +
                                                +
                                                +
                                                + +

                                                results matching ""

                                                +
                                                  + +
                                                  +
                                                  + +

                                                  No results matching ""

                                                  + +
                                                  +
                                                  +
                                                  + +
                                                  +
                                                  + +
                                                  + + + + + + + + + + + + + + +
                                                  + + +
                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/use-a-database/connect-to-a-database.html b/book/chapters/use-a-database/connect-to-a-database.html new file mode 100644 index 0000000..7c9e8de --- /dev/null +++ b/book/chapters/use-a-database/connect-to-a-database.html @@ -0,0 +1,783 @@ + + + + + + + 连接数据库 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                  +
                                                  + + + + + + + + +
                                                  + +
                                                  + +
                                                  + + + + + + + + +
                                                  +
                                                  + +
                                                  +
                                                  + +
                                                  + +

                                                  连接数据库

                                                  +

                                                  通过 Entity Framework Core 连接数据库,需要做一些准备工作。因为你通过 dotnet new 让项目使用了 MVC + Individual认证 项目模板,这些准备已经就绪了:

                                                  +
                                                    +
                                                  • Entity Framework Core包 这些都默认包括在了所有 ASP.NET Core 项目中。

                                                    +
                                                  • +
                                                  • 数据库(必须地呀) 经由 dotnet new 指令,在项目的根目录下生成了小型的 SQLite 数据库文件 app.db。 SQLite 是一个轻量级数据库引擎,可以运行在你的机器上而不必安装任何额外工具,所以在开发环境下使用起来既方便又快捷。

                                                    +
                                                  • +
                                                  • 数据库上下文 数据库上下文(database context)是一个 C# 类提供的数据库入口点。 你的代码就是通过它与数据库交互,进行读写的。Data/ApplicationDbContext.cs 文件里,就保存着一个很基本的数据库上下文。

                                                    +
                                                  • +
                                                  • 连接字符串 无论你连接本地文件数据库(SQLite)还是位于其它主机的数据库,都需要定义一个字符串,其中包含 数据库的名字 或 用来连接的数据库地址。 这一项已经在 appsettings.json 文件里为你设置好了: SQLite 数据库的 连接字符串 是 DataSource=app.db

                                                    +
                                                  • +
                                                  +

                                                  Entity Framework Core 借助 数据库上下文、连接字符串 与数据库建立连接。你需要在 Startup 类里的 ConfigureServices 方法中为 Entity Framework Core 指定所用的 数据库上下文、连接字符串和数据库类型。感谢项目模板:

                                                  +
                                                  services.AddDbContext<ApplicationDbContext>(options =>
                                                  +    options.UseSqlite(
                                                  +        Configuration.GetConnectionString("DefaultConnection")));
                                                  +
                                                  +

                                                  这段代码把 ApplicationDbContext 添加到服务容器里,并通过配置(appsettings.json)中的 连接字符串 指定 Entity Framework Core 使用 SQLite 数据库。

                                                  +

                                                  如你所见,dotnet new 为你完成了很多工作! 数据库已经配置好待用了。但是还没有表用于保存 待办事项条目。为了能存储 TodoItem 实体,你需要修改数据库上下文,并对数据库进行变更。

                                                  +
                                                  +

                                                  Connect to a database

                                                  +

                                                  There are a few things you need to use Entity Framework Core to connect to a database. Since you used dotnet new and the MVC + Individual Auth template to set your project, you've already got them:

                                                  +
                                                    +
                                                  • The Entity Framework Core packages. These are included by default in all ASP.NET Core projects.

                                                    +
                                                  • +
                                                  • A database (naturally). The app.db file in the project root directory is a small SQLite database created for you by dotnet new. SQLite is a lightweight database engine that can run without requiring you to install any extra tools on your machine, so it's easy and quick to use in development.

                                                    +
                                                  • +
                                                  • A database context class. The database context is a C# class that provides an entry point into the database. It's how your code will interact with the database to read and save items. A basic context class already exists in the Data/ApplicationDbContext.cs file.

                                                    +
                                                  • +
                                                  • A connection string. Whether you are connecting to a local file database (like SQLite) or a database hosted elsewhere, you'll define a string that contains the name or address of the database to connect to. This is already set up for you in the appsettings.json file: the connection string for the SQLite database is DataSource=app.db.

                                                    +
                                                  • +
                                                  +

                                                  Entity Framework Core uses the database context, together with the connection string, to establish a connection to the database. You need to tell Entity Framework Core which context, connection string, and database provider to use in the ConfigureServices method of the Startup class. Here's what's defined for you, thanks to the template:

                                                  +
                                                  services.AddDbContext<ApplicationDbContext>(options =>
                                                  +    options.UseSqlite(
                                                  +        Configuration.GetConnectionString("DefaultConnection")));
                                                  +
                                                  +

                                                  This code adds the ApplicationDbContext to the service container, and tells Entity Framework Core to use the SQLite database provider, with the connection string from configuration (appsettings.json).

                                                  +

                                                  As you can see, dotnet new creates a lot of stuff for you! The database is set up and ready to be used. However, it doesn't have any tables for storing to-do items. In order to store your TodoItem entities, you'll need to update the context and migrate the database.

                                                  + + +
                                                  + +
                                                  +
                                                  +
                                                  + +

                                                  results matching ""

                                                  +
                                                    + +
                                                    +
                                                    + +

                                                    No results matching ""

                                                    + +
                                                    +
                                                    +
                                                    + +
                                                    +
                                                    + +
                                                    + + + + + + + + + + + + + + +
                                                    + + +
                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/use-a-database/create-migration.html b/book/chapters/use-a-database/create-migration.html new file mode 100644 index 0000000..8a9670a --- /dev/null +++ b/book/chapters/use-a-database/create-migration.html @@ -0,0 +1,879 @@ + + + + + + + 创建变更 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                    +
                                                    + + + + + + + + +
                                                    + +
                                                    + +
                                                    + + + + + + + + +
                                                    +
                                                    + +
                                                    +
                                                    + +
                                                    + +

                                                    创建变更

                                                    +

                                                    变更按时间记录着数据库结构的变化。它们使以下的操作成为可能:撤销(回滚)一部分修改,或创建一个新的数据库——与原有数据库结构一致。有了变更,你有一个完整的数据库历史,记录着对数据库的修改,例如添加或删除字段(以及整个表)。

                                                    +

                                                    上一章节里,你在数据库上下文里添加了一个 Items 集合。既然现在数据库上下文里包括了一个集合(或者说表),而数据库里没有它,你就需要创建一个变更来修改数据库:

                                                    +
                                                    dotnet ef migrations add AddItems
                                                    +

                                                    这行代码通过检查你在数据库上下文里所做的修改,创建了一个新的变更,名为 AddItems

                                                    +
                                                    +

                                                    如果你看到这样的报错: No executable found matching command "dotnet-ef",请确保在正确的目录下。 这些命令必须在项目的根目录下执行(Program.cs所在目录)。

                                                    +

                                                    译者注:如果你使用 3.0 或以上版本的 SDK,需要手动安装 dotnet-ef 工具,原因请参考 dotnet ef not found in .NET Core 3,使用如下命令进行安装。

                                                    +
                                                    +
                                                    dotnet tool install --global dotnet-ef
                                                    +
                                                    +

                                                    如果你打开 Data/Migrations 目录,你将会看到:

                                                    +

                                                    Multiple migrations

                                                    +

                                                    第一个变更文件(00_CreateIdentitySchema.cs),是在你执行 dotnet new 的时候创建并应用的。 变更 AddItem 带有你创建它时候的时间戳。

                                                    +
                                                    +

                                                    你可以用 dotnet ef migrations list 命令查看一个变更的列表。

                                                    +
                                                    +

                                                    如果你打开一个变更文件,可以看到两个方法,名字分别是 UpDown:

                                                    +

                                                    Data/Migrations/_AddItems.cs

                                                    +
                                                    protected override void Up(MigrationBuilder migrationBuilder)
                                                    +{
                                                    +    // (... some code)
                                                    +
                                                    +    migrationBuilder.CreateTable(
                                                    +        name: "Items",
                                                    +        columns: table => new
                                                    +        {
                                                    +            Id = table.Column<Guid>(nullable: false),
                                                    +            DueAt = table.Column<DateTimeOffset>(nullable: true),
                                                    +            IsDone = table.Column<bool>(nullable: false),
                                                    +            Title = table.Column<string>(nullable: true)
                                                    +        },
                                                    +        constraints: table =>
                                                    +        {
                                                    +            table.PrimaryKey("PK_Items", x => x.Id);
                                                    +        });
                                                    +
                                                    +    // (some code...)
                                                    +}
                                                    +
                                                    +protected override void Down(MigrationBuilder migrationBuilder)
                                                    +{
                                                    +    // (... some code)
                                                    +
                                                    +    migrationBuilder.DropTable(
                                                    +        name: "Items");
                                                    +
                                                    +    // (some code...)
                                                    +}
                                                    +
                                                    +

                                                    将变更应用到数据库时 Up 方法将会被执行。因为你在数据库上下文里添加了一个 DbSet<TodoItem> ,应用变更时 Entity Framework Core 会创建一个 Items 表(其列与 TodoItem 相匹配)。

                                                    +

                                                    Down 方法刚好相反:当你需要撤销(回滚)变更时,Items 表将会被丢弃。

                                                    +

                                                    绕开 SQLite 的局限性

                                                    +

                                                    如果你按原样执行变更,会遭遇 SQLite 数据库的局限性带来的问题,要修复它,可以这样绕开:

                                                    +
                                                      +
                                                    • Up 方法里注释掉或删除 migrationBuilder.AddForeignKey 那些行。
                                                    • +
                                                    • Down 方法里注释掉或删除 migrationBuilder.DropForeignKey 那些行。
                                                    • +
                                                    +

                                                    如果你使用完善的数据库,如 SQL Server 或者 MySQL,就不需要这样(有点旁门左道的)绕弯了。

                                                    +

                                                    应用变更

                                                    +

                                                    创建变更的最后一步,就是要应用它(们)到数据库中:

                                                    +
                                                    dotnet ef database update
                                                    +

                                                    这条命令会导致 Entity Framework Core 在数据库中创建 Items 表。

                                                    +
                                                    +

                                                    如果你想回滚数据库,你可以提供 上一个 迁移的名称:dotnet ef database update CreateIdentitySchema 这将运行所有迟于你指定变更的 Down 方法。
                                                    如果你需要完整的抹掉数据库并重新开始,运行 dotnet ef database drop 然后运行 dotnet ef database update,重新搭建数据库并应用到到当前的变更。

                                                    +
                                                    +

                                                    搞定! 数据库和上下文都已就绪。接下来,你将在服务层使用上下文。

                                                    +
                                                    +

                                                    Create a migration

                                                    +

                                                    Migrations keep track of changes to the database structure over time. They make it possible to undo (roll back) a set of changes, or create a second database with the same structure as the first. With migrations, you have a full history of modifications like adding or removing columns (and entire tables).

                                                    +

                                                    In the previous chapter, you added an Items set to the context. Since the context now includes a set (or table) that doesn't exist in the database, you need to create a migration to update the database:

                                                    +
                                                    dotnet ef migrations add AddItems
                                                    +

                                                    This creates a new migration called AddItems by examining any changes you've made to the context.

                                                    +
                                                    +

                                                    If you get an error like No executable found matching command "dotnet-ef", make sure you're in the right directory. These commands must be run from the project root directory (where the Program.cs file is).

                                                    +
                                                    +

                                                    If you open up the Data/Migrations directory, you'll see a few files:

                                                    +

                                                    Multiple migrations

                                                    +

                                                    The first migration file (with a name like 00_CreateIdentitySchema.cs) was created and applied for you way back when you ran dotnet new. Your new AddItem migration is prefixed with a timestamp when you create it.

                                                    +
                                                    +

                                                    You can see a list of migrations with dotnet ef migrations list.

                                                    +
                                                    +

                                                    If you open your migration file, you'll see two methods called Up and Down:

                                                    +

                                                    Data/Migrations/_AddItems.cs

                                                    +
                                                    protected override void Up(MigrationBuilder migrationBuilder)
                                                    +{
                                                    +    // (... some code)
                                                    +
                                                    +    migrationBuilder.CreateTable(
                                                    +        name: "Items",
                                                    +        columns: table => new
                                                    +        {
                                                    +            Id = table.Column<Guid>(nullable: false),
                                                    +            DueAt = table.Column<DateTimeOffset>(nullable: true),
                                                    +            IsDone = table.Column<bool>(nullable: false),
                                                    +            Title = table.Column<string>(nullable: true)
                                                    +        },
                                                    +        constraints: table =>
                                                    +        {
                                                    +            table.PrimaryKey("PK_Items", x => x.Id);
                                                    +        });
                                                    +
                                                    +    // (some code...)
                                                    +}
                                                    +
                                                    +protected override void Down(MigrationBuilder migrationBuilder)
                                                    +{
                                                    +    // (... some code)
                                                    +
                                                    +    migrationBuilder.DropTable(
                                                    +        name: "Items");
                                                    +
                                                    +    // (some code...)
                                                    +}
                                                    +
                                                    +

                                                    The Up method runs when you apply the migration to the database. Since you added a DbSet<TodoItem> to the database context, Entity Framework Core will create an Items table (with columns that match a TodoItem) when you apply the migration.

                                                    +

                                                    The Down method does the opposite: if you need to undo (roll back) the migration, the Items table will be dropped.

                                                    +

                                                    Workaround for SQLite limitations

                                                    +

                                                    There are some limitations of SQLite that get in the way if you try to run the migration as-is. Until this problem is fixed, use this workaround:

                                                    +
                                                      +
                                                    • Comment out or remove the migrationBuilder.AddForeignKey lines in the Up method.
                                                    • +
                                                    • Comment out or remove any migrationBuilder.DropForeignKey lines in the Down method.
                                                    • +
                                                    +

                                                    If you use a full-fledged SQL database, like SQL Server or MySQL, this won't be an issue and you won't need to do this (admittedly hackish) workaround.

                                                    +

                                                    Apply the migration

                                                    +

                                                    The final step after creating one (or more) migrations is to actually apply them to the database:

                                                    +
                                                    dotnet ef database update
                                                    +

                                                    This command will cause Entity Framework Core to create the Items table in the database.

                                                    +
                                                    +

                                                    If you want to roll back the database, you can provide the name of the previous migration: +dotnet ef database update CreateIdentitySchema +This will run the Down methods of any migrations newer than the migration you specify.

                                                    +

                                                    If you need to completely erase the database and start over, run dotnet ef database drop followed by dotnet ef database update to re-scaffold the database and bring it up to the current migration.

                                                    +
                                                    +

                                                    That's it! Both the database and the context are ready to go. Next, you'll use the context in your service layer.

                                                    + + +
                                                    + +
                                                    +
                                                    +
                                                    + +

                                                    results matching ""

                                                    +
                                                      + +
                                                      +
                                                      + +

                                                      No results matching ""

                                                      + +
                                                      +
                                                      +
                                                      + +
                                                      +
                                                      + +
                                                      + + + + + + + + + + + + + + +
                                                      + + +
                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/use-a-database/create-service-class.html b/book/chapters/use-a-database/create-service-class.html new file mode 100644 index 0000000..8245e95 --- /dev/null +++ b/book/chapters/use-a-database/create-service-class.html @@ -0,0 +1,869 @@ + + + + + + + 创建服务类 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                      +
                                                      + + + + + + + + +
                                                      + +
                                                      + +
                                                      + + + + + + + + +
                                                      +
                                                      + +
                                                      +
                                                      + +
                                                      + +

                                                      创建服务类

                                                      +

                                                      回顾 MVC基础 章节, 你创建了一个 FakeTodoItemService,其中包含硬编码的 待办事项。现在你有了数据库上下文,就可以创建一个新的服务类,从而借助 Entity Framework Core 从数据库中获取真实内容。

                                                      +

                                                      删除文件 FakeTodoItemService.cs,并创建一个新文件:

                                                      +

                                                      Services/TodoItemService.cs

                                                      +
                                                      using System;
                                                      +using System.Collections.Generic;
                                                      +using System.Linq;
                                                      +using System.Threading.Tasks;
                                                      +using AspNetCoreTodo.Data;
                                                      +using AspNetCoreTodo.Models;
                                                      +using Microsoft.EntityFrameworkCore;
                                                      +
                                                      +namespace AspNetCoreTodo.Services
                                                      +{
                                                      +    public class TodoItemService : ITodoItemService
                                                      +    {
                                                      +        private readonly ApplicationDbContext _context;
                                                      +
                                                      +        public TodoItemService(ApplicationDbContext context)
                                                      +        {
                                                      +            _context = context;
                                                      +        }
                                                      +
                                                      +        public async Task<TodoItem[]> GetIncompleteItemsAsync()
                                                      +        {
                                                      +            var items = await _context.Items
                                                      +                .Where(x => x.IsDone == false)
                                                      +                .ToArrayAsync();
                                                      +            return items;
                                                      +        }
                                                      +    }
                                                      +}
                                                      +
                                                      +

                                                      你应该注意到相同的依赖注入模式,如你在 MVC基础 章节所见到的那样,只是这次被注入的服务是 ApplicationDbContextApplicationDbContext 已经在ConfigureServices 方法里被添加到服务容器里,所以在这里可以直接使用。

                                                      +

                                                      让我们仔细探究 GetIncompleteItemsAsync 方法的代码。首先,它用数据库上下文中的 Items 的属性获取 DbSet 中所有的 待办事项:

                                                      +
                                                      var items = await _context.Items
                                                      +
                                                      +

                                                      然后,Where 用于过滤出所有“未完成”的条目:

                                                      +
                                                      .Where(x => x.IsDone == false)
                                                      +
                                                      +

                                                      Where 方法来自 C# 里的一个名为 LINQ(language integrated query) 的特性,它受到函数式编程的启发,简化了在程序代码里数据库查询的写法。在底层,Entity Framework Core 把这个方法翻译成一个类似的语句 SELECT * FROM Items WHERE IsDone = 0,或在 NoSQL数据库 里的一个等效查询。

                                                      +

                                                      最后,ToArrayAsync 方法吩咐 Entity Framework Core 取出所有过滤后的数据,并作为一个数组返回。ToArrayAsync 是异步的(返回一个 Task),所以必须执行一次 await(等待) 以获取其中的值。

                                                      +

                                                      如果想使这个方法变简短一点,你可以删除中间变量 items,直接返回查询结果(跟原来功能一样):

                                                      +
                                                      public async Task<TodoItem[]> GetIncompleteItemsAsync()
                                                      +{
                                                      +    return await _context.Items
                                                      +        .Where(x => x.IsDone == false)
                                                      +        .ToArrayAsync();
                                                      +}
                                                      +
                                                      +

                                                      修改服务容器

                                                      +

                                                      由于你删除了 FakeTodoItemService 类,就需要修改 ConfigureServices 方法里配置ITodoItemService 接口的那一行:

                                                      +
                                                      services.AddScoped<ITodoItemService, TodoItemService>();
                                                      +
                                                      +

                                                      AddScoped 会以 scoped 的生命周期把你的服务添加到容器里。这意味着每次 web 请求中,一个 TodoItemService 类的新实例就会被创建出来。这对于那些跟数据库打交道的类来说,是必要的。

                                                      +
                                                      +

                                                      添加一个服务类去跟 Entity Framework Core(以及你的数据库)打交道,如果用单件(或其它)生命周期会引发麻烦,原因在于 Entity Framework Core 底层以请求为单位管数据库连接。要避免这些问题,请在跟 Entity Framework Core 打交道的服务上,始终采用 scoped 生命周期。

                                                      +
                                                      +

                                                      依赖于被注入的 ITodoItemServiceTodoController 将幸福地对这个变化毫无察觉,但在底层,你将使用 Entity Framework Core 与真实的数据库进行交互!

                                                      +

                                                      试试看

                                                      +

                                                      启动程序并导航至 http://localhost:5000/todo。硬编码的那些条目不见了,你的程序对数据库发起了真正的查询。数据库里刚好还没有任何已存的 待办事项条目,所以页面目前还是空白的。

                                                      +

                                                      下一章,你将在程序中添加更多的功能,从“创建新 待办事项 的能力”开始。

                                                      +
                                                      +

                                                      Create a new service class

                                                      +

                                                      Back in the MVC basics chapter, you created a FakeTodoItemService that contained hard-coded to-do items. Now that you have a database context, you can create a new service class that will use Entity Framework Core to get the real items from the database.

                                                      +

                                                      Delete the FakeTodoItemService.cs file, and create a new file:

                                                      +

                                                      Services/TodoItemService.cs

                                                      +
                                                      using System;
                                                      +using System.Collections.Generic;
                                                      +using System.Linq;
                                                      +using System.Threading.Tasks;
                                                      +using AspNetCoreTodo.Data;
                                                      +using AspNetCoreTodo.Models;
                                                      +using Microsoft.EntityFrameworkCore;
                                                      +
                                                      +namespace AspNetCoreTodo.Services
                                                      +{
                                                      +    public class TodoItemService : ITodoItemService
                                                      +    {
                                                      +        private readonly ApplicationDbContext _context;
                                                      +
                                                      +        public TodoItemService(ApplicationDbContext context)
                                                      +        {
                                                      +            _context = context;
                                                      +        }
                                                      +
                                                      +        public async Task<TodoItem[]> GetIncompleteItemsAsync()
                                                      +        {
                                                      +            var items = await _context.Items
                                                      +                .Where(x => x.IsDone == false)
                                                      +                .ToArrayAsync();
                                                      +            return items;
                                                      +        }
                                                      +    }
                                                      +}
                                                      +
                                                      +

                                                      You'll notice the same dependency injection pattern here that you saw in the MVC basics chapter, except this time it's the ApplicationDbContext that's getting injected. The ApplicationDbContext is already being added to the service container in the ConfigureServices method, so it's available for injection here.

                                                      +

                                                      Let's take a closer look at the code of the GetIncompleteItemsAsync method. First, it uses the Items property of the context to access all the to-do items in the DbSet:

                                                      +
                                                      var items = await _context.Items
                                                      +
                                                      +

                                                      Then, the Where method is used to filter only the items that are not complete:

                                                      +
                                                      .Where(x => x.IsDone == false)
                                                      +
                                                      +

                                                      The Where method is a feature of C# called LINQ (language integrated query), which takes inspiration from functional programming and makes it easy to express database queries in code. Under the hood, Entity Framework Core translates the Where method into a statement like SELECT * FROM Items WHERE IsDone = 0, or an equivalent query document in a NoSQL database.

                                                      +

                                                      Finally, the ToArrayAsync method tells Entity Framework Core to get all the entities that matched the filter and return them as an array. The ToArrayAsync method is asynchronous (it returns a Task), so it must be awaited to get its value.

                                                      +

                                                      To make the method a little shorter, you can remove the intermediate items variable and just return the result of the query directly (which does the same thing):

                                                      +
                                                      public async Task<TodoItem[]> GetIncompleteItemsAsync()
                                                      +{
                                                      +    return await _context.Items
                                                      +        .Where(x => x.IsDone == false)
                                                      +        .ToArrayAsync();
                                                      +}
                                                      +
                                                      +

                                                      Update the service container

                                                      +

                                                      Because you deleted the FakeTodoItemService class, you'll need to update the line in ConfigureServices that is wiring up the ITodoItemService interface:

                                                      +
                                                      services.AddScoped<ITodoItemService, TodoItemService>();
                                                      +
                                                      +

                                                      AddScoped adds your service to the service container using the scoped lifecycle. This means that a new instance of the TodoItemService class will be created during each web request. This is required for service classes that interact with a database.

                                                      +
                                                      +

                                                      Adding a service class that interacts with Entity Framework Core (and your database) with the singleton lifecycle (or other lifecycles) can cause problems, because of how Entity Framework Core manages database connections per request under the hood. To avoid that, always use the scoped lifecycle for services that interact with Entity Framework Core.

                                                      +
                                                      +

                                                      The TodoController that depends on an injected ITodoItemService will be blissfully unaware of the change in services classes, but under the hood it'll be using Entity Framework Core and talking to a real database!

                                                      +

                                                      Test it out

                                                      +

                                                      Start up the application and navigate to http://localhost:5000/todo. The fake items are gone, and your application is making real queries to the database. There doesn't happen to be any saved to-do items, so it's blank for now.

                                                      +

                                                      In the next chapter, you'll add more features to the application, starting with the ability to create new to-do items.

                                                      + + +
                                                      + +
                                                      +
                                                      +
                                                      + +

                                                      results matching ""

                                                      +
                                                        + +
                                                        +
                                                        + +

                                                        No results matching ""

                                                        + +
                                                        +
                                                        +
                                                        + +
                                                        +
                                                        + +
                                                        + + + + + + + + + + + + + + +
                                                        + + +
                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/use-a-database/index.html b/book/chapters/use-a-database/index.html new file mode 100644 index 0000000..7b75b8f --- /dev/null +++ b/book/chapters/use-a-database/index.html @@ -0,0 +1,759 @@ + + + + + + + 运用数据库 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                        +
                                                        + + + + + + + + +
                                                        + +
                                                        + +
                                                        + + + + + + + + +
                                                        +
                                                        + +
                                                        +
                                                        + +
                                                        + +

                                                        运用数据库

                                                        +

                                                        与数据库交互的代码写起来坑很多。除非你对其了如指掌,否则在程序代码里粘贴 SQL 查询字符串就是个糟糕的决定。一个 对象-关系 映射(object-relational mapper) (ORM)在你的代码和数据库之间添加一个抽象层,并以此简化了与数据库交互代码的编写。Java 中的 Hibernate 和 Ruby 中的 ActiveRecord 就是广为人知的 ORM。

                                                        +

                                                        .NET 上有多个 ORM,其中有一个由微软开发,并默认包含在 ASP.NET Core 中,这就是 Entity Framework Core。Entity Framework Core 支持多个不同类型的数据库,并允许你使用 C# 代码创建数据库查询语句,查询结果映射回 C# 模型(POCO)。

                                                        +
                                                        +

                                                        还记得创建服务接口以解耦控制器和服务的实现类吗?Entity Framework Core 就像一个数据库上的大型接口。你的 C# 代码可以于具体的数据库实现无关,你可以根据底层以来的数据库技术更换不同的 provider。

                                                        +
                                                        +

                                                        Entity Framework Core 可以连接到 SQL Server、PostgreSQL 和 MySQL 这种关系型数据库,也可以与 Mongo 这种 NoSQL(文档) 数据库协作。在本项目的开发过程中,你将使用一个 SQLite 数据库,以简化安装和配置的工作。

                                                        +
                                                        +

                                                        Use a database

                                                        +

                                                        Writing database code can be tricky. Unless you really know what you're doing, it's a bad idea to paste raw SQL query strings into your application code. An object-relational mapper (ORM) makes it easier to write code that interacts with a database by adding a layer of abstraction between your code and the database itself. Hibernate in Java and ActiveRecord in Ruby are two well-known ORMs.

                                                        +

                                                        There are a number of ORMs for .NET, including one built by Microsoft and included in ASP.NET Core by default: Entity Framework Core. Entity Framework Core makes it easy to connect to a number of different database types, and lets you use C# code to create database queries that are mapped back into C# models (POCOs).

                                                        +
                                                        +

                                                        Remember how creating a service interface decoupled the controller code from the actual service class? Entity Framework Core is like a big interface over your database. Your C# code can stay database-agnostic, and you can swap out different providers depending on the underlying database technology.

                                                        +
                                                        +

                                                        Entity Framework Core can connect to relational databases like SQL Server, PostgreSQL, and MySQL, and also works with NoSQL (document) databases like Mongo. During development, you'll use SQLite in this project to make things easy to set up.

                                                        + + +
                                                        + +
                                                        +
                                                        +
                                                        + +

                                                        results matching ""

                                                        +
                                                          + +
                                                          +
                                                          + +

                                                          No results matching ""

                                                          + +
                                                          +
                                                          +
                                                          + +
                                                          +
                                                          + +
                                                          + + + + + + + + + + + + + + +
                                                          + + +
                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/use-a-database/migrations.png b/book/chapters/use-a-database/migrations.png new file mode 100644 index 0000000..fea14b5 Binary files /dev/null and b/book/chapters/use-a-database/migrations.png differ diff --git a/book/chapters/use-a-database/update-context.html b/book/chapters/use-a-database/update-context.html new file mode 100644 index 0000000..8024c3a --- /dev/null +++ b/book/chapters/use-a-database/update-context.html @@ -0,0 +1,817 @@ + + + + + + + 修改数据库上下文 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                          +
                                                          + + + + + + + + +
                                                          + +
                                                          + +
                                                          + + + + + + + + +
                                                          +
                                                          + +
                                                          +
                                                          + +
                                                          + +

                                                          修改数据库上下文

                                                          +

                                                          数据库上下文这边所需的工作不多:

                                                          +

                                                          Data/ApplicationDbContext.cs

                                                          +
                                                          public class ApplicationDbContext 
                                                          +             : IdentityDbContext<ApplicationUser>
                                                          +{
                                                          +    public ApplicationDbContext(
                                                          +        DbContextOptions<ApplicationDbContext> options)
                                                          +        : base(options)
                                                          +    {
                                                          +    }
                                                          +
                                                          +    protected override void OnModelCreating(ModelBuilder builder)
                                                          +    {
                                                          +        base.OnModelCreating(builder);
                                                          +        // ...
                                                          +    }
                                                          +}
                                                          +
                                                          +

                                                          在构造函数的下方,为 ApplicationDbContext 添加一个 DbSet 属性:

                                                          +
                                                          public ApplicationDbContext(
                                                          +    DbContextOptions<ApplicationDbContext> options)
                                                          +    : base(options)
                                                          +{
                                                          +}
                                                          +
                                                          +public DbSet<TodoItem> Items { get; set; }
                                                          +
                                                          +// ...
                                                          +
                                                          +

                                                          DbSet 代表数据库里的 表 或者 集合。创建一个名为 ItemsDbSet<TodoItem> 属性,可以让 Entity Framework Core 知道,你需要在一个名为 Items 的表里保存 TodoItem 实体。

                                                          +

                                                          你修改了 数据库上下文 的类,却产生了一个小问题: 现在上下文和数据库不同步了,因为数据库里实际上并不存在 Items 这个表。(对数据库上下文代码的修改,并不会改变数据库本身。)

                                                          +

                                                          为了把“数据库上下文中的改动”反映到数据库里,你需要创建一个 变更(migration)

                                                          +
                                                          +

                                                          如果你已经有一个现存的数据库,请在网络上搜索“scaffold-dbcontext existing database”相关的内容,并阅读微软的关于使用 Scaffold-DbContext 工具的文档,以此对你的数据库进行逆向工程,自动地为数据库结构生成相应的 DbContext 和模型类。

                                                          +
                                                          +
                                                          +

                                                          Update the context

                                                          +

                                                          There's not a whole lot going on in the database context yet:

                                                          +

                                                          Data/ApplicationDbContext.cs

                                                          +
                                                          public class ApplicationDbContext 
                                                          +             : IdentityDbContext<ApplicationUser>
                                                          +{
                                                          +    public ApplicationDbContext(
                                                          +        DbContextOptions<ApplicationDbContext> options)
                                                          +        : base(options)
                                                          +    {
                                                          +    }
                                                          +
                                                          +    protected override void OnModelCreating(ModelBuilder builder)
                                                          +    {
                                                          +        base.OnModelCreating(builder);
                                                          +        // ...
                                                          +    }
                                                          +}
                                                          +
                                                          +

                                                          Add a DbSet property to the ApplicationDbContext, right below the constructor:

                                                          +
                                                          public ApplicationDbContext(
                                                          +    DbContextOptions<ApplicationDbContext> options)
                                                          +    : base(options)
                                                          +{
                                                          +}
                                                          +
                                                          +public DbSet<TodoItem> Items { get; set; }
                                                          +
                                                          +// ...
                                                          +
                                                          +

                                                          A DbSet represents a table or collection in the database. By creating a DbSet<TodoItem> property called Items, you're telling Entity Framework Core that you want to store TodoItem entities in a table called Items.

                                                          +

                                                          You've updated the context class, but now there's one small problem: the context and database are now out of sync, because there isn't actually an Items table in the database. (Just updating the code of the context class doesn't change the database itself.)

                                                          +

                                                          In order to update the database to reflect the change you just made to the context, you need to create a migration.

                                                          +
                                                          +

                                                          If you already have an existing database, search the web for "scaffold-dbcontext existing database" and read Microsoft's documentation on using the Scaffold-DbContext tool to reverse-engineer your database structure into the proper DbContext and model classes automatically.

                                                          +
                                                          + + +
                                                          + +
                                                          +
                                                          +
                                                          + +

                                                          results matching ""

                                                          +
                                                            + +
                                                            +
                                                            + +

                                                            No results matching ""

                                                            + +
                                                            +
                                                            +
                                                            + +
                                                            +
                                                            + +
                                                            + + + + + + + + + + + + + + +
                                                            + + +
                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/your-first-application/breakpoint.png b/book/chapters/your-first-application/breakpoint.png new file mode 100644 index 0000000..feb1e8b Binary files /dev/null and b/book/chapters/your-first-application/breakpoint.png differ diff --git a/book/chapters/your-first-application/create-aspnetcore-project.html b/book/chapters/your-first-application/create-aspnetcore-project.html new file mode 100644 index 0000000..05f101a --- /dev/null +++ b/book/chapters/your-first-application/create-aspnetcore-project.html @@ -0,0 +1,862 @@ + + + + + + + 创建一个 ASP.NET Core 项目 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                            +
                                                            + + + + + + + + +
                                                            + +
                                                            + +
                                                            + + + + + + + + +
                                                            +
                                                            + +
                                                            +
                                                            + +
                                                            + +

                                                            创建一个 ASP.NET Core 项目

                                                            +

                                                            如果你还在 Hello World 示例的那个目录里,请退回到 我的文档 或者 home 目录:

                                                            +
                                                            cd ..
                                                            +
                                                            +

                                                            接下来,创建一个新目录以保存你的整个项目,然后进到该目录里:

                                                            +
                                                            mkdir AspNetCoreTodo
                                                            +cd AspNetCoreTodo
                                                            +
                                                            +

                                                            接下来,使用 dotnet new 创建一个新项目,这一次添加几个选项:

                                                            +
                                                            dotnet new mvc --auth Individual -o AspNetCoreTodo
                                                            +cd AspNetCoreTodo
                                                            +
                                                            +

                                                            这个命令,使用 mvc 模板创建了一个新的项目,并添加了一些额外的验证和安全性相关的内容。(关于安全性的内容,我会在 安全性与身份 一章讲解。)

                                                            +
                                                            +

                                                            你可能有点疑惑,为什么在一个 AspNetCoreTodo 目录里弄另一个 AspNetCoreTodo 目录。这个顶层或者说“根”目录可以容纳一个或多个项目目录。根目录有时候被称为 解决方案目录。后面,你将会在 AspNetCoreTodo 项目目录边上添加多个项目目录,它们全都在一个单一的根解决方案目录里。

                                                            +
                                                            +

                                                            在这个新的项目目录里,你会发现多出来几个文件。在你 cd 到新目录里之后,就只需要运行这个项目了:

                                                            +
                                                            dotnet run
                                                            +
                                                            +Now listening on: http://localhost:5000
                                                            +Application started. Press Ctrl+C to shut down.
                                                            +
                                                            +

                                                            这个程序不再打印到控制台后直接退出,而是启动了一个 web 服务器,并在端口 5000 上等待访问请求。

                                                            +

                                                            开启你的网络浏览器,浏览 http://localhost:5000。你将看到 ASP.NET Core 程序的默认欢迎页面,说明你的程序工作正常!看够了这个页面之后,在终端窗口内按下 Ctrl-C 以便停止这个服务器。

                                                            +

                                                            一个 ASP.NET Core 项目的各部分

                                                            +

                                                            dotnet new mvc 模板为你生成了多个文件和目录。在默认创建的基本内容里,这几个是最重要的:

                                                            +
                                                              +
                                                            • Program.csStartup.cs 文件,设置 web 服务器和 ASP.NET Core 的处理管线。在 Startup 类里,你可以添加中间件,它们用于 处理和调整传入的请求、提供静态内容和错误页面。在这里,你还可以向依赖注入容器中添加你自己的服务(后面细说)。

                                                              +
                                                            • +
                                                            • ModelsViews,和 Controllers目录里放置着 模型-视图-控制器(MVC,Model-View-Controller)架构的组件。下一章,你将一探他们三者的究竟。

                                                              +
                                                            • +
                                                            • wwwroot 目录里放着 CSS、JavaScript、图片文件 这些静态资源。wwwroot 里的文件将作为静态内容,自动被打包和压缩。

                                                              +
                                                            • +
                                                            • appsettings.json 文件里包含着 ASP.NET Core 启动时读取的配置信息。你可以用它来保存数据库连接字符串,或者其它你不想硬编码的任何内容。

                                                              +
                                                            • +
                                                            +

                                                            Visual Studio Code 技巧

                                                            +

                                                            如果你是初次使用 Visual Studio Code(或者 Visual Studio),下面这几个有益的小技巧将帮你轻松上手:

                                                            +
                                                              +
                                                            • 打开项目的根文件夹 : 在 Visual Studio Code 里,选择 文件 -> 打开文件夹。打开 AspNetCoreTodo 文件夹(根目录),不是内层的项目目录。如果 Visual Studio Code 提示你安装缺失的文件,点击“是”以添加它们。

                                                              +
                                                            • +
                                                            • 用 F5 运行(并调试断点):使你的项目处于打开状态,按下 F5 以调试模式运行项目。这跟命令行的 dotnet run 功能相同,但有一个额外好处——你可以在代码编辑器的左边栏上点击,以设置一个断点:

                                                              +

                                                              Visual Studio Code 中的断点

                                                              +
                                                            • +
                                                            • 潜在问题的小灯泡提示:如果你的代码里有红色波浪线(编译错误),把编辑的光标放在红线里,到左边栏里找那个小灯泡的图标,小灯泡的提示信息会给出常见问题的修改建议,比如在代码里添加一个 using 语句:

                                                              +

                                                              小灯泡提示

                                                              +
                                                            • +
                                                            • 快捷编译:使用快捷键 Command-Shift-B 或者 Control-Shift-B 运行编译任务,这跟 dotnet build 的效果一样。

                                                              +
                                                            • +
                                                            +
                                                            +

                                                            这些也可以用在 Widnows 版的 Visual Studio (不带 Code)。如果你用的是 Visual Studio,你需要直接打开 .csproj 项目文件所在的目录。 Visual Studio 后面会提示你保存解决方案文件,你应该把它保存在根目录(第一个 AspNetCoreTodo 文件夹)。你也可以在 Visual Studio 里使用模板直接创建 ASP.NET Core 项目,操作是 文件 > 新建 > 项目。

                                                            +
                                                            +

                                                            Git 小贴士:

                                                            +

                                                            如果你使用 Git 或者 GitHub 管理你的源码,眼下就是一个适合的时机,在项目目录下用 git init 来初始化你的 Git 仓库:

                                                            +
                                                            cd ..
                                                            +git init
                                                            +
                                                            +

                                                            请确保你添加了一个 .gitignore 文件用以忽略 binobj 这些目录。 GitHub 上 gitignore 模板仓库(https://github.com/github/gitignore)里的 Visual Studio gitignore 模板就很好用。

                                                            +

                                                            还有很多值得研究的内容,让我们着手构建这个应用吧!

                                                            +
                                                            +

                                                            Create an ASP.NET Core project

                                                            +

                                                            If you're still in the directory you created for the Hello World sample, move back up to your Documents or home directory:

                                                            +
                                                            cd ..
                                                            +

                                                            Next, create a new directory to store your entire project, and move into it:

                                                            +
                                                            mkdir AspNetCoreTodo
                                                            +cd AspNetCoreTodo
                                                            +

                                                            Next, create a new project with dotnet new, this time with some extra options:

                                                            +
                                                            dotnet new mvc --auth Individual -o AspNetCoreTodo
                                                            +cd AspNetCoreTodo
                                                            +

                                                            This creates a new project from the mvc template, and adds some additional authentication and security bits to the project. (I'll cover security in the Security and identity chapter.)

                                                            +
                                                            +

                                                            You might be wondering why you have a directory called AspNetCoreTodo inside another directory called AspNetCoreTodo. The top-level or "root" directory can contain one or more project directories. The root directory is sometimes called a solution directory. Later, you'll add more project directories side-by-side with the AspNetCoreTodo project directory, all within a single root solution directory.

                                                            +
                                                            +

                                                            You'll see quite a few files show up in the new project directory. Once you cd into the new directory, all you have to do is run the project:

                                                            +
                                                            dotnet run
                                                            +
                                                            +Now listening on: http://localhost:5000
                                                            +Application started. Press Ctrl+C to shut down.
                                                            +

                                                            Instead of printing to the console and exiting, this program starts a web server and waits for requests on port 5000.

                                                            +

                                                            Open your web browser and navigate to http://localhost:5000. You'll see the default ASP.NET Core splash page, which means your project is working! When you're done, press Ctrl-C in the terminal window to stop the server.

                                                            +

                                                            The parts of an ASP.NET Core project

                                                            +

                                                            The dotnet new mvc template generates a number of files and directories for you. Here are the most important things you get out of the box:

                                                            +
                                                              +
                                                            • The Program.cs and Startup.cs files set up the web server and ASP.NET Core pipeline. The Startup class is where you can add middleware that handles and modifies incoming requests, and serves things like static content or error pages. It's also where you add your own services to the dependency injection container (more on this later).

                                                              +
                                                            • +
                                                            • The Models, Views, and Controllers directories contain the components of the Model-View-Controller (MVC) architecture. You'll explore all three in the next chapter.

                                                              +
                                                            • +
                                                            • The wwwroot directory contains static assets like CSS, JavaScript, and image files. Files in wwwroot will be served as static content, and can be bundled and minified automatically.

                                                              +
                                                            • +
                                                            • The appsettings.json file contains configuration settings ASP.NET Core will load on startup. You can use this to store database connection strings or other things that you don't want to hard-code.

                                                              +
                                                            • +
                                                            +

                                                            Tips for Visual Studio Code

                                                            +

                                                            If you're using Visual Studio Code for the first time, here are a couple of helpful tips to get you started:

                                                            +
                                                              +
                                                            • Open the project root folder: In Visual Studio Code, choose File - Open or File - Open Folder. Open the AspNetCoreTodo folder (the root directory), not the inner project directory. If Visual Studio Code prompts you to install missing files, click Yes to add them.

                                                              +
                                                            • +
                                                            • F5 to run (and debug breakpoints): With your project open, press F5 to run the project in debug mode. This is the same as dotnet run on the command line, but you have the benefit of setting breakpoints in your code by clicking on the left margin:

                                                              +
                                                            • +
                                                            +

                                                            Breakpoint in Visual Studio Code

                                                            +
                                                              +
                                                            • Lightbulb to fix problems: If your code contains red squiggles (compiler errors), put your cursor on the code that's red and look for the lightbulb icon on the left margin. The lightbulb menu will suggest common fixes, like adding a missing using statement to your code:
                                                            • +
                                                            +

                                                            Lightbulb suggestions

                                                            +
                                                              +
                                                            • Compile quickly: Use the shortcut Command-Shift-B or Control-Shift-B to run the Build task, which does the same thing as dotnet build.
                                                            • +
                                                            +
                                                            +

                                                            These tips apply to Visual Studio (not Code) on Windows too. If you're using Visual Studio, you'll need to open the .csproj project file directly. Visual Studio will later prompt you to save the Solution file, which you should save in the root directory (the first AspNetCoreTodo folder). You can also create an ASP.NET Core project directly within Visual Studio using the templates in File - New Project.

                                                            +
                                                            +

                                                            A note about Git

                                                            +

                                                            If you use Git or GitHub to manage your source code, now is a good time to do git init and initialize a Git repository in the project root directory:

                                                            +
                                                            cd ..
                                                            +git init
                                                            +

                                                            Make sure you add a .gitignore file that ignores the bin and obj directories. The Visual Studio template on GitHub's gitignore template repo (https://github.com/github/gitignore) works great.

                                                            +

                                                            There's plenty more to explore, so let's dive in and start building an application!

                                                            + + +
                                                            + +
                                                            +
                                                            +
                                                            + +

                                                            results matching ""

                                                            +
                                                              + +
                                                              +
                                                              + +

                                                              No results matching ""

                                                              + +
                                                              +
                                                              +
                                                              + +
                                                              +
                                                              + +
                                                              + + + + + + + + + + + + + + +
                                                              + + +
                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/your-first-application/get-the-sdk.html b/book/chapters/your-first-application/get-the-sdk.html new file mode 100644 index 0000000..a6e7a3b --- /dev/null +++ b/book/chapters/your-first-application/get-the-sdk.html @@ -0,0 +1,787 @@ + + + + + + + 获取 SDK · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                              +
                                                              + + + + + + + + +
                                                              + +
                                                              + +
                                                              + + + + + + + + +
                                                              +
                                                              + +
                                                              +
                                                              + +
                                                              + +

                                                              获取 SDK

                                                              +

                                                              搜索“下载 .net core”,在微软为你所在平台提供的下载页面,获取 .NET Core 的 SDK。完成 SDK 的安装后,开启一个终端窗口(或者 Windows 上的 PowerShell),并使用 dotnet 命令行工具(command line tool,也叫 CLI)确保一切正常工作:

                                                              +
                                                              dotnet --version
                                                              +
                                                              +2.1.104
                                                              +
                                                              +

                                                              还可以通过 --info 选项,获取你所在平台更详细的信息:

                                                              +
                                                              dotnet --info
                                                              +
                                                              +.NET Command Line Tools (2.1.104)
                                                              +
                                                              +Product Information:
                                                              + Version:            2.1.104
                                                              + Commit SHA-1 hash:  48ec687460
                                                              +
                                                              +Runtime Environment:
                                                              + OS Name:     Mac OS X
                                                              + OS Version:  10.13
                                                              +
                                                              +(more details...)
                                                              +
                                                              +

                                                              如果你看到类似于上面的输出,就大步前进吧。

                                                              +
                                                              +

                                                              Get the SDK

                                                              +

                                                              Search for "download .net core" and follow the instructions on Microsoft's download page to get the .NET Core SDK. After the SDK has finished installing, open up the Terminal (or PowerShell on Windows) and use the dotnet command line tool (also called a CLI) to make sure everything is working:

                                                              +
                                                              dotnet --version
                                                              +
                                                              +2.1.104
                                                              +

                                                              You can get more information about your platform with the --info flag:

                                                              +
                                                              dotnet --info
                                                              +
                                                              +.NET Command Line Tools (2.1.104)
                                                              +
                                                              +Product Information:
                                                              + Version:            2.1.104
                                                              + Commit SHA-1 hash:  48ec687460
                                                              +
                                                              +Runtime Environment:
                                                              + OS Name:     Mac OS X
                                                              + OS Version:  10.13
                                                              +
                                                              +(more details...)
                                                              +

                                                              If you see output like the above, you're ready to go!

                                                              + + +
                                                              + +
                                                              +
                                                              +
                                                              + +

                                                              results matching ""

                                                              +
                                                                + +
                                                                +
                                                                + +

                                                                No results matching ""

                                                                + +
                                                                +
                                                                +
                                                                + +
                                                                +
                                                                + +
                                                                + + + + + + + + + + + + + + +
                                                                + + +
                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/your-first-application/hello-world-in-csharp.html b/book/chapters/your-first-application/hello-world-in-csharp.html new file mode 100644 index 0000000..21057cc --- /dev/null +++ b/book/chapters/your-first-application/hello-world-in-csharp.html @@ -0,0 +1,829 @@ + + + + + + + C# 版的 Hello World · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                +
                                                                + + + + + + + + +
                                                                + +
                                                                + +
                                                                + + + + + + + + +
                                                                +
                                                                + +
                                                                +
                                                                + +
                                                                + +

                                                                C# 版的 Hello World

                                                                +

                                                                深入钻研 ASP.NET Core 之前,先试着创建并运行一个简单的应用程序吧。

                                                                +

                                                                这个可以在命令行下执行。首先开启一个终端窗口(或者 Windows 上的 PowerShell)。一路 cd 到要放置你项目的路径下,比如你的“我的文档”目录:

                                                                +
                                                                cd Documents
                                                                +
                                                                +

                                                                使用 dotnet 命令创建一个新的项目:

                                                                +
                                                                dotnet new console -o CsharpHelloWorld
                                                                +
                                                                +

                                                                dotnet new 指令默认会用 C# 创建一个 .NET 项目。参数 console 选择了一个命令行应用(一种向屏幕输出文本的程序)的模板。-o CsharpHelloWorld 参数指示 dotnet new 为项目的所有文件创建一个名为 CsharpHelloWorld 的目录。进入到这个新目录里:

                                                                +
                                                                cd CsharpHelloWorld
                                                                +
                                                                +

                                                                dotnet new console 命令创建了一个基本的 C# 程序,它输出文本 Hello World! 到屏幕上。这个程序由两个文件构成:一个项目文件(使用 .csproj 扩展名)和一个 C# 源文件(带有 .cs 扩展名),打开前面那个文件的话,可以看到以下内容:

                                                                +

                                                                CsharpHelloWorld.csproj

                                                                +
                                                                <Project Sdk="Microsoft.NET.Sdk">
                                                                +
                                                                +  <PropertyGroup>
                                                                +    <OutputType>Exe</OutputType>
                                                                +    <TargetFramework>netcoreapp2.0</TargetFramework>
                                                                +  </PropertyGroup>
                                                                +
                                                                +</Project>
                                                                +
                                                                +

                                                                项目文件基于 XML,其中定义了一些关于项目的元数据。到后面,你引用其它包的时候,那些包将被记录在这里(类似于 npm 的 package.json),你不需要经常手动编辑这个文件。

                                                                +

                                                                Program.cs

                                                                +
                                                                using System;
                                                                +
                                                                +namespace CsharpHelloWorld
                                                                +{
                                                                +    class Program
                                                                +    {
                                                                +        static void Main(string[] args)
                                                                +        {
                                                                +            Console.WriteLine("Hello World!");
                                                                +        }
                                                                +    }
                                                                +}
                                                                +
                                                                +

                                                                static void Main 是 C# 程序的入口点方法,按照惯例,会被置于一个叫 Program 的类(一种代码结构或模块)里。最上面的 using 语句引入了 .NET 内置于 System 的那些类,以便在你的这个类里使用它们。

                                                                +

                                                                在项目的目录里,用 dotnet run 指令运行这个程序,在代码编译完成之后,你将看到输出在控制台里面的内容:

                                                                +
                                                                dotnet run
                                                                +
                                                                +Hello World!
                                                                +
                                                                +

                                                                这就是构建一个 .NET 程序所需的全部!下一节,你将把同样的流程应用在一个 ASP.NET Core 程序上。

                                                                +
                                                                +

                                                                Hello World in C#

                                                                +

                                                                Before you dive into ASP.NET Core, try creating and running a simple C# application.

                                                                +

                                                                You can do this all from the command line. First, open up the Terminal (or PowerShell on Windows). Navigate to the location you want to store your projects, such as your Documents directory:

                                                                +
                                                                cd Documents
                                                                +

                                                                Use the dotnet command to create a new project:

                                                                +
                                                                dotnet new console -o CsharpHelloWorld
                                                                +

                                                                The dotnet new command creates a new .NET project in C# by default. The console parameter selects a template for a console application (a program that outputs text to the screen). The -o CsharpHelloWorld parameter tells dotnet new to create a new directory called CsharpHelloWorld for all the project files. Move into this new directory:

                                                                +
                                                                cd CsharpHelloWorld
                                                                +

                                                                dotnet new console creates a basic C# program that writes the text Hello World! to the screen. The program is comprised of two files: a project file (with a .csproj extension) and a C# code file (with a .cs extension). If you open the former in a text or code editor, you'll see this:

                                                                +

                                                                CsharpHelloWorld.csproj

                                                                +
                                                                <Project Sdk="Microsoft.NET.Sdk">
                                                                +
                                                                +  <PropertyGroup>
                                                                +    <OutputType>Exe</OutputType>
                                                                +    <TargetFramework>netcoreapp2.0</TargetFramework>
                                                                +  </PropertyGroup>
                                                                +
                                                                +</Project>
                                                                +
                                                                +

                                                                The project file is XML-based and defines some metadata about the project. Later, when you reference other packages, those will be listed here (similar to a package.json file for npm). You won't have to edit this file by hand very often.

                                                                +

                                                                Program.cs

                                                                +
                                                                using System;
                                                                +
                                                                +namespace CsharpHelloWorld
                                                                +{
                                                                +    class Program
                                                                +    {
                                                                +        static void Main(string[] args)
                                                                +        {
                                                                +            Console.WriteLine("Hello World!");
                                                                +        }
                                                                +    }
                                                                +}
                                                                +
                                                                +

                                                                static void Main is the entry point method of a C# program, and by convention it's placed in a class (a type of code structure or module) called Program. The using statement at the top imports the built-in System classes from .NET and makes them available to the code in your class.

                                                                +

                                                                From inside the project directory, use dotnet run to run the program. You'll see the output written to the console after the code compiles:

                                                                +
                                                                dotnet run
                                                                +
                                                                +Hello World!
                                                                +

                                                                That's all it takes to scaffold and run a .NET program! Next, you'll do the same thing for an ASP.NET Core application.

                                                                + + +
                                                                + +
                                                                +
                                                                +
                                                                + +

                                                                results matching ""

                                                                +
                                                                  + +
                                                                  +
                                                                  + +

                                                                  No results matching ""

                                                                  + +
                                                                  +
                                                                  +
                                                                  + +
                                                                  +
                                                                  + +
                                                                  + + + + + + + + + + + + + + +
                                                                  + + +
                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/your-first-application/index.html b/book/chapters/your-first-application/index.html new file mode 100644 index 0000000..eb95622 --- /dev/null +++ b/book/chapters/your-first-application/index.html @@ -0,0 +1,757 @@ + + + + + + + 你的第一个程序 · 简明 ASP.NET Core 手册 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                  +
                                                                  + + + + + + + + +
                                                                  + +
                                                                  + +
                                                                  + + + + + + + + +
                                                                  +
                                                                  + +
                                                                  +
                                                                  + +
                                                                  + +

                                                                  你的第一个程序

                                                                  +

                                                                  准备好创建你的第一个 ASP.NET Core web 应用了么?先做点“利其器”的事:

                                                                  +

                                                                  你惯用的代码编辑器 你可以用 Atom、Sublime、Notepad 或者任何你喜欢的编辑器。如果你还没有一个惯用的,请试试 Visual Studio Code。这是个免费、跨平台的代码编辑器,对于 C#、JavaScript、HTML 和很多其它语言编程的支持非常丰富。只需要搜索“下载 visual studio code”再按指令操作即可。(译者的话:别用 百度,试试 bing.com

                                                                  +

                                                                  如果你在 Windows 下,也可以用 Visual Studio 构建 ASP.NET Core 应用程序。这需要用到 Visual Studio 2017 的 15.3 及以上的版本(免费的社区版就够用了)。Visual Studio 有着优秀的 代码补全 和 C# 的代码重构,且略优于 Visual Studio Code。

                                                                  +

                                                                  .NET Core SDK 不论你用什么编辑器或者平台,都需要安装 .NET Core SDK,包括运行时,基础库以及用于构建 ASP.NET Core 应用程序的命令行工具。它可以安装在 Windows、Mac、Linux上。

                                                                  +

                                                                  选定了编辑器,就该去获取 SDK 了。

                                                                  +
                                                                  +

                                                                  Your first application

                                                                  +

                                                                  Ready to build your first web app with ASP.NET Core? You'll need to gather a few things first:

                                                                  +

                                                                  Your favorite code editor. You can use Atom, Sublime, Notepad, or whatever editor you prefer writing code in. If you don't have a favorite, give Visual Studio Code a try. It's a free, cross-platform code editor that has rich support for writing C#, JavaScript, HTML, and more. Just search for "download visual studio code" and follow the instructions.

                                                                  +

                                                                  If you're on Windows, you can also use Visual Studio to build ASP.NET Core applications. You'll need Visual Studio 2017 version 15.3 or later (the free Community Edition is fine). Visual Studio has great code completion and refactoring support for C#, although Visual Studio Code is close behind.

                                                                  +

                                                                  The .NET Core SDK. Regardless of the editor or platform you're using, you'll need to install the .NET Core SDK, which includes the runtime, base libraries, and command line tools you need for building ASP.NET Core applications. The SDK can be installed on Windows, Mac, or Linux.

                                                                  +

                                                                  Once you've decided on an editor, you'll need to get the SDK.

                                                                  + + +
                                                                  + +
                                                                  +
                                                                  +
                                                                  + +

                                                                  results matching ""

                                                                  +
                                                                    + +
                                                                    +
                                                                    + +

                                                                    No results matching ""

                                                                    + +
                                                                    +
                                                                    +
                                                                    + +
                                                                    +
                                                                    + +
                                                                    + + + + + + + + + + + + + + +
                                                                    + + +
                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/chapters/your-first-application/lightbulb.png b/book/chapters/your-first-application/lightbulb.png new file mode 100644 index 0000000..a147bd2 Binary files /dev/null and b/book/chapters/your-first-application/lightbulb.png differ diff --git a/book/cover.jpg b/book/cover.jpg new file mode 100644 index 0000000..05bface Binary files /dev/null and b/book/cover.jpg differ diff --git a/book/cover_small.jpg b/book/cover_small.jpg new file mode 100644 index 0000000..f19e0e4 Binary files /dev/null and b/book/cover_small.jpg differ diff --git a/book/gitbook/fonts/fontawesome/FontAwesome.otf b/book/gitbook/fonts/fontawesome/FontAwesome.otf new file mode 100644 index 0000000..d4de13e Binary files /dev/null and b/book/gitbook/fonts/fontawesome/FontAwesome.otf differ diff --git a/book/gitbook/fonts/fontawesome/fontawesome-webfont.eot b/book/gitbook/fonts/fontawesome/fontawesome-webfont.eot new file mode 100644 index 0000000..c7b00d2 Binary files /dev/null and b/book/gitbook/fonts/fontawesome/fontawesome-webfont.eot differ diff --git a/book/gitbook/fonts/fontawesome/fontawesome-webfont.svg b/book/gitbook/fonts/fontawesome/fontawesome-webfont.svg new file mode 100644 index 0000000..8b66187 --- /dev/null +++ b/book/gitbook/fonts/fontawesome/fontawesome-webfont.svg @@ -0,0 +1,685 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf b/book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf new file mode 100644 index 0000000..f221e50 Binary files /dev/null and b/book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf differ diff --git a/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff b/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff new file mode 100644 index 0000000..6e7483c Binary files /dev/null and b/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff differ diff --git a/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 b/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 new file mode 100644 index 0000000..7eb74fd Binary files /dev/null and b/book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 differ diff --git a/book/gitbook/gitbook-plugin-anchors/plugin.css b/book/gitbook/gitbook-plugin-anchors/plugin.css new file mode 100644 index 0000000..adf3e9e --- /dev/null +++ b/book/gitbook/gitbook-plugin-anchors/plugin.css @@ -0,0 +1,30 @@ + +a.plugin-anchor { + color: inherit !important; + display: none; + margin-left: -30px; + padding-left: 40px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; +} + +a.plugin-anchor i { + margin-left: -30px; + font-size: 15px !important; +} + +h1, h2, h3, h4, h5, h6 { + position: relative; +} + +h1:hover a.plugin-anchor, h2:hover a.plugin-anchor, h3:hover a.plugin-anchor, +h4:hover a.plugin-anchor, h5:hover a.plugin-anchor, h6:hover a.plugin-anchor { + display: inline-block; +} + +.book .book-body .page-wrapper .page-inner section.normal { + overflow: visible; +} diff --git a/book/gitbook/gitbook-plugin-copy-code-button/toggle.js b/book/gitbook/gitbook-plugin-copy-code-button/toggle.js new file mode 100644 index 0000000..2a98457 --- /dev/null +++ b/book/gitbook/gitbook-plugin-copy-code-button/toggle.js @@ -0,0 +1,86 @@ +require(["gitbook", "jQuery"], function(gitbook, $) { + function selectElementText(el){ + var range = document.createRange(); + range.selectNodeContents(el); + var selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + + function getSelectedText() { + var t = ''; + if (window.getSelection) { + t = window.getSelection(); + } else if (document.getSelection) { + t = document.getSelection(); + } else if (document.selection) { + t = document.selection.createRange().text; + } + return t; + } + + function copyToClipboard(text) { + if (window.clipboardData && window.clipboardData.setData) { + // IE specific code path to prevent textarea being shown while dialog is visible. + return clipboardData.setData("Text", text); + + } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) { + var textarea = document.createElement("textarea"); + textarea.textContent = text; + textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge. + document.body.appendChild(textarea); + textarea.select(); + try { + return document.execCommand("copy"); // Security exception may be thrown by some browsers. + } catch (ex) { + console.warn("Copy to clipboard failed.", ex); + return false; + } finally { + document.body.removeChild(textarea); + } + } + } + + function expand(chapter) { + chapter.show(); + if (chapter.parent().attr('class') != 'summary' + && chapter.parent().attr('class') != 'book-summary' + && chapter.length != 0 + ) { + expand(chapter.parent()); + } + } + + gitbook.events.bind("page.change", function() { + $("pre").each(function(){ + $(this).css("position", "relative"); + + var $copyCodeButton = $(""); + $copyCodeButton.css({"position": "absolute", "top": "5px", "right": "5px", "padding": "3px", "background-color":"#313E4E", "color":"white", "border-radius": "5px" , "-moz-border-radius": "5px", "-webkit-border-radius": "5px", "border": "2px solid #CCCCCC"}); + $copyCodeButton.click(function(){ + var $codeContainer = $(this).siblings("code"); + if($codeContainer) { + selectElementText($codeContainer.get(0)); + var selectedText = getSelectedText(); + + var buttonNewText = ""; + if(copyToClipboard(selectedText) == true){ + buttonNewText = "Copied"; + selectElementText($codeContainer.get(0)); + } else { + buttonNewText = "Unable to copy"; + selectElementText($codeContainer.get(0)); + } + + $(this).text(buttonNewText); + var that = this; + setTimeout(function(){ + $(that).text("Copy"); + }, 2000); + } + }); + + $(this).append($copyCodeButton); + }); + }); +}); diff --git a/book/gitbook/gitbook-plugin-disqus/plugin.css b/book/gitbook/gitbook-plugin-disqus/plugin.css new file mode 100644 index 0000000..7030dad --- /dev/null +++ b/book/gitbook/gitbook-plugin-disqus/plugin.css @@ -0,0 +1,4 @@ +#disqus_thread { + margin: 5px 15px; + margin-top: 30px; +} diff --git a/book/gitbook/gitbook-plugin-disqus/plugin.js b/book/gitbook/gitbook-plugin-disqus/plugin.js new file mode 100644 index 0000000..308c495 --- /dev/null +++ b/book/gitbook/gitbook-plugin-disqus/plugin.js @@ -0,0 +1,75 @@ +require([ + "gitbook", + "jQuery" +], function(gitbook, $) { + var use_identifier = false; + + function resetDisqus() { + var $disqusDiv = $("
                                                                    ", { + "id": "disqus_thread" + }); + $(".book-body .page-inner").append($disqusDiv); + + if (typeof DISQUS !== "undefined") { + DISQUS.reset({ + reload: true, + config: function () { + this.language = $('html').attr('lang') || "en"; + this.page.url = window.location.href; + + if (use_identifier) { + this.page.identifier = currentUrl(); + } + } + }); + } + } + + function joinURL(baseUrl, url) { + var theUrl = new URI(url); + if (theUrl.is("relative")) { + theUrl = theUrl.absoluteTo(baseUrl); + } + return theUrl.toString(); + } + + function currentUrl() { + var location = new URI(window.location.href), + base = joinURL(window.location.href, gitbook.state.basePath), + current = location.relativeTo(base).toString(), + language = $('html').attr('lang'), + parent = joinURL(base, '..'), + folder = new URI(base).relativeTo(parent).toString(); + + // If parent folder is the same as language, we assume translated books + if (folder.replace(/\/$/, "") === language) { + current = folder + current; + } + + return current; + } + + gitbook.events.bind("start", function(e, config) { + config.disqus = config.disqus || {}; + var disqus_shortname = config.disqus.shortName; + var disqus_config = function() { + this.language = $('html').attr('lang') || "en"; + }; + + if (config.disqus.useIdentifier) { + use_identifier = true; + var disqus_identifier = currentUrl(); + } + + /* * * DON'T EDIT BELOW THIS LINE * * */ + (function() { + var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; + dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; + (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); + })(); + + resetDisqus(); + }); + + gitbook.events.bind("page.change", resetDisqus); +}); diff --git a/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css b/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css new file mode 100644 index 0000000..0b4275f --- /dev/null +++ b/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css @@ -0,0 +1,29 @@ +.book .book-summary .chapter > .articles { + overflow: hidden; + max-height: 0px; +} + +.book .book-summary .chapter.expanded > .articles { + max-height: 9999px; +} + +.book .book-summary .exc-trigger { + position: absolute; + left: 12px; + top: 12px; +} + +.book .book-summary ul.summary li a, +.book .book-summary ul.summary li span { + padding-left: 30px; +} + +.book .book-summary .exc-trigger:before { + content: "\f105"; +} + +.book .book-summary .expanded > a .exc-trigger:before, +.book .book-summary .expanded > span .exc-trigger:before { + content: "\f107"; +} + diff --git a/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.js b/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.js new file mode 100644 index 0000000..740689e --- /dev/null +++ b/book/gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.js @@ -0,0 +1,68 @@ +require(['gitbook', 'jQuery'], function(gitbook, $) { + var TOGGLE_CLASSNAME = 'expanded', + CHAPTER = '.chapter', + ARTICLES = '.articles', + TRIGGER_TEMPLATE = '', + LS_NAMESPACE = 'expChapters'; + var init = function () { + // adding the trigger element to each ARTICLES parent and binding the event + $(ARTICLES) + .parent(CHAPTER) + .children('a') + .append( + $(TRIGGER_TEMPLATE) + .on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + toggle($(e.target).closest(CHAPTER)); + }) + ); + expand(lsItem()); + //expand current selected chapter with it's parents + var activeChapter = $(CHAPTER + '.active'); + expand(activeChapter); + expand(activeChapter.parents(CHAPTER)); + + + } + var toggle = function ($chapter) { + if ($chapter.hasClass('expanded')) { + collapse($chapter); + } else { + expand($chapter); + } + } + var collapse = function ($chapter) { + if ($chapter.length && $chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.removeClass(TOGGLE_CLASSNAME); + lsItem($chapter); + } + } + var expand = function ($chapter) { + if ($chapter.length && !$chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.addClass(TOGGLE_CLASSNAME); + lsItem($chapter); + } + } + var lsItem = function () { + var map = JSON.parse(localStorage.getItem(LS_NAMESPACE)) || {} + if (arguments.length) { + var $chapters = arguments[0]; + $chapters.each(function (index, element) { + var level = $(this).data('level'); + var value = $(this).hasClass(TOGGLE_CLASSNAME); + map[level] = value; + }) + localStorage.setItem(LS_NAMESPACE, JSON.stringify(map)); + } else { + return $(CHAPTER).map(function(index, element){ + if (map[$(this).data('level')]) { + return this; + } + }) + } + } + gitbook.events.bind('page.change', function() { + init() + }); +}); diff --git a/book/gitbook/gitbook-plugin-fontsettings/fontsettings.js b/book/gitbook/gitbook-plugin-fontsettings/fontsettings.js new file mode 100644 index 0000000..ff7be71 --- /dev/null +++ b/book/gitbook/gitbook-plugin-fontsettings/fontsettings.js @@ -0,0 +1,240 @@ +require(['gitbook', 'jquery'], function(gitbook, $) { + // Configuration + var MAX_SIZE = 4, + MIN_SIZE = 0, + BUTTON_ID; + + // Current fontsettings state + var fontState; + + // Default themes + var THEMES = [ + { + config: 'white', + text: 'White', + id: 0 + }, + { + config: 'sepia', + text: 'Sepia', + id: 1 + }, + { + config: 'night', + text: 'Night', + id: 2 + } + ]; + + // Default font families + var FAMILIES = [ + { + config: 'serif', + text: 'Serif', + id: 0 + }, + { + config: 'sans', + text: 'Sans', + id: 1 + } + ]; + + // Return configured themes + function getThemes() { + return THEMES; + } + + // Modify configured themes + function setThemes(themes) { + THEMES = themes; + updateButtons(); + } + + // Return configured font families + function getFamilies() { + return FAMILIES; + } + + // Modify configured font families + function setFamilies(families) { + FAMILIES = families; + updateButtons(); + } + + // Save current font settings + function saveFontSettings() { + gitbook.storage.set('fontState', fontState); + update(); + } + + // Increase font size + function enlargeFontSize(e) { + e.preventDefault(); + if (fontState.size >= MAX_SIZE) return; + + fontState.size++; + saveFontSettings(); + } + + // Decrease font size + function reduceFontSize(e) { + e.preventDefault(); + if (fontState.size <= MIN_SIZE) return; + + fontState.size--; + saveFontSettings(); + } + + // Change font family + function changeFontFamily(configName, e) { + if (e && e instanceof Event) { + e.preventDefault(); + } + + var familyId = getFontFamilyId(configName); + fontState.family = familyId; + saveFontSettings(); + } + + // Change type of color theme + function changeColorTheme(configName, e) { + if (e && e instanceof Event) { + e.preventDefault(); + } + + var $book = gitbook.state.$book; + + // Remove currently applied color theme + if (fontState.theme !== 0) + $book.removeClass('color-theme-'+fontState.theme); + + // Set new color theme + var themeId = getThemeId(configName); + fontState.theme = themeId; + if (fontState.theme !== 0) + $book.addClass('color-theme-'+fontState.theme); + + saveFontSettings(); + } + + // Return the correct id for a font-family config key + // Default to first font-family + function getFontFamilyId(configName) { + // Search for plugin configured font family + var configFamily = $.grep(FAMILIES, function(family) { + return family.config == configName; + })[0]; + // Fallback to default font family + return (!!configFamily)? configFamily.id : 0; + } + + // Return the correct id for a theme config key + // Default to first theme + function getThemeId(configName) { + // Search for plugin configured theme + var configTheme = $.grep(THEMES, function(theme) { + return theme.config == configName; + })[0]; + // Fallback to default theme + return (!!configTheme)? configTheme.id : 0; + } + + function update() { + var $book = gitbook.state.$book; + + $('.font-settings .font-family-list li').removeClass('active'); + $('.font-settings .font-family-list li:nth-child('+(fontState.family+1)+')').addClass('active'); + + $book[0].className = $book[0].className.replace(/\bfont-\S+/g, ''); + $book.addClass('font-size-'+fontState.size); + $book.addClass('font-family-'+fontState.family); + + if(fontState.theme !== 0) { + $book[0].className = $book[0].className.replace(/\bcolor-theme-\S+/g, ''); + $book.addClass('color-theme-'+fontState.theme); + } + } + + function init(config) { + // Search for plugin configured font family + var configFamily = getFontFamilyId(config.family), + configTheme = getThemeId(config.theme); + + // Instantiate font state object + fontState = gitbook.storage.get('fontState', { + size: config.size || 2, + family: configFamily, + theme: configTheme + }); + + update(); + } + + function updateButtons() { + // Remove existing fontsettings buttons + if (!!BUTTON_ID) { + gitbook.toolbar.removeButton(BUTTON_ID); + } + + // Create buttons in toolbar + BUTTON_ID = gitbook.toolbar.createButton({ + icon: 'fa fa-font', + label: 'Font Settings', + className: 'font-settings', + dropdown: [ + [ + { + text: 'A', + className: 'font-reduce', + onClick: reduceFontSize + }, + { + text: 'A', + className: 'font-enlarge', + onClick: enlargeFontSize + } + ], + $.map(FAMILIES, function(family) { + family.onClick = function(e) { + return changeFontFamily(family.config, e); + }; + + return family; + }), + $.map(THEMES, function(theme) { + theme.onClick = function(e) { + return changeColorTheme(theme.config, e); + }; + + return theme; + }) + ] + }); + } + + // Init configuration at start + gitbook.events.bind('start', function(e, config) { + var opts = config.fontsettings; + + // Generate buttons at start + updateButtons(); + + // Init current settings + init(opts); + }); + + // Expose API + gitbook.fontsettings = { + enlargeFontSize: enlargeFontSize, + reduceFontSize: reduceFontSize, + setTheme: changeColorTheme, + setFamily: changeFontFamily, + getThemes: getThemes, + setThemes: setThemes, + getFamilies: getFamilies, + setFamilies: setFamilies + }; +}); + + diff --git a/book/gitbook/gitbook-plugin-fontsettings/website.css b/book/gitbook/gitbook-plugin-fontsettings/website.css new file mode 100644 index 0000000..26591fe --- /dev/null +++ b/book/gitbook/gitbook-plugin-fontsettings/website.css @@ -0,0 +1,291 @@ +/* + * Theme 1 + */ +.color-theme-1 .dropdown-menu { + background-color: #111111; + border-color: #7e888b; +} +.color-theme-1 .dropdown-menu .dropdown-caret .caret-inner { + border-bottom: 9px solid #111111; +} +.color-theme-1 .dropdown-menu .buttons { + border-color: #7e888b; +} +.color-theme-1 .dropdown-menu .button { + color: #afa790; +} +.color-theme-1 .dropdown-menu .button:hover { + color: #73553c; +} +/* + * Theme 2 + */ +.color-theme-2 .dropdown-menu { + background-color: #2d3143; + border-color: #272a3a; +} +.color-theme-2 .dropdown-menu .dropdown-caret .caret-inner { + border-bottom: 9px solid #2d3143; +} +.color-theme-2 .dropdown-menu .buttons { + border-color: #272a3a; +} +.color-theme-2 .dropdown-menu .button { + color: #62677f; +} +.color-theme-2 .dropdown-menu .button:hover { + color: #f4f4f5; +} +.book .book-header .font-settings .font-enlarge { + line-height: 30px; + font-size: 1.4em; +} +.book .book-header .font-settings .font-reduce { + line-height: 30px; + font-size: 1em; +} +.book.color-theme-1 .book-body { + color: #704214; + background: #f3eacb; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section { + background: #f3eacb; +} +.book.color-theme-2 .book-body { + color: #bdcadb; + background: #1c1f2b; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section { + background: #1c1f2b; +} +.book.font-size-0 .book-body .page-inner section { + font-size: 1.2rem; +} +.book.font-size-1 .book-body .page-inner section { + font-size: 1.4rem; +} +.book.font-size-2 .book-body .page-inner section { + font-size: 1.6rem; +} +.book.font-size-3 .book-body .page-inner section { + font-size: 2.2rem; +} +.book.font-size-4 .book-body .page-inner section { + font-size: 4rem; +} +.book.font-family-0 { + font-family: Georgia, serif; +} +.book.font-family-1 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal { + color: #704214; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 { + border-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr { + background-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote { + border-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { + background: #fdf6e3; + color: #657b83; + border-color: #f8df9c; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight { + background-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td { + border-color: #f5d06c; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr { + color: inherit; + background-color: #fdf6e3; + border-color: #444444; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { + background-color: #fbeecb; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal { + color: #bdcadb; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a { + color: #3eb1d0; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { + color: #fffffa; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 { + border-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { + color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr { + background-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote { + border-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { + color: #9dbed8; + background: #2d3143; + border-color: #2d3143; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight { + background-color: #282a39; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td { + border-color: #3b3f54; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr { + color: #b6c2d2; + background-color: #2d3143; + border-color: #3b3f54; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { + background-color: #35394b; +} +.book.color-theme-1 .book-header { + color: #afa790; + background: transparent; +} +.book.color-theme-1 .book-header .btn { + color: #afa790; +} +.book.color-theme-1 .book-header .btn:hover { + color: #73553c; + background: none; +} +.book.color-theme-1 .book-header h1 { + color: #704214; +} +.book.color-theme-2 .book-header { + color: #7e888b; + background: transparent; +} +.book.color-theme-2 .book-header .btn { + color: #3b3f54; +} +.book.color-theme-2 .book-header .btn:hover { + color: #fffff5; + background: none; +} +.book.color-theme-2 .book-header h1 { + color: #bdcadb; +} +.book.color-theme-1 .book-body .navigation { + color: #afa790; +} +.book.color-theme-1 .book-body .navigation:hover { + color: #73553c; +} +.book.color-theme-2 .book-body .navigation { + color: #383f52; +} +.book.color-theme-2 .book-body .navigation:hover { + color: #fffff5; +} +/* + * Theme 1 + */ +.book.color-theme-1 .book-summary { + color: #afa790; + background: #111111; + border-right: 1px solid rgba(0, 0, 0, 0.07); +} +.book.color-theme-1 .book-summary .book-search { + background: transparent; +} +.book.color-theme-1 .book-summary .book-search input, +.book.color-theme-1 .book-summary .book-search input:focus { + border: 1px solid transparent; +} +.book.color-theme-1 .book-summary ul.summary li.divider { + background: #7e888b; + box-shadow: none; +} +.book.color-theme-1 .book-summary ul.summary li i.fa-check { + color: #33cc33; +} +.book.color-theme-1 .book-summary ul.summary li.done > a { + color: #877f6a; +} +.book.color-theme-1 .book-summary ul.summary li a, +.book.color-theme-1 .book-summary ul.summary li span { + color: #877f6a; + background: transparent; + font-weight: normal; +} +.book.color-theme-1 .book-summary ul.summary li.active > a, +.book.color-theme-1 .book-summary ul.summary li a:hover { + color: #704214; + background: transparent; + font-weight: normal; +} +/* + * Theme 2 + */ +.book.color-theme-2 .book-summary { + color: #bcc1d2; + background: #2d3143; + border-right: none; +} +.book.color-theme-2 .book-summary .book-search { + background: transparent; +} +.book.color-theme-2 .book-summary .book-search input, +.book.color-theme-2 .book-summary .book-search input:focus { + border: 1px solid transparent; +} +.book.color-theme-2 .book-summary ul.summary li.divider { + background: #272a3a; + box-shadow: none; +} +.book.color-theme-2 .book-summary ul.summary li i.fa-check { + color: #33cc33; +} +.book.color-theme-2 .book-summary ul.summary li.done > a { + color: #62687f; +} +.book.color-theme-2 .book-summary ul.summary li a, +.book.color-theme-2 .book-summary ul.summary li span { + color: #c1c6d7; + background: transparent; + font-weight: 600; +} +.book.color-theme-2 .book-summary ul.summary li.active > a, +.book.color-theme-2 .book-summary ul.summary li a:hover { + color: #f4f4f5; + background: #252737; + font-weight: 600; +} diff --git a/book/gitbook/gitbook-plugin-forkmegithub/plugin.css b/book/gitbook/gitbook-plugin-forkmegithub/plugin.css new file mode 100644 index 0000000..93e5182 --- /dev/null +++ b/book/gitbook/gitbook-plugin-forkmegithub/plugin.css @@ -0,0 +1,34 @@ +.book .book-header { + margin-right: 120px; +} + +.book .book-header h1 { + padding-left: 140px; + padding-right: 140px; +} + +a#forkmegithub img { + position: absolute; + top: 0; + right: 0; + border: 0; +} + +i.fa-github { + display: none; +} + +@media (max-width:800px) { + .book .book-header { + margin-right: 0px; + } + + a#forkmegithub { + display: none; + } + + i.fa-github { + display: inline-block; + } +} + diff --git a/book/gitbook/gitbook-plugin-forkmegithub/plugin.js b/book/gitbook/gitbook-plugin-forkmegithub/plugin.js new file mode 100644 index 0000000..f7b8354 --- /dev/null +++ b/book/gitbook/gitbook-plugin-forkmegithub/plugin.js @@ -0,0 +1,61 @@ +require(['gitbook', 'jQuery'], function (gitbook, $) { + var colorRibbons = { + red: { + src: 'https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67', + canonicalSrc: 'https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png', + }, + green: { + src: 'https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67', + canonicalSrc: 'https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png', + }, + darkblue: { + src: 'https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67', + canonicalSrc: 'https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png', + }, + orange: { + src: 'https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67', + canonicalSrc: 'https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png', + }, + gray: { + src: 'https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67', + canonicalSrc: 'https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png', + }, + }; + + var forkmeRibbon; + var pluginConfig = {}; + function initializePlugin(config) { + pluginConfig = config.forkmegithub; + + var colorRibbon = colorRibbons[pluginConfig.color]; + forkmeRibbon + = '' + + 'Fork me on GitHub' + + '' + ; + } + + function getPluginConfig() { + return pluginConfig; + } + + gitbook.events.bind('start', function (e, config) { + initializePlugin(config); + + gitbook.toolbar.createButton({ + icon: 'fa fa-github', + label: 'GitHub', + position: 'right', + onClick: function() { + window.open(pluginConfig.url); + } + }); + }); + + gitbook.events.bind('page.change', function() { + var bodyInner = $('.book .book-body .body-inner'); + bodyInner.append(forkmeRibbon); + }); +}); + diff --git a/book/gitbook/gitbook-plugin-highlight/ebook.css b/book/gitbook/gitbook-plugin-highlight/ebook.css new file mode 100644 index 0000000..cecaaab --- /dev/null +++ b/book/gitbook/gitbook-plugin-highlight/ebook.css @@ -0,0 +1,135 @@ +pre, +code { + /* http://jmblog.github.io/color-themes-for-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +pre .hljs-comment, +code .hljs-comment, +pre .hljs-title, +code .hljs-title { + color: #8e908c; +} +pre .hljs-variable, +code .hljs-variable, +pre .hljs-attribute, +code .hljs-attribute, +pre .hljs-tag, +code .hljs-tag, +pre .hljs-regexp, +code .hljs-regexp, +pre .hljs-deletion, +code .hljs-deletion, +pre .ruby .hljs-constant, +code .ruby .hljs-constant, +pre .xml .hljs-tag .hljs-title, +code .xml .hljs-tag .hljs-title, +pre .xml .hljs-pi, +code .xml .hljs-pi, +pre .xml .hljs-doctype, +code .xml .hljs-doctype, +pre .html .hljs-doctype, +code .html .hljs-doctype, +pre .css .hljs-id, +code .css .hljs-id, +pre .css .hljs-class, +code .css .hljs-class, +pre .css .hljs-pseudo, +code .css .hljs-pseudo { + color: #c82829; +} +pre .hljs-number, +code .hljs-number, +pre .hljs-preprocessor, +code .hljs-preprocessor, +pre .hljs-pragma, +code .hljs-pragma, +pre .hljs-built_in, +code .hljs-built_in, +pre .hljs-literal, +code .hljs-literal, +pre .hljs-params, +code .hljs-params, +pre .hljs-constant, +code .hljs-constant { + color: #f5871f; +} +pre .ruby .hljs-class .hljs-title, +code .ruby .hljs-class .hljs-title, +pre .css .hljs-rules .hljs-attribute, +code .css .hljs-rules .hljs-attribute { + color: #eab700; +} +pre .hljs-string, +code .hljs-string, +pre .hljs-value, +code .hljs-value, +pre .hljs-inheritance, +code .hljs-inheritance, +pre .hljs-header, +code .hljs-header, +pre .hljs-addition, +code .hljs-addition, +pre .ruby .hljs-symbol, +code .ruby .hljs-symbol, +pre .xml .hljs-cdata, +code .xml .hljs-cdata { + color: #718c00; +} +pre .css .hljs-hexcolor, +code .css .hljs-hexcolor { + color: #3e999f; +} +pre .hljs-function, +code .hljs-function, +pre .python .hljs-decorator, +code .python .hljs-decorator, +pre .python .hljs-title, +code .python .hljs-title, +pre .ruby .hljs-function .hljs-title, +code .ruby .hljs-function .hljs-title, +pre .ruby .hljs-title .hljs-keyword, +code .ruby .hljs-title .hljs-keyword, +pre .perl .hljs-sub, +code .perl .hljs-sub, +pre .javascript .hljs-title, +code .javascript .hljs-title, +pre .coffeescript .hljs-title, +code .coffeescript .hljs-title { + color: #4271ae; +} +pre .hljs-keyword, +code .hljs-keyword, +pre .javascript .hljs-function, +code .javascript .hljs-function { + color: #8959a8; +} +pre .hljs, +code .hljs { + display: block; + background: white; + color: #4d4d4c; + padding: 0.5em; +} +pre .coffeescript .javascript, +code .coffeescript .javascript, +pre .javascript .xml, +code .javascript .xml, +pre .tex .hljs-formula, +code .tex .hljs-formula, +pre .xml .javascript, +code .xml .javascript, +pre .xml .vbscript, +code .xml .vbscript, +pre .xml .css, +code .xml .css, +pre .xml .hljs-cdata, +code .xml .hljs-cdata { + opacity: 0.5; +} diff --git a/book/gitbook/gitbook-plugin-highlight/website.css b/book/gitbook/gitbook-plugin-highlight/website.css new file mode 100644 index 0000000..6674448 --- /dev/null +++ b/book/gitbook/gitbook-plugin-highlight/website.css @@ -0,0 +1,434 @@ +.book .book-body .page-wrapper .page-inner section.normal pre, +.book .book-body .page-wrapper .page-inner section.normal code { + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #8e908c; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #c82829; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #f5871f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #eab700; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #718c00; +} +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #3e999f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #4271ae; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #8959a8; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: white; + color: #4d4d4c; + padding: 0.5em; +} +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { + /* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + /* Solarized Green */ + /* Solarized Cyan */ + /* Solarized Blue */ + /* Solarized Yellow */ + /* Solarized Orange */ + /* Solarized Red */ + /* Solarized Violet */ +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc { + color: #93a1a1; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title { + color: #859900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url { + color: #2aa198; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function { + color: #268bd2; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference { + color: #b58900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header { + color: #cb4b16; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important { + color: #dc322f; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label { + color: #6c71c4; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula { + background: #eee8d5; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { + /* Tomorrow Night Bright Theme */ + /* Original theme - https://github.com/chriskempson/tomorrow-theme */ + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #969896; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #d54e53; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #e78c45; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #e7c547; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #b9ca4a; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #70c0b1; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #7aa6da; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #c397d8; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: black; + color: #eaeaea; + padding: 0.5em; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} diff --git a/book/gitbook/gitbook-plugin-lunr/lunr.min.js b/book/gitbook/gitbook-plugin-lunr/lunr.min.js new file mode 100644 index 0000000..6aa6bc7 --- /dev/null +++ b/book/gitbook/gitbook-plugin-lunr/lunr.min.js @@ -0,0 +1,7 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 + * Copyright (C) 2015 Oliver Nightingale + * MIT Licensed + * @license + */ +!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;no;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n element for each result + res.results.forEach(function(res) { + var $li = $('
                                                                  • ', { + 'class': 'search-results-item' + }); + + var $title = $('

                                                                    '); + + var $link = $('', { + 'href': gitbook.state.basePath + '/' + res.url, + 'text': res.title + }); + + var content = res.body.trim(); + if (content.length > MAX_DESCRIPTION_SIZE) { + content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...'; + } + var $content = $('

                                                                    ').html(content); + + $link.appendTo($title); + $title.appendTo($li); + $content.appendTo($li); + $li.appendTo($searchList); + }); + } + + function launchSearch(q) { + // Add class for loading + $body.addClass('with-search'); + $body.addClass('search-loading'); + + // Launch search query + throttle(gitbook.search.query(q, 0, MAX_RESULTS) + .then(function(results) { + displayResults(results); + }) + .always(function() { + $body.removeClass('search-loading'); + }), 1000); + } + + function closeSearch() { + $body.removeClass('with-search'); + $bookSearchResults.removeClass('open'); + } + + function launchSearchFromQueryString() { + var q = getParameterByName('q'); + if (q && q.length > 0) { + // Update search input + $searchInput.val(q); + + // Launch search + launchSearch(q); + } + } + + function bindSearch() { + // Bind DOM + $searchInput = $('#book-search-input input'); + $bookSearchResults = $('#book-search-results'); + $searchList = $bookSearchResults.find('.search-results-list'); + $searchTitle = $bookSearchResults.find('.search-results-title'); + $searchResultsCount = $searchTitle.find('.search-results-count'); + $searchQuery = $searchTitle.find('.search-query'); + + // Launch query based on input content + function handleUpdate() { + var q = $searchInput.val(); + + if (q.length == 0) { + closeSearch(); + } + else { + launchSearch(q); + } + } + + // Detect true content change in search input + // Workaround for IE < 9 + var propertyChangeUnbound = false; + $searchInput.on('propertychange', function(e) { + if (e.originalEvent.propertyName == 'value') { + handleUpdate(); + } + }); + + // HTML5 (IE9 & others) + $searchInput.on('input', function(e) { + // Unbind propertychange event for IE9+ + if (!propertyChangeUnbound) { + $(this).unbind('propertychange'); + propertyChangeUnbound = true; + } + + handleUpdate(); + }); + + // Push to history on blur + $searchInput.on('blur', function(e) { + // Update history state + if (usePushState) { + var uri = updateQueryString('q', $(this).val()); + history.pushState({ path: uri }, null, uri); + } + }); + } + + gitbook.events.on('page.change', function() { + bindSearch(); + closeSearch(); + + // Launch search based on query parameter + if (gitbook.search.isInitialized()) { + launchSearchFromQueryString(); + } + }); + + gitbook.events.on('search.ready', function() { + bindSearch(); + + // Launch search from query param at start + launchSearchFromQueryString(); + }); + + function getParameterByName(name) { + var url = window.location.href; + name = name.replace(/[\[\]]/g, '\\$&'); + var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, ' ')); + } + + function updateQueryString(key, value) { + value = encodeURIComponent(value); + + var url = window.location.href; + var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'), + hash; + + if (re.test(url)) { + if (typeof value !== 'undefined' && value !== null) + return url.replace(re, '$1' + key + '=' + value + '$2$3'); + else { + hash = url.split('#'); + url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); + if (typeof hash[1] !== 'undefined' && hash[1] !== null) + url += '#' + hash[1]; + return url; + } + } + else { + if (typeof value !== 'undefined' && value !== null) { + var separator = url.indexOf('?') !== -1 ? '&' : '?'; + hash = url.split('#'); + url = hash[0] + separator + key + '=' + value; + if (typeof hash[1] !== 'undefined' && hash[1] !== null) + url += '#' + hash[1]; + return url; + } + else + return url; + } + } +}); diff --git a/book/gitbook/gitbook-plugin-sharing/buttons.js b/book/gitbook/gitbook-plugin-sharing/buttons.js new file mode 100644 index 0000000..709a4e4 --- /dev/null +++ b/book/gitbook/gitbook-plugin-sharing/buttons.js @@ -0,0 +1,90 @@ +require(['gitbook', 'jquery'], function(gitbook, $) { + var SITES = { + 'facebook': { + 'label': 'Facebook', + 'icon': 'fa fa-facebook', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href)); + } + }, + 'twitter': { + 'label': 'Twitter', + 'icon': 'fa fa-twitter', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href)); + } + }, + 'google': { + 'label': 'Google+', + 'icon': 'fa fa-google-plus', + 'onClick': function(e) { + e.preventDefault(); + window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href)); + } + }, + 'weibo': { + 'label': 'Weibo', + 'icon': 'fa fa-weibo', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)); + } + }, + 'instapaper': { + 'label': 'Instapaper', + 'icon': 'fa fa-instapaper', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href)); + } + }, + 'vk': { + 'label': 'VK', + 'icon': 'fa fa-vk', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href)); + } + } + }; + + + + gitbook.events.bind('start', function(e, config) { + var opts = config.sharing; + + // Create dropdown menu + var menu = $.map(opts.all, function(id) { + var site = SITES[id]; + + return { + text: site.label, + onClick: site.onClick + }; + }); + + // Create main button with dropdown + if (menu.length > 0) { + gitbook.toolbar.createButton({ + icon: 'fa fa-share-alt', + label: 'Share', + position: 'right', + dropdown: [menu] + }); + } + + // Direct actions to share + $.each(SITES, function(sideId, site) { + if (!opts[sideId]) return; + + gitbook.toolbar.createButton({ + icon: site.icon, + label: site.text, + position: 'right', + onClick: site.onClick + }); + }); + }); +}); diff --git a/book/gitbook/gitbook-plugin-splitter/splitter.css b/book/gitbook/gitbook-plugin-splitter/splitter.css new file mode 100644 index 0000000..4e84720 --- /dev/null +++ b/book/gitbook/gitbook-plugin-splitter/splitter.css @@ -0,0 +1,22 @@ +.divider-content-summary { + position: absolute; + top: 0; + right: 0; + height: 100%; + width: 5px; + display: table; + cursor: col-resize; + color: #ccc; + -webkit-transition: color 350ms ease; + -moz-transition: color 350ms ease; + -o-transition: color 350ms ease; + transition: color 350ms ease +} +.divider-content-summary:hover { + color: #444; +} + .divider-content-summary__icon { + display: table-cell; + vertical-align: middle; + text-align: center; + } diff --git a/book/gitbook/gitbook-plugin-splitter/splitter.js b/book/gitbook/gitbook-plugin-splitter/splitter.js new file mode 100644 index 0000000..5034e5b --- /dev/null +++ b/book/gitbook/gitbook-plugin-splitter/splitter.js @@ -0,0 +1,128 @@ +require(['gitbook', 'jQuery'], function (gitbook, $) { + + // MEMO: + // Gitbook is calculated as "calc (100% - 60px)" in the horizontal width when the width of the screen size is 600px + // or less. + // In this case, since contradiction occurs in the implementation of this module, return. + if($(window).width() <= 600) { + return; + } + + gitbook.events.bind('start', function () { + }); + + gitbook.events.bind('page.change', function () { + + var KEY_SPLIT_STATE = 'plugin_gitbook_split'; + + var dividerWidth = null; + var isDraggable = false; + var dividerCenterOffsetLeft = null; + var splitState = null; + var grabPointWidth = null; + + var $body = $('body'); + var $book = $('.book'); + var $summary = $('.book-summary'); + var $bookBody = $('.book-body'); + var $divider = $('

                                                                    ' + + '
                                                                    ' + + '' + + '
                                                                    ' + + '
                                                                    '); + + $summary.append($divider); + + dividerWidth = $divider.outerWidth(); + dividerCenterOffsetLeft = $divider.outerWidth() / 2; + + // restore split state from sessionStorage + splitState = getSplitState(); + setSplitState( + splitState.summaryWidth, + splitState.summaryOffset, + splitState.bookBodyOffset + ); + + setTimeout(function() { + var isGreaterThanEqualGitbookV2_5 = !Boolean($('.toggle-summary').length); + + var $toggleSummary = isGreaterThanEqualGitbookV2_5 + ? $('.fa.fa-align-justify').parent() : $('.toggle-summary'); + + $toggleSummary.on('click', function () { + + var summaryOffset = null; + var bookBodyOffset = null; + + var isOpen = isGreaterThanEqualGitbookV2_5 + ? !gitbook.sidebar.isOpen() : $book.hasClass('with-summary'); + + if (isOpen) { + summaryOffset = -($summary.outerWidth()); + bookBodyOffset = 0; + } else { + summaryOffset = 0; + bookBodyOffset = $summary.outerWidth(); + } + + setSplitState($summary.outerWidth(), summaryOffset, bookBodyOffset); + saveSplitState($summary.outerWidth(), summaryOffset, bookBodyOffset); + }); + }, 1); + + $divider.on('mousedown', function (event) { + event.stopPropagation(); + isDraggable = true; + grabPointWidth = $summary.outerWidth() - event.pageX; + }); + + $body.on('mouseup', function (event) { + event.stopPropagation(); + isDraggable = false; + saveSplitState( + $summary.outerWidth(), + $summary.position().left, + $bookBody.position().left + ); + }); + + $body.on('mousemove', function (event) { + if (!isDraggable) { + return; + } + event.stopPropagation(); + event.preventDefault(); + $summary.outerWidth(event.pageX + grabPointWidth); + $bookBody.offset({ left: event.pageX + grabPointWidth }); + }); + + function getSplitState() { + var splitState = JSON.parse(sessionStorage.getItem(KEY_SPLIT_STATE)); + splitState || (splitState = {}); + splitState.summaryWidth || (splitState.summaryWidth = $summary.outerWidth()); + splitState.summaryOffset || (splitState.summaryOffset = $summary.position().left); + splitState.bookBodyOffset || (splitState.bookBodyOffset = $bookBody.position().left); + return splitState; + } + + function saveSplitState(summaryWidth, summaryWidthOffset, bookBodyOffset) { + sessionStorage.setItem(KEY_SPLIT_STATE, JSON.stringify({ + summaryWidth: summaryWidth, + summaryOffset: summaryWidthOffset, + bookBodyOffset: bookBodyOffset, + })); + } + + function setSplitState(summaryWidth, summaryOffset, bookBodyOffset) { + $summary.outerWidth(summaryWidth); + $summary.offset({ left: summaryOffset }); + $bookBody.offset({ left: bookBodyOffset }); + // improved broken layout in windows chrome. + // "$(x).offset" automatically add to "position:relative". + // but it cause layout broken.. + $summary.css({ position: 'absolute' }); + $bookBody.css({ position: 'absolute' }); + } + }); +}); diff --git a/book/gitbook/gitbook.js b/book/gitbook/gitbook.js new file mode 100644 index 0000000..13077b4 --- /dev/null +++ b/book/gitbook/gitbook.js @@ -0,0 +1,4 @@ +!function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):"string"!=typeof t?de.grep(e,function(e){return se.call(t,e)>-1!==n}):je.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return se.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function s(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function a(e){return e}function u(e){throw e}function c(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function l(){te.removeEventListener("DOMContentLoaded",l),e.removeEventListener("load",l),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Pe,"-$&").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n=p(n)}catch(e){}Re.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,s=20,a=r?function(){return r.cur()}:function(){return de.css(e,t,"")},u=a(),c=n&&n[3]||(de.cssNumber[t]?"":"px"),l=(de.cssNumber[t]||"px"!==c&&+u)&&$e.exec(de.css(e,t));if(l&&l[3]!==c){c=c||l[3],n=n||[],l=+u||1;do i=i||".5",l/=i,de.style(e,t,l+c);while(i!==(i=a()/u)&&1!==i&&--s)}return n&&(l=+l||+u||0,o=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=c,r.start=l,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,"display"),t.parentNode.removeChild(t),"none"===o&&(o="block"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,s=e.length;i-1)o&&o.push(i);else if(c=de.contains(i.ownerDocument,i),s=v(f.appendChild(i),"script"),c&&y(s),n)for(l=0;i=s[l++];)Ve.test(i.type||"")&&n.push(i);return f}function b(){return!0}function w(){return!1}function T(){try{return te.activeElement}catch(e){}}function C(e,t,n,r,o,i){var s,a;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(a in t)C(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(s=o,o=function(e){return de().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function j(e,t){return de.nodeName(e,"table")&&de.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e:e}function k(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function S(e,t){var n,r,o,i,s,a,u,c;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),s=Fe.set(t,i),c=i.events)){delete s.handle,s.events={};for(o in c)for(n=0,r=c[o].length;n1&&"string"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=x(t,e[0].ownerDocument,!1,e,o),s=i.firstChild,1===i.childNodes.length&&(i=s),s||o)){for(a=de.map(v(i,"script"),k),u=a.length;f=0&&nC.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split("|"),r=n.length;r--;)C.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return function(t){return"form"in t?t.parentNode&&t.disabled===!1?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&je(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),s=i.length;s--;)n[o=i[s]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r="";t1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o-1&&(r[c]=!(s[c]=f))}}else x=v(x===s?x.splice(d,x.length):x),i?i(null,s,x,u):K.apply(s,x)})}function x(e){for(var t,n,r,o=e.length,i=C.relative[e[0].type],s=i||C.relative[" "],a=i?1:0,u=d(function(e){return e===t},s,!0),c=d(function(e){return ee(t,e)>-1},s,!0),l=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):c(e,n,r));return t=null,o}];a1&&g(l),a>1&&h(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ae,"$1"),n,a0,i=e.length>0,s=function(r,s,a,u,c){var l,f,p,h=0,d="0",g=r&&[],m=[],y=A,x=r||i&&C.find.TAG("*",c),b=B+=null==y?1:Math.random()||.1,w=x.length;for(c&&(A=s===L||s||c);d!==w&&null!=(l=x[d]);d++){if(i&&l){for(f=0,s||l.ownerDocument===L||(O(l),a=!F);p=e[f++];)if(p(l,s||L,a)){u.push(l);break}c&&(B=b)}o&&((l=!p&&l)&&h--,r&&g.push(l))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,s,a);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Q.call(u));m=v(m)}K.apply(u,m),c&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return c&&(B=b,A=y),g};return o?r(s):s}var w,T,C,j,k,E,S,N,A,q,D,O,L,H,F,R,I,P,M,$="sizzle"+1*new Date,W=e.document,B=0,_=0,U=n(),z=n(),X=n(),V=function(e,t){return e===t&&(D=!0),0},G={}.hasOwnProperty,Y=[],Q=Y.pop,J=Y.push,K=Y.push,Z=Y.slice,ee=function(e,t){for(var n=0,r=e.length;n+~]|"+ne+")"+ne+"*"),le=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(ie),pe=new RegExp("^"+re+"$"),he={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+ie),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ve=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,xe=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),be=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,Te=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},Ce=function(){O()},je=d(function(e){return e.disabled===!0&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{K.apply(Y=Z.call(W.childNodes),W.childNodes),Y[W.childNodes.length].nodeType}catch(e){K={apply:Y.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}T=t.support={},k=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!k(L),W!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Ce,!1):n.attachEvent&&n.attachEvent("onunload",Ce)),T.attributes=o(function(e){return e.className="i",!e.getAttribute("className")}),T.getElementsByTagName=o(function(e){return e.appendChild(L.createComment("")),!e.getElementsByTagName("*").length}),T.getElementsByClassName=me.test(L.getElementsByClassName),T.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),T.getById?(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){return e.getAttribute("id")===t}},C.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},C.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode("id"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode("id"),n&&n.value===e)return[i]}return[]}}),C.find.TAG=T.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):T.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if("*"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},C.find.CLASS=T.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],R=[],(T.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML="
                                                                    ",e.querySelectorAll("[msallowcapture^='']").length&&R.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||R.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+$+"-]").length||R.push("~="),e.querySelectorAll(":checked").length||R.push(":checked"),e.querySelectorAll("a#"+$+"+*").length||R.push(".#.+[+~]")}),o(function(e){e.innerHTML="";var t=L.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&R.push("name"+ne+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&R.push(":enabled",":disabled"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&R.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),R.push(",.*:")})),(T.matchesSelector=me.test(P=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){T.disconnectedMatch=P.call(e,"*"),P.call(e,"[s!='']:x"),I.push("!=",ie)}),R=R.length&&new RegExp(R.join("|")),I=I.length&&new RegExp(I.join("|")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},V=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!T.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===W&&M(W,e)?-1:t===L||t.ownerDocument===W&&M(W,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]===W?-1:u[r]===W?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(le,"='$1']"),T.matchesSelector&&F&&!X[n+" "]&&(!I||!I.test(n))&&(!R||!R.test(n)))try{var r=P.call(e,n);if(r||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=C.attrHandle[t.toLowerCase()],r=n&&G.call(C.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:T.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+"").replace(we,Te)},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!T.detectDuplicates,q=!T.sortStable&&e.slice(0),e.sort(V),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},j=t.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=j(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=j(t);return n},C=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,be),e[3]=(e[3]||e[4]||e[5]||"").replace(xe,be),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,be).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&U(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?"!="===n:!n||(i+="","="===n?i===r:"!="===n?i!==r:"^="===n?r&&0===i.indexOf(r):"*="===n?r&&i.indexOf(r)>-1:"$="===n?r&&i.slice(-r.length)===r:"~="===n?(" "+i.replace(se," ")+" ").indexOf(r)>-1:"|="===n&&(i===r||i.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,o){var i="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,p,h,d,g=i!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(a?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&y){for(p=m,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h&&c[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(x=h=0)||d.pop();)if(1===p.nodeType&&++x&&p===t){l[e]=[B,h,x];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h),x===!1)for(;(p=++h&&p&&p[g]||(x=h=0)||d.pop())&&((a?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++x||(y&&(f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),l[e]=[B,x]),p!==t)););return x-=o,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var o,i=C.pseudos[e]||C.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return i[$]?i(n):i.length>1?(o=[e,e,"",n],C.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),s=o.length;s--;)r=ee(e,o[s]),e[r]=!(t[r]=o[s])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=S(e.replace(ae,"$1"));return o[$]?r(function(e,t,n,r){for(var i,s=o(e,null,r,[]),a=e.length;a--;)(i=s[a])&&(e[a]=!(t[a]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){ +return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(xe,be),function(t){return(t.textContent||t.innerText||j(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(xe,be).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:c(!1),disabled:c(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r2&&"ID"===(s=i[0]).type&&9===t.nodeType&&F&&C.relative[i[1].type]){if(t=(C.find.ID(s.matches[0].replace(xe,be),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(s=i[o],!C.relative[a=s.type]);)if((u=C.find[a])&&(r=u(s.matches[0].replace(xe,be),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return K.apply(n,r),n;break}}return(c||S(e,l))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},T.sortStable=$.split("").sort(V).join("")===$,T.detectDuplicates=!!D,O(),T.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement("fieldset"))}),o(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||i("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),T.attributes&&o(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||i("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute("disabled")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=xe,de.expr=xe.selectors,de.expr[":"]=de.expr.pseudos,de.uniqueSort=de.unique=xe.uniqueSort,de.text=xe.getText,de.isXMLDoc=xe.isXML,de.contains=xe.contains,de.escapeSelector=xe.escape;var be=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Te=de.expr.match.needsContext,Ce=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,je=/^.[^:#\[\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if("string"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,"string"==typeof e&&Te.test(e)?de(e):e||[],!1).length}});var ke,Ee=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,Se=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||ke,"string"==typeof e){if(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Ce.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Se.prototype=de.fn,ke=de(te);var Ne=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?"string"==typeof e?se.call(de(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return be(e,"parentNode")},parentsUntil:function(e,t,n){return be(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return be(e,"nextSibling")},prevAll:function(e){return be(e,"previousSibling")},nextUntil:function(e,t,n){return be(e,"nextSibling",n)},prevUntil:function(e,t,n){return be(e,"previousSibling",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Ne.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\x20\t\r\n\f]+/g;de.Callbacks=function(e){e="string"==typeof e?s(e):de.extend({},e);var t,n,r,o,i=[],a=[],u=-1,c=function(){for(o=e.once,r=t=!0;a.length;u=-1)for(n=a.shift();++u-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||t||(i=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},de.extend({Deferred:function(t){var n=[["notify","progress",de.Callbacks("memory"),de.Callbacks("memory"),2],["resolve","done",de.Callbacks("once memory"),de.Callbacks("once memory"),0,"resolved"],["reject","fail",de.Callbacks("once memory"),de.Callbacks("once memory"),1,"rejected"]],r="pending",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var c=this,l=arguments,f=function(){var e,f;if(!(t=s&&(r!==u&&(c=void 0,l=[e]),n.rejectWith(c,l))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var s=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:a,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:a)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var s=t[2],a=t[5];o[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[0][2].lock),s.add(t[3].fire),i[t[0]]=function(){return i[t[0]+"With"](this===i?void 0:this,arguments),this},i[t[0]+"With"]=s.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(c(e,i.done(s(n)).resolve,i.reject),"pending"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)c(o[n],s(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,"complete"===te.readyState||"loading"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener("DOMContentLoaded",l),e.addEventListener("load",l));var Le=function(e,t,n,r,o,i,s){var a=0,u=e.length,c=null==n;if("object"===de.type(n)){o=!0;for(a in n)Le(e,t,a,n[a],!0,i,s)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(de(e),n)})),t))for(;a1,null,!0)},removeData:function(e){return this.each(function(){Re.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),s=function(){de.dequeue(e,t)};"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===t&&n.unshift("inprogress"),delete i.stop,o.call(e,s,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks("once memory").add(function(){Fe.remove(e,[t+"queue",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,Ve=/^$|\/(?:java|ecma)script/i,Ge={option:[1,""],thead:[1,"","
                                                                    "],col:[2,"","
                                                                    "],tr:[2,"","
                                                                    "],td:[3,"","
                                                                    "],_default:[0,"",""]};Ge.optgroup=Ge.option,Ge.tbody=Ge.tfoot=Ge.colgroup=Ge.caption=Ge.thead,Ge.th=Ge.td;var Ye=/<|&#?\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement("div")),n=te.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Qe=te.documentElement,Je=/^key/,Ke=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Qe,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return"undefined"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(qe)||[""],c=t.length;c--;)a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},l=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(".")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||"").match(qe)||[""],c=t.length;c--;)if(a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=i=p.length;i--;)l=p[i],!o&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[c],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,s,a=de.event.fix(e),u=new Array(arguments.length),c=(Fe.get(this,"events")||{})[a.type]||[],l=de.event.special[a.type]||{};for(u[0]=a,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||c.disabled!==!0)){for(i=[],s={},n=0;n-1:de.find(o,this,null,[c]).length),s[o]&&i.push(r);i.length&&a.push({elem:c,handlers:i})}return c=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,tt=/\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,"<$1>")},clone:function(e,t,n){var r,o,i,s,a=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(s=v(a),i=v(e),r=0,o=i.length;r0&&y(s,!u&&v(e,"script")),a},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Re.expando]&&(n[Re.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!tt.test(e)&&!Ge[(Xe.exec(e)||["",""])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?"":"px")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=["*"]):e=e.match(qe);for(var n,r=0,o=e.length;r1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return"undefined"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+""),n):o&&"get"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&"radio"===t&&de.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,s=t.toLowerCase();return r||(i=yt[s],yt[s]=o,o=null!=n(e,t,r)?s:null,yt[s]=i),o}});var xt=/^(?:input|select|textarea|button)$/i,bt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&"get"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,"tabindex");return t?parseInt(t,10):xt.test(e.nodeName)||bt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if("string"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&" "+z(o)+" "){for(s=0;i=t[s++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");a=z(r),o!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&" "+z(o)+" "){for(s=0;i=t[s++];)for(;r.indexOf(" "+i+" ")>-1;)r=r.replace(" "+i+" "," ");a=z(r),o!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if("string"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||(t=X(this),t&&Fe.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||e===!1?"":Fe.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+z(X(n))+" ").indexOf(t)>-1)return!0;return!1}});var wt=/\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o="":"number"==typeof o?o+="":de.isArray(o)&&(o=de.map(o,function(e){return null==e?"":e+""})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:(n=o.value,"string"==typeof n?n.replace(wt,""):null==n?"":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,"value");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,s="select-one"===e.type,a=s?null:[],u=s?i+1:o.length;for(r=i<0?u:s?i:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each(["radio","checkbox"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Tt=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,s,a,u,c,l,f,p=[r||te],h=ce.call(t,"type")?t.type:t,d=ce.call(t,"namespace")?t.namespace.split("."):[];if(s=a=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Tt.test(h+de.event.triggered)&&(h.indexOf(".")>-1&&(d=h.split("."),h=d.shift(),d.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[de.expando]?t:new de.Event(h,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Tt.test(u+h)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||te)&&p.push(a.defaultView||a.parentWindow||e)}for(i=0;(s=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,l=(Fe.get(s,"events")||{})[t.type]&&Fe.get(s,"handle"),l&&l.apply(s,n),l=c&&s[c],l&&l.apply&&He(s)&&(t.result=l.apply(s,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||c&&de.isFunction(r[h])&&!de.isWindow(r)&&(a=r[c],a&&(r[c]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,a&&(r[c]=a)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin="onfocusin"in e,pe.focusin||de.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Ct=e.location,jt=de.now(),kt=/\?/;de.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||de.error("Invalid XML: "+t),n};var Et=/\[\]$/,St=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)V(n,e[n],t,o);return r.join("&")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,"elements");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(St,"\r\n")}}):{name:t.name,value:n.replace(St,"\r\n")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Pt={},Mt="*/".concat("*"),$t=te.createElement("a");$t.href=Ct.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Ht.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Mt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Q(Q(e,de.ajaxSettings),t):Q(de.ajaxSettings,e)},ajaxPrefilter:G(It),ajaxTransport:G(Pt),ajax:function(t,n){function r(t,n,r,a){var c,p,h,b,w,T=n;l||(l=!0,u&&e.clearTimeout(u),o=void 0,s=a||"",C.readyState=t>0?4:0,c=t>=200&&t<300||304===t,r&&(b=J(d,C,r)),b=K(d,b,C,c),c?(d.ifModified&&(w=C.getResponseHeader("Last-Modified"),w&&(de.lastModified[i]=w),w=C.getResponseHeader("etag"),w&&(de.etag[i]=w)),204===t||"HEAD"===d.type?T="nocontent":304===t?T="notmodified":(T=b.state,p=b.data,h=b.error,c=!h)):(h=T,!t&&T||(T="error",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+"",c?v.resolveWith(g,[p,T,C]):v.rejectWith(g,[C,T,h]),C.statusCode(x),x=void 0,f&&m.trigger(c?"ajaxSuccess":"ajaxError",[C,d,c?p:h]),y.fireWith(g,[C,T]),f&&(m.trigger("ajaxComplete",[C,d]),--de.active||de.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,s,a,u,c,l,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks("once memory"),x=d.statusCode||{},b={},w={},T="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=Lt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return l?s:null},setRequestHeader:function(e,t){return null==l&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return o&&o.abort(t),r(0,t),this}};if(v.promise(C),d.url=((t||d.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(qe)||[""],null==d.crossDomain){c=te.createElement("a");try{c.href=d.url,c.href=c.href,d.crossDomain=$t.protocol+"//"+$t.host!=c.protocol+"//"+c.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),Y(It,d,n,C),l)return C;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(qt,"+")):(h=d.url.slice(i.length),d.data&&(i+=(kt.test(i)?"&":"?")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,"$1"),h=(kt.test(i)?"&":"?")+"_="+jt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&C.setRequestHeader("If-Modified-Since",de.lastModified[i]),de.etag[i]&&C.setRequestHeader("If-None-Match",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",d.contentType),C.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Mt+"; q=0.01":""):d.accepts["*"]);for(p in d.headers)C.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,C,d)===!1||l))return C.abort();if(T="abort",y.add(d.complete),C.done(d.success),C.fail(d.error),o=Y(Pt,d,n,C)){if(C.readyState=1,f&&m.trigger("ajaxSend",[C,d]),l)return C;d.async&&d.timeout>0&&(u=e.setTimeout(function(){C.abort("timeout")},d.timeout));try{l=!1,o.send(b,r)}catch(e){if(l)throw e;r(-1,e)}}else r(-1,"No Transport");return C},getJSON:function(e,t,n){return de.get(e,t,n,"json")},getScript:function(e,t){return de.get(e,void 0,t,"script")}}),de.each(["get","post"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},Bt=de.ajaxSettings.xhr();pe.cors=!!Bt&&"withCredentials"in Bt,pe.ajax=Bt=!!Bt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Bt&&!t.crossDomain)return{send:function(o,i){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest");for(s in o)a.setRequestHeader(s,o[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?i(0,"error"):i(a.status,a.statusText):i(Wt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=n("error"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),de.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(" +

                                                                  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/search_index.json b/book/search_index.json new file mode 100644 index 0000000..a439205 --- /dev/null +++ b/book/search_index.json @@ -0,0 +1 @@ +{"index":{"version":"0.5.12","fields":[{"name":"title","boost":10},{"name":"keywords","boost":15},{"name":"body","boost":1}],"ref":"url","documentStore":{"store":{"./":["\"versions\"","(and","(c#,","(chinese)","(csrf)","(english","(even","(html,","(jvm)","(littleasp.net/book)","(model","(or","(the","(turkish)",".net",".net标准",".net标准1.0",".net标准1.5",".net标准2.0",".net标准,这些命名有些混乱,所以在此做一简短的释疑:","1","1.0.","1.5,","10","10x","2.0","2.0,","2.0,一个用于创建","2018.","387","4","4,","4.0","5","5,而后者的名字最终被改成了","75615","978","above)","absolut","actual","add","advanc","advantag","agnost","ahead","along","alreadi","already:","alright,","anoth","anyth","apach","api","api:","apis,","apis.","api。值得指出的是,.net","api。这是你将要安装到机器上,用来构建和运行","app","applic","application_start","applications,","applications.","appropri","area","around","asp.net","asp.net,","aspnetcor","asynchron","attacks,","attribut","avail","available,","available.","back","backend","bake","barbettini","basic","basic,","basic,f#)可以用来编写","becam","befor","begin","below.","benefit","between","big","bit.","book","book!","book,","book.","book/book/)的版本更新。有关版本信息和更新内容,请查阅本书的最后一页。","brought","bug","build","built","c#","c#,","came","center,","changelog.","chapter!","chapter.","check","choice,","choos","chunk","class","code","code,","code.","codes,","come","commercially).","common","commun","compar","compiled,","compiler,","complet","compris","concept","configur","confus","confusing,","connectors,","contain","content.","contribut","contributors,","control","controller)","controller),","controller)、依赖注入,和一个由中间件构成的请求处理管线。它基于","copy,","copyright","core","core!","core.","core?","core。","core?","cover","creat","creativ","credit","cross","css,","data","data.","databas","database,","decoupl","defin","definition.","depend","deploy","deserialization,","develop","developer,","didn't","differ","dive","django,","doesn't","don't","download","driven","e","each","ecosystem.","efficiency.","el","encourag","end","enough","entir","everyth","example,","execut","experi","explanation:","f#).","familiar","fantast","fast.","faster","featur","features.","feel","final","finish","fit","fix","focu","forgeri","format,","framework","framework).","framework,","framework?","free","freeli","frequent","front","frontend","function","functionality,","gems,","gems,或者","generation,","get","github:","github:","give","global.asax","global.asax.","go,","good","great","greek","ground","halfway","handl","harder","have","have?","haven't","hear","help","here'","home!","https://creativecommons.org/licenses/by/4.0/","https://www.github.com/nbarbettini/littl","i'll","idea","iis,","implement","import","improv","in,","inform","information,","inject","injection,","injection.","input","instal","intend","interact","interest","interfac","interpret","interpreter.","introduc","introduct","introduction.","is).","isbn:","it'","it'll","itself","java","java,","javascript","javascript)","json","katana","kitabı","know","know.","languag","languages:","laravel,","last","learn","learn:","legacy,","let'","level","librari","license,","license.","link","linter","linux","linux.","littl","log","long","longer","look","lot","mac","mac,","machin","make","manager;","mani","matter","maven).","maven)上有成千上万的软件包。有现成的包可用来完成","mean","measure,","mention","microservices.","microsoft","microsoft'","middleware,","middleware.","modern","more","more.","much","much.","multilingu","multithread","mvc","mvc,","mvc、视图模板和依赖注入。你将使用","mvc(model","name","naming,","nate","need","new","new,","next","ninject","ninject。整个框架已经针对速度和运行时效率进行了优化。","node,","node.j","node.js.","node/express,","node、python、ruby、go","note","notic","npm,","npm、rubi","nuget","nuget(.net","number","occasion","of.","offici","only.","open","oper","optim","origin","out","over","owin/katana","packag","page","paranoid","pattern","pdf","pdf,","pdf、电子书,或者打印版,请查阅官网(littleasp.net/book,中文版为","peopl","pick","piec","pipelin","platform","point","popular","prevent","previou","print","product,","program","programming,","project","provid","purpos","python,","rails,","rails、django、laravel","read","real","redistribut","reflect","registration,","releas","rememb","remix","renam","repres","request","reserved.","return","reus","rewrit","right","rubi","ruby,","ruby.","ruby。asp.net","run","runtim","runtime,","sanit","scratch!","secur","security.","see","seriously,","share,","short","similar","simpl","simpli","simplifies)","site","skip","someth","sound","sourc","specif","speed","speed.","split","spring,","standard","standard.","start","started.","startup","static","statu","structur","structuremap","stuff","support","surfac","system.","system.web,","system.web、iis、和","take","tasks.","teach","team","templates,","thank","there'","there:","thing","think","thousand","throughout","time.","times.","to.","todo","togeth","together)","tool","top","topics.","touch","transform","translat","turn","tutorial.","type","ultim","under","until","up","up.","updat","us","variabl","veri","version","version)","version,","view","views,","virtual","visit","visual","want","we'll","web","websit","web应用","wide","window","windows,","windows.","windows、mac或者linux上安装的","windows、mac,和","windst","windsting.github.io/littl","won't","work","world.","worries!","worry,","write","written","wrote","you'll","you'r","you,","yuyi","©","—","、","上。在","上构建并运行","上,但我不会过多涉及这个主题。","不再有区别:控制器可以方便的返回视图、状态码,或者数据。依赖注入功能已经内置了,所以,如果你不想费劲的话,完全可以不用再安装并配置一个服务容器了,比如","不论你此前在","专用的","之前,它是唯一的","之类的后端语言写程序,你会注意到很多熟悉的概念,比如","也为多线程和异步任务作了专门的优化。与使用","也可以跑在","什么是","什么是依赖注入以及它的实用之处","从构建伊始就注重安全。它已经自动处理了净化输入数据和跨域伪造请求(csrf),你就不需要操心这些了。你同时还享有","代码的支持库。如果你看着这段已经像天书那么晦涩,直接跳到下一章吧。","以","以前的版本,直接看下一章去吧!","作为","作为对比,这里要指出,","你可能还会听说","你将要构建的这个应用,其完整源码位于","修改、转换或以本作品为基础进行创作,在任何用途下,甚至商业目的。您必须给出适当的署名,提供指向本许可协议的链接。","倍是很正常的。","写的代码相比,执行速度高出","出现并把","则不复存在了。整个处理管线由中间件驱动,mvc","创作共用署名4.0国际许可证","创建一个简单但实用的","别担心,就算对","前端代码(html、css、javascript)怎样与后端代码交互","前言","却已久经考验。在","又一个","又有什么可取之处呢?","又比","反序列化、数据库连接、pdf生成,或者几乎你能想到的任何需求。","发布。您可以自由地:共享","可能初出茅庐,但","吧。","和","在任何媒介以任何形式复制、发行本作品,演绎","增添了一些新工具,并复用(及简化)了你用过的那些东西。我将在后续章节指出部分差异。","多。","多,后者的","好了,前言就到这儿。开始学习","如何添加","如何进行数据库的读写操作","如何部署该应用程序到网络上","如果你从没用过","如果你刚开始编程,本书将在“构建最新web应用”方面,使你了解其中的模式和概念。你将以从无到有、循序渐进的方式,学习构建一个","如果你已经在使用诸如","如果你已经被这些命名搞糊涂了,别发愁!咱们马上就要写代码进行实践了。","如果你是一个","如果需要与你自己的代码做对比,可任意下载。","安全性","已经被翻译成其它语言:","应用、api、微服务","应用。","应用。你将学习如何通过前后端代码实现设计目标,如何与数据库交互,如何部署应用到真实环境。","应用的方法(以及合理组织各模块的方法)。对于你在编程方面所需的内容,本书不能事无巨细的涵盖,但它可以作为一个起点,引导你了解更高级的内容。","应用程序的部分。","开发者注意","开发者,将如鱼得水。","开始之前","彻底的重写,重点关注于:让该框架应用新的开发方法,并最终使其与","很快。因为","微软的开发团队很注重安全性,asp.net","感谢你选择这本","感谢那些多语言的投稿者,简明","或者","所覆盖的广度)。比如","手册","手册!我写这本小书的目的,是帮助","推向","数量,比","新功能提交","是一个平台无关的接口,它定义了特性和","是一个由微软创建的,用于构建","是另一个","是可在","是对","是最常见的选择,我在本书中也会采用它。你可以在","是编译运行的,执行速度远高于解释执行的语言,比如","本书的目标读者","标准","标准中的","标准并不等同于任何实际的代码或者功能,仅仅是","标准现存多个不同的“版本”或者说级别,反映出提供","框架。它使用常见的模式,诸如","框架选项已经很多了:node/express、spring、rubi","框架)的知识。我会偶尔提及","框架,需求何在?","模式的基本内容","现存的","生态","登录、注册功能,以及如何提升安全性","的","的传承,","的内容组织成了一篇教程。你将从头开始,完整地构建一个应用程序,同时了解以下内容:","的包管理系统,类似","的定义。.net","的实现,它只能运行在","的数量(或者说","的方式进行贡献。","的框架。","的解释器。有几种语言(c#,visual","程序。c#","等等,数不胜数。asp.net","简明","类成了起始和中心,application_start","编程开发者以及爱好者了解","编程方面经验如何,本书都会倾囊相授,足够你借助","编译器的静态类型检测的优势,它像个时刻警惕着,还有些强迫症的审校者。这样,在使用一个变量或者某些数据时,那些无意识的错误就插翅难逃了。","缺陷修复","著","虚拟机(jvm)或者","解耦。你要是还记得","许可证开放源码,就是说,源代码可以自由获取,并且欢迎社区成员以","译","详情请访问:https://creativecommons.org/licenses/by/4.0/deed.zh","贯穿本书,你将学习有关","运行在微软的","运行时库。","运行时库。它在各个操作系统上,使用对应的平台相关代码,实现了定义于","运行时库上,类似于","运行时,这个用于运行","这本","这本书本身也会由于修订和内容的增加而频繁更新。如果你阅读的是","进行编程,但跟你熟知的内容相去不远。","选择你的语言阅读","速度","那些内容,你就已经学会一半了:","项目成了","(web","(及以上列表的内容)一无所知,也不妨碍你学下去。"],"chapters/your-first-application/":["\"download","(the",".net","15.3","2017","although","app","applic","applications.","asp.net","atom,","atom、sublime、notepad","base","behind.","bing.com)","build","c#","c#,","c#、javascript、html","close","code","code\"","code”再按指令操作即可。(译者的话:别用","code。","code。这是个免费、跨平台的代码编辑器,对于","command","commun","complet","core","core?","cross","decid","don't","edit","editor","editor,","editor.","favorit","favorite,","few","fine).","first","first:","follow","free","free,","gather","give","great","html,","in.","includ","instal","instructions.","it'","javascript,","later","libraries,","line","linux.","mac,","more.","need","notepad,","onc","platform","prefer","readi","refactor","regardless","rich","runtime,","sdk","sdk,","sdk.","sdk,包括运行时,基础库以及用于构建","search","studio","sublime,","support","thing","tool","try.","us","using,","version","visual","web","whatev","window","windows,","windows、mac、linux上。","write","you'll","you'r","you'v","下,也可以用","不论你用什么编辑器或者平台,都需要安装","了。","代码补全","你可以用","你惯用的代码编辑器","你的第一个程序","准备好创建你的第一个","及以上的版本(免费的社区版就够用了)。visual","和","和很多其它语言编程的支持非常丰富。只需要搜索“下载","如果你在","应用了么?先做点“利其器”的事:","应用程序。这需要用到","应用程序的命令行工具。它可以安装在","或者任何你喜欢的编辑器。如果你还没有一个惯用的,请试试","有着优秀的","构建","百度,试试","的","的代码重构,且略优于","选定了编辑器,就该去获取"],"chapters/your-first-application/get-the-sdk.html":["\"download","(2.1.104)","(also","(more","(or",".net","1","10.13","2.1.104","48ec687460","above,","call","cli)","cli)确保一切正常工作:","command","commit","core","core\"","core”,在微软为你所在平台提供的下载页面,获取","details...)","dotnet","download","environment:","everyth","finish","flag:","follow","go!","hash:","info","inform","information:","installing,","instruct","line","mac","make","microsoft'","more","name:","open","os","output","page","platform","powershel","powershell),并使用","product","readi","runtim","sdk","sdk.","sdk。完成","search","see","sha","sure","termin","tool","tool,也叫","up","us","version","version:","window","windows)","working:","x","you'r","上的","命令行工具(command","如果你看到类似于上面的输出,就大步前进吧。","搜索“下载","的","的安装后,开启一个终端窗口(或者","获取","还可以通过","选项,获取你所在平台更详细的信息:"],"chapters/your-first-application/hello-world-in-csharp.html":["(a","(or","(similar","(with",".c",".csproj",".net","applic","application.","args)","asp.net","avail","base","basic","befor","built","c#","call","cd","class","class.","code","command","compiles:","compris","consol","console.writeline(\"hello","convent","core","core,","creat","csharphelloworld","csharphelloworld.csproj","default.","defin","directori","directory,","directory:","dive","document","dotnet","edit","editor,","entri","ex","extension)","extension).","file","files.","files:","first,","former","hand","hello","here","import","insid","it'","later,","line.","list","locat","main","main(string[]","make","metadata","method","module)","move","namespac","navig","netcoreapp2.0","new","next,","npm","npm).","o","often.","open","output","package.json","package.json),你不需要经常手动编辑这个文件。","packages,","paramet","place","point","powershel","powershell)。一路","program","program!","program,","program.","program.c","project","project.","project:","projects,","refer","run","same","scaffold","screen).","screen.","see","select","simpl","statement","static","store","structur","such","system","system;","take","tell","templat","termin","text","that'","thing","this:","those","top","tri","two","type","up","us","veri","void","want","window","windows).","won't","world","world!","world!\");","write","written","xml","xml,其中定义了一些关于项目的元数据。到后面,你引用其它包的时候,那些包将被记录在这里(类似于","you'll","{","}","上的","为项目的所有文件创建一个名为","之前,先试着创建并运行一个简单的应用程序吧。","使用","内置于","创建一个","到屏幕上。这个程序由两个文件构成:一个项目文件(使用","到要放置你项目的路径下,比如你的“我的文档”目录:","参数指示","命令创建一个新的项目:","命令创建了一个基本的","在项目的目录里,用","扩展名)和一个","扩展名),打开前面那个文件的话,可以看到以下内容:","指令运行这个程序,在代码编译完成之后,你将看到输出在控制台里面的内容:","指令默认会用","是","深入钻研","源文件(带有","版的","的","的目录。进入到这个新目录里:","的类(一种代码结构或模块)里。最上面的","的那些类,以便在你的这个类里使用它们。","程序上。","程序所需的全部!下一节,你将把同样的流程应用在一个","程序的入口点方法,按照惯例,会被置于一个叫","程序,它输出文本","语句引入了","这个可以在命令行下执行。首先开启一个终端窗口(或者","这就是构建一个","选择了一个命令行应用(一种向屏幕输出文本的程序)的模板。","项目。参数","项目文件基于"],"chapters/your-first-application/create-aspnetcore-project.html":["\"root\"","(and","(compil","(https://github.com/github/gitignore)","(i'll","(more","(mvc)","(not","(the","(不带","..",".csproj",".gitignor","5000","5000.",">","ad","add","addit","anoth","appli","applic","application!","appsettings.json","architecture.","asp.net","aspnetcoretodo","aspnetcoretodo.","asset","auth","authent","automatically.","b","back","benefit","bin","bit","box:","breakpoint","breakpoints):","browser","build","build.","bundl","c","call","cd","chapter.","chapter.)","choos","class","click","code","code)","code)。如果你用的是","code,","code.","code:","code(或者","command","common","compil","compon","configur","connect","consol","contain","content","content,","control","controllers目录里放置着","controller)架构的组件。下一章,你将一探他们三者的究竟。","core","coupl","cover","creat","css,","css、javascript、图片文件","ctrl","ctrl+c","cursor","databas","debug","default","depend","directli","directly.","directori","directories.","directory),","directory,","directory.","directory:","dive","document","don't","done,","dotnet","down.","entir","error","errors),","exiting,","explor","explore,","extra","f5","few","file","file,","files,","files.","first","fix","fixes,","folder","folder).","folder.","folder:","gener","git","github","github'","gitignor","good","great.","handl","hard","hello","help","here","home","http://localhost:5000","http://localhost:5000.","http://localhost:5000。你将看到","icon","ident","ignor","imag","import","incom","individu","init","initi","inject","inner","insid","instal","instead","it'","it:","javascript,","later","later).","later,","left","let'","level","lightbulb","line,","listen","load","look","make","manag","margin.","margin:","mean","menu","middlewar","minifi","miss","mkdir","mode.","model","models,","models、views,和","modifi","more","move","mvc","navig","need","new","new,","next","next,","note","now","number","o","obj","on","on:","onc","open","open,","options:","out","page,","pages.","part","pipeline.","plenti","port","press","print","problems:","program","program.c","project","project,","project.","project:","prompt","put","quickly:","quit","red","repo","repositori","request","requests,","root","run","same","sample,","save","secur","see","serv","server","server.","servic","set","shift","shortcut","show","shut","side","singl","solut","sometim","sourc","splash","squiggl","start","started.","started:","startup","startup.","startup.c","statement","static","still","stop","store","string","studio","studio,","studio),下面这几个有益的小技巧将帮你轻松上手:","studio,你需要直接打开","suggest","sure","task,","templat","template,","termin","that'","them.","there'","thing","three","time","time,","tip","too.","top","up","us","view","views,","visual","wait","want","web","widnow","window","within","wonder","work","working!","world","wwwroot","ye","you'll","you'r","you.","一个","一章讲解。)","上","上等待访问请求。","仓库:","以便停止这个服务器。","以调试模式运行项目。这跟命令行的","你可能有点疑惑,为什么在一个","创建一个","创建一个新项目,这一次添加几个选项:","到新目录里之后,就只需要运行这个项目了:","功能相同,但有一个额外好处——你可以在代码编辑器的左边栏上点击,以设置一个断点:","后面会提示你保存解决方案文件,你应该把它保存在根目录(第一个","启动时读取的配置信息。你可以用它来保存数据库连接字符串,或者其它你不想硬编码的任何内容。","和","在","在这个新的项目目录里,你会发现多出来几个文件。在你","处理和调整传入的请求、提供静态内容和错误页面。在这里,你还可以向依赖注入容器中添加你自己的服务(后面细说)。","如果你使用","如果你是初次使用","如果你还在","安全性与身份","小贴士:","开启你的网络浏览器,浏览","快捷编译:使用快捷键","我的文档","或者","打开文件夹。打开","打开项目的根文件夹","技巧","接下来,使用","接下来,创建一个新目录以保存你的整个项目,然后进到该目录里:","控制器(mvc,model","提示你安装缺失的文件,点击“是”以添加它们。","文件","文件夹(根目录),不是内层的项目目录。如果","文件夹)。你也可以在","文件用以忽略","文件里包含着","文件,设置","新建","服务器和","服务器,并在端口","来初始化你的","模型","模板为你生成了多个文件和目录。在默认创建的基本内容里,这几个是最重要的:","模板仓库(https://github.com/github/gitignore)里的","模板创建了一个新的项目,并添加了一些额外的验证和安全性相关的内容。(关于安全性的内容,我会在","模板就很好用。","潜在问题的小灯泡提示:如果你的代码里有红色波浪线(编译错误),把编辑的光标放在红线里,到左边栏里找那个小灯泡的图标,小灯泡的提示信息会给出常见问题的修改建议,比如在代码里添加一个","版的","用","的处理管线。在","的效果一样。","目录。这个顶层或者说“根”目录可以容纳一个或多个项目目录。根目录有时候被称为","目录里弄另一个","目录里放着","目录:","示例的那个目录里,请退回到","程序的默认欢迎页面,说明你的程序工作正常!看够了这个页面之后,在终端窗口内按下","管理你的源码,眼下就是一个适合的时机,在项目目录下用","类里,你可以添加中间件,它们用于","视图","解决方案目录。后面,你将会在","语句:","请确保你添加了一个","运行编译任务,这跟","运行(并调试断点):使你的项目处于打开状态,按下","还有很多值得研究的内容,让我们着手构建这个应用吧!","这个命令,使用","这个程序不再打印到控制台后直接退出,而是启动了一个","这些也可以用在","这些目录。","这些静态资源。wwwroot","里使用模板直接创建","里的文件将作为静态内容,自动被打包和压缩。","里,选择","项目","项目。","项目文件所在的目录。","项目的各部分","项目目录边上添加多个项目目录,它们全都在一个单一的根解决方案目录里。","项目,操作是",":"],"chapters/mvc-basics/":["\"backend\")","\"frontend\")","\"hello","(call","(model","(rubi","(sometim","(usual","ad","add","alreadi","android","angular","angular.","app","applic","application.","asp.net","attach","basic","book,","browser","browser,","build","built","button","c#,","call","chapter","chapter,","chapter.","check","click","client","code","common","complete.","components:","concept","control","controller)","controller,","controllers.","controller)是一个构建","core","core,","core.","core、c#和mvc模式","cover","creat","creating:","css,","cycl","data","databas","decis","default","display","dotnet","each","engin","enter","entiti","examples),","exercis","explor","express","feel","follow","form","form,","framework","frontend","good?","great","handl","handlebars,","handlebars、pug、razor","haven't","help","hold","home","html","html,","incom","inform","interact","interfac","io","is:","it!","it'","item","javascript","kept","languag","languages,","larger","let","let'","list","login","look","make","mani","mobil","model","models,","more","mvc","mvc,","mvc.","mvc(模型","mvc,那你在","name","new","onc","page","part","pattern","plu","popular","previou","privat","project","pug,","rail","razor)","receiv","render","repeat","request","right","run","run.","scope,","screen.","secur","see","send","server","simpl","small","sound","specifically,","sqlite","started.","step","store","submit","suggests,","system","teach","templat","that'","three","touch","up","us","user","user'","user.","variat","via","view","views,","web","web应用","web框架(rubi","welcom","well.","work","world\"","world”,就是创建一个待办事项清单应用程序。这是个很棒的练习,麻雀小,五脏俱全,它将涉及","you'd","you'll","you'r","you'v","“hello","一个","一个用于存储用户待办事项条目的数据库,使用","一个登录及安全检查表单,以便每个用户的待办事项列表都保持私密","上的移动应用也是","中的","之类的模板语言),它接收传入的数据并展示给用户。模型则保管着数据,要么是准备发送给视图的,要么是用户输入的。","创建一个新的","听起来心动吗?那就整起来吧!你要是还没按上一章所讲,用","和","在这一章,你将探究","基础","外加某种","如果你用其它开发语言写过","就是常见的范例)以及","应用程序服务器(有时也被称为“后端”),使用","打交道,这一章将教你基础知识,带你上道。","控制器使用查找到的信息创建模型,并使之与一个视图绑定","控制器接收请求,到数据库查找所需资料","控制器,model","数据库引擎和一个被称为","有三个组件:模型、视图、和控制器。控制器处理从客户端浏览器传入的请求,并选定相应的代码进行处理。视图就是模板(一般是","框架。io","正如其名字所示,mvc","用户点击一个按钮或者提交一个表单,从而发送一个新的请求给控制器,重复整个处理流程","的一个变种。","的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。","的模式,其应用几乎遍及所有的","的系统创建","程序里常见的模式是:","系统。","练习内容","练习里的","视图","视图在用户的浏览器里渲染并呈现","让用户通过她们的浏览器进行交互的网页和界面(也被称为“前端”),使用html、css、javascript创建","这样的前端","通读本书,你将构建一个待办清单应用,允许用户添加待办项,并在事项完成之后勾掉它。具体来说,你将创建的是:","里将如鱼得水。如果你是初次跟","项目。那你应该现在就创建并运行那个项目,直到看见默认的欢迎页面为止。"],"chapters/mvc-basics/create-controller.html":["(common","(index,","//","/foo","/foo,","200","404",":",">","about()","about,","action","action.","actions,","action名","action,把那句","add","alreadi","asp.net","aspnetcoretodo.control","back","becom","befor","behavior","best","browser.","call","case,","class","class.","code","code,","code:","comment:","contact()","contact)","contact),由","control","controllers/todocontroller.c","convent","conventions.","core","core,","creat","custom","data,","databas","database,","default","directory,","example,","few","flexibl","follow","foocontrol","found","found.","functionality,","get","give","go","handl","here","homecontrol","homecontroller,就是你访问","http","http://localhost:5000","http://localhost:5000.","iactionresult","ignor","includ","index","index()","it'","item","json","keep","left","lightweight","like,","list","localhost:5000/hom","localhost:5000/home/about","localhost:5000/home/contact","map","method","microsoft.aspnetcore.mvc;","model","name","namespac","need","new","now,","now.","number","ok","ok和404","out","pattern","patterns)","possible.","practic","project'","public","put","render","replac","repres","respons","rest","return","rout","screen","see","send","statu","stick","such","system.collections.generic;","system.linq;","system.threading.tasks;","system;","those","three","todocontrol","todocontroller,","type","understand,","url","url.","urls:","url:","us","user'","view","view.","views,","visit","we'll","welcom","write","you'd","{","}","一个","中","中有几个惯例(常见的模式),比如这个","之类的状态码。返回类型","从数据库获取","使控制器尽可能保持轻量化,是一个良好的习惯。在当前的情形里,这个控制器应该仅仅完成这些事情:从数据库取出待办事项的记录,把这些事项包装在一个可用于视图的模型中,并把这个视图发送到用户的浏览器。","使用","分别映射到如下的","创建控制器","包含三个","可以在","和","在","在这里添加","在项目的","把条目置于","方法可以返回视图、json数据,或者","方法(index,about,和","映射到","条目","模型","注释替换掉:","渲染视图","由控制器本身处理的路由叫","的","的模式,还有","目录里,已经预置了几个控制器,其中有渲染默认欢迎页的","看到的那个页面。暂时不用管这些控制器。","给了你足够的灵活性,以返回上面提到的任意一个。","给待办清单功能创建一个新的控制器,取名叫","继续编码这个控制器之前,你需要创建","视图。","里省略。如果你有需要,可以自定义这些行为,不过就目前的情况,让我们暂且遵循这些惯例。","里,添加一个名为",",在控制器类里用方法表示。比如,homecontrol",",并添加如下代码:"],"chapters/mvc-basics/create-models.html":["\"models\",","\"plain","(depend","(entity)","(integer)","(or","(or,","(sometim","(text","(the","(true/fals","43ec09f2","4f4b","65011d5781bb.","65011d5781bb。因为","7f70","9559","?","?,每个待办事项都必须带有一个截止日期。id","[required]","accident","accur","ad","along","alway","aren't","array","asp.net","aspnetcoretodo.model","attribut","auto","back","badli","bool","boolean","both","browser.","c#","c#里的字符串总是可空的,所以没必要给","call","can't","case,","checkbox","class","class:","click","code","code.","combin","commonli","complete,","configur","contain","core","creat","created:","databas","database,","database.","date","date,","date.","date/tim","datetimeoffset","datetimeoffset,","datetimeoffset?","datetimeoffset,c#","default","default,","defin","descript","differ","directory:","display","doesn't","don't","due","dueat","duplicated,","each","easi","empty,","empty.","entiti","entity),","entri","exactli","exotic.","extrem","fals","false。你后面会编写代码,在用户在视图里点击某个条目的复选框时,修改这个属性为","first,","follow","gener","get;","getter","global","guid","guid,","guids)","guid(或者guid)是一个由字母和数字组成的长长的字符串,看起来是这样的","guid,或者说是","hold","html","hundr","i'll","id","id,","identifier.","ids.","id、一个标题或者名称、该事项是否已经完成,以及截至日期是什么时候。每行定义了这个类的一个属性:","included,","increment","incrementing.","integer)作为数据库记录的标识,但你需要在数据库里配置,以便这个数字在添加新条目的时候始终增长。因为","is.","isdon","it'","item","item'","item.","item:","items.","later","latter","letter","level","line","list.","long","look","low","make","mark","matter","methods).","model","model).","model.","models,","models/todoitem.c","models/todoviewmodel.c","model)。","mongodb,","more","mv","mvc","mvc)","mv)发送到用户的浏览器。因为他们都可以被称为模型,我将称后者为","mysql,","name","name,","namespac","need","new","notic","now","null","null,","nullable,","nullable.","number","numbers,","object\"","object)”","offset","often,","old","optional.","poco.","poco。","point,","procrastinating).","properti","public","question","random","randomly,","read/writ","redis,","refer","render","repres","requir","right","row","same","say","sent","separ","server,","server,mysql,mongodb,redis,或者什么其它稀奇古怪的玩意儿。这个模型定义了数据库里的行或者记录在","set;","set;,","setter","shorthand","show","similar","simpl","singl","someth","sometim","sql","stamp","store","string","stuff","style","switch","system","system.componentmodel.dataannotations;","system;","take","technically,","technolog","tell","ten,","text.","there'","this,","time","time,","timezon","timezones.","titl","todoitem","todoitem[]","todoitems:","todoviewmodel","togeth","true","true/false)。默认情况下,所有新建条目的该值为","true。","two","two,","type","type?","underli","uniqu","unlik","us","user","user'","utc","utc.","valu","value).","view","view.","want","wasn't","way","whether","worri","write","you'd","you'll","{","}","了吗?它表示","偏移量表示的时区。把时期、时间和时区一起保存,有助于在不同时区的系统上准确地显示时间。","全局(globally)","创建模型","可空(nullable),或者说是可选的。如果不加这个","可读/可写(read/write)(或者,更确切地说,它有","向用户展示待办事项列表的视图了。","和","唯一(unique)","因此,视图模型应该是一个独立的类,里面包含着一个","好了,现在模型也有了,是时候创建一个接收","字符串可以没有值,也可以是空白字符串或者包含任意文本。","对象(plain","属性","属性是一个","属性是一个字符串,用于保存待办事项的名称或者简述。","属性没有标记为可空,所以是必须的,并可以确保始终有值(或者是一个缺省值)。","属性添加可空标记。c#","布尔值(值为","并以","我们需要创建两个独立的模型类:一个模型表示保存在数据库里的条目(有时候也称为一个","或者","方法各一个)。","日期/时间","是随机生产的,所以就你不必再担心这个","是随机的,并极少会有重复值,所以常被用作唯一标识。你也可以用数字(整形","标识符(identifier).","模型代表单一的一个数据库里的条目,而视图则需要展示两个、十个,甚至是一百个待办事项(取决于用户拖延症的病情轻重)。","每个属性后面都跟着","现在,暂且不必关心底层数据库采用的是哪种实现。它可以是","用于这种类型保存一个","的戳记和一个与","的数组:","的类:","的问题了。","目录下,创建一个名为","看到","类型后面那个问号","自增","视图模型","视图模型(view","记录(entity)),另一个模型将与视图结合(mvc里的","这个类定义了每个待办事项都要保存的内容:一个","通常,你保存在数据库里的模型(实体),跟你在","里用的模型(视图模型)非常相似,但又不尽相同。在现在的情形下,","里看起来是什么样的,所以你无须在代码层面担心数据库层面的东西。这种模型简单的风格被称为“朴实可爱的","首先,在",",这是个简写,表示该属性"],"chapters/mvc-basics/create-view.html":["\"manag","#888;","✔","(","(a","(at","(if","(var",".cshtml","15px;","=","@","@foreach","@item.dueat","@item.titl","@model","@viewdata[\"title\"]","@{","access","action","ad","add","alreadi","application.","asp.net","assum","base","basic","bootstrap","bottom","bound","built","c#","checkbox","code","code.","color:","combin","complet","complete.","components,","contain","control","convention,","core","correspond","course,","creat","css","custom","data","date.","decoration:","default","defin","direct","directori","directory,","directory.","display","div.todo","document","due","each","element)","erb","erb,在","exampl","expect","extension.","feel.","few","file","file,","file:","footer","foreach","handlebar","header","html","html,","html.","html。这些","html,偶尔掺杂一点","html:","https://docs.asp.net)","https://docs.asp.net)有几个示例可以参考。","id","idea.)","includ","index","insid","is:","it'","item","item'","items)","jade、pug","java","java,","javascript","jqueri","jquery,便于你快捷地创建一个","language,","layout","learn","librari","like.","line","list\";","look","loop","margin","mark","model","model.item","model.items)","model.items,","more,","more.","moustaches,","moustaches,在","much","name","name.","need","new","nice","now.","number","occasion","of.","offici","out","over","page","page?","panel","partial","place","prefix","property.","pull","quickli","rail","rails,","razor","render","rest","row","rubi","rule","rules.","sequenc","server","simpl","site.css","statement","store","structur","style","stylesheet","subdirectori","such","symbol.","tabl","tag,","take","tell","templat","text","through","through;","thymeleaf","to.","todo","todocontrol","todoviewmodel","top","top:","tr.done","turn","us","user","user.","veri","view","viewdata[\"title\"]","views/shared/_layout.cshtml.","views/shared/_layout.cshtml。","views/todo/index.cshtml","web","wonder","written","wwwroot/css","wwwroot/css/site.css","you'd","you'v","{","}","下用","中的","作为前缀。","你可以用类似的规则完全自定义页面的外观和体验。","你可能会纳闷,其余的","使用一个布局视图,用以定义容纳视图的基础结构的其余部分。布局视图被保存在","元素),改行包含条目的名字和截止日期。还会展示一个带有","写过页面,那你就已经了解其基本概念了.)","创建视图","和","在哪儿?asp.net","在文件顶端,@model","如果在","定制样式表","属性进行访问。","布局文件","库。","应用程序。当然,只要你愿意,你可以使用自己的","或者","扩展名。","指令告诉","文件的底部添加以下这些","标签,或者","样式规则:","模板在布局文件中包含了","模板语言编写,这种模板语言混合了","现在,请在","生成的视图,需要从视图模型(一个待办事项的数组)获取数据,并用一个适当的表格展示给用户。按规定,视图要置于","由","的代码。(如果你在","的名字加上一个","的复选框,可以在后续操作中把该条目标记为已完成。","的官方文档(位于","目录里,在一个与所属控制器同名的子目录下。视图文件的文件名就是","绝大多数视图代码就是","该视图要绑定到哪个模型。模型通过","语句以符号","语句将遍历到每个代办事项,并渲染成一个表格的行(","语句,用以从视图模型里抽取数据并转换为文本或者","还有更多功能,比如部分视图和后端渲染的视图组件,但你现在只需要一个简单的布局和视图。想要了解更多的内容,asp.net","里有一些待办事项条目,则","里的视图使用","页脚","页首","默认的"],"chapters/mvc-basics/add-service-class.html":["\"a","\"build","\"business\"","\"i\".","\"layers\"","\"learn","'todoitem'","(and","(are","(aspnetcoretodo.servic","(in","(layers)","(more","(no","(or",".net","1.","3","3级",":","=","actual","add","again,","alreadi","alway","applic","application,","application.","apps\",","architect","architecture.","architecture:","array","asp.net","aspnetcoretodo.model","aspnetcoretodo.models;","aspnetcoretodo.models中),它需要在文件顶部包含一条","aspnetcoretodo.servic","aspnetcoretodo.services.","aspnetcoretodo.services。命名空间是一种组织","assembl","asynchronous.","autom","avoid","away","awesom","base","becom","befor","better","big,","bloat","build","busi","c#","calcul","call","cases,","chang","chapter).","chapter,","check","class","class.","code","code.","combin","common","complet","concept","concern.","concerns:","confusing,","contain","control","controller,","controller.","convention,","core\",","cost","cover","creat","customari","data","data:","databas","database.","date","datetimeoffset.now.adddays(1)","datetimeoffset.now.adddays(2)","decis","decoupl","default","defined,","definit","depth","differ","direct","directli","directori","directory,","directory:","display","does.","due","dueat","each","easi","easier","enough","error","everything.","exampl","exists,","experi","fake","faketodoitemservic","feel","file","files,","first.","focus","follow","found","free","futur","game.","getincompleteitemsasync","getincompleteitemsasync()","getincompleteitemsasync();","go","handl","hard","have","help","here","here,","https://en.wikipedia.org/wiki/futures_and_promis","i'll","implement","import","includ","incom","incomplete.","instead,","interact","interfac","interface,","interfaces,","isn't","isol","it'","item","item1","item1,","item2","items:","itodoitemservic","juggl","keep","languag","larger","later","later.","later.)","layer","layer,","layer.","layers:","level","like:","list","logic","logic).","logic,","look","made","make","manag","mani","massiv","mean","method","method.","miss","model","model,","more","multi","n","name","namespac","namespace)","namespace),","namespace.","need","new","next","note","now","n级架构。在某些情况下,这些层级被隔离在完全分离的项目中,也有时候这仅仅意味着各个类之间组织和调用的方式。重点在于考量如何把你的程序分割成多个可管理的部分,以避免控制器或者某些臃肿的类试图去处理所有事情。","object'","on","on).","one)","organ","paramet","perform","pieces,","player","point","possibl","possible,","practic","prefix","present","price","product","project","project,","projects,","promise,","promise1,这里使用它的原因是,这将是个","properti","properties.","public","purpos","quickli","rates,","readi","real","refer","reference?)","relat","render","repositori","repres","requir","retriev","return","right","same","save","see","separ","separate.","servic","services/faketodoitemservice.c","services/itodoitemservice.c","set","signature)","signature))。该方法不需要任何参数,并且返回一个","similar","simpl","simplicity,","singl","single,","sometim","split","statement","statement,","step","store","syntax","system.collections.generic;","system.threading.tasks;","system;","talk","task","task.","task.fromresult(new[]","tasks,","task。","tax","test","test,","test.","that'","thing","think","think:","those","three,","tier","time","titl","todoitem","todoitems\".","todoitems.","top","total","tri","two","two,","type","up","us","used.","user'","user,","var","view","view,","way","whether","why?","without","words,","world","write","you'll","you'r","you'v","{","}","});","};","↩","习惯上,接口以大写字母“i”开头,在","代码文件的方式,一般与存放该文件的目录名保持一致(services目录下的文件,命名空间是aspnetcoretodo.services,以此类推)。","你可以在直接在控制器里编写这段数据库相关的代码,但是作为更良好的实践,应该保持你的代码独立。为什么呢?在一个巨大的,现实世界的程序里,你不得不应付一些事情:","你已经创建了一个模型、一个视图、一个控制器。在你把模型和视图应用于控制器中之前,需要先写点代码,用它把用户的待办事项条目从数据库里取出来。","使用数据库","创建一个接口","创建服务类","因为这个文件(在命名空间aspnetcoretodo.services中)引用了","因为这是一个接口,所以不包含任何实现相关的代码,只有","多数较大的项目使用一种","多级","如果这种语法让你看上去感到困惑,就这么理解:“一个","存入和取出数据库中的数据。","实现了","对当前这个项目而言,你将把程序分为两个层:一个由控制器和视图构成的","并处理接收的数据:你的控制器已经处理好了。","异步的(asynchronous)","待办事项","或者","执行业务逻辑,或者说跟你程序的目标和“业务”相关联的代码与逻辑。在一个待办事项列表程序里,业务逻辑意味着“为新任务设置一个默认的截止时间”,或者“仅显示未完成的任务”这些决策。业务逻辑的其它例子,包括“基于产品价格和税率计算总价”,或者“在游戏里检查一个玩家是否有足够的经验值升级”。","把程序以这种方式分割,有时被称为","接口(interface),在接口中,一个对象中方法和属性的定义与实际包含这些方法和属性的类分离开来。接口有助于解耦你的那些类,也有助于测试,如你接下来(以及在后续的","接口,但总是返回这个包含两个","方法。换句话说,这个方法可能不会即时返回待办事项的列表,因为它需要先查询数据库。(详情见后续章节。)","方法的定义(或者叫","方法签名(method","是一个仅关注数据库操作(不处理业务逻辑)的类。咱们眼下的程序里,为简化操作,我们将把这些混进一个服务层里,不过你尽可尝试采用不同的方式去架构你的代码。","服务层。表示层已经有了,所以,接下来就应该构建一个服务,用来处理","架构:一个表示层,一个逻辑服务层,一个数据仓储层。仓储(repository)","注意一下,这个文件的命名空间是","添加一个服务类","渲染视图","现在接口已经定义好,你可开始创建具体的服务类了。在后续的","的业务逻辑,并把待办事项条目保存到数据库里去。","的数组”。","的数组。你可以用它去测试控制器和视图,然后在","目录下新建一个文件:","章节中)所见。你将用一个接口来表示一个服务,该服务负责就待办事项条目事宜与数据库交互。","类型类似于一个","类(在命名空间","编程语言里有一个概念叫","自动化测试","表示层,用来处理用户的交互,和一个包含了业务逻辑和数据库代码的","译者注:二者都是其它语言中,与异步编程相关的概念,它们是用于指代某个尚未就绪的值的对象。而这个值,往往是某个计算过程的结果。要了解详细,请参考","语句,你会看到这样的报错:","语句,引入那个命名空间。如果不写这个","还是那句话,把所有这些东西写进一个单独的巨大的控制器是可行的,但这很快就会变得难以管理和测试。相反,常见的程序都把这些分割成两个、三个或更多的“层”或级,每个层级处理(且仅处理)一件事情。这有助于保持控制器尽量简单,并简化测试工作,以及后续的业务逻辑和数据库代码的修改。","那章添加真正的代码去访问数据库。","那章,我会深入讲解有关数据库的代码,但目前你可以造个假,直接返回硬编码的值:","里面装着一个"],"chapters/mvc-basics/use-dependency-injection.html":["\"callback","\"injected\"","\"wire","(...","(a","(call","(or","(separate)","(the","(via","(you'll","...",".net","//",":","=","_todoitemservic","_todoitemservice.getincompleteitemsasync();","_todoitemservice;","about.","action","actual","ad","add","addsingleton","along!","anywher","api","applic","application.","approach","ask","asp.net","aspnetcoretodo.services;","async","async:","asynchron","async:","autom","automat","avail","await","await。","await,以确保你的代码暂停,直到结果就绪才继续执行。","away,","away.","awesom","back","be","befor","blocked,","call","callback","care","case).","catch","chapter.","class","class,","class.","code","code)","code,","collect","come","comment","common","concret","configureservic","configureservices(iservicecollect","configureservices.","constructor","constructor,","contain","container,","continu","control","copi","core","core,你想把","core,在任何时候,只要","cover","creat","created,","databas","database,","deal","declar","declared)","decoupl","defin","depend","detail","differ","doesn't","don't","done","each","easi","easier","else!","else).","experiment,","explain","explicit","faketodoitemservic","faketodoitemservice,","faketodoitemservice。","faketodoitemservice。因为服务是从服务容器里“注入(injected)”的,这个模式被称为","faketodoitemservice,或者是其它读写数据库的类,或者别的什么类。只要它符合该接口的要求,控制器就能工作。这使你可以轻而易举地,独立测试程序的各部分。(我会在","final","finishes.","first","follow","future.","get","getincompleteitemsasync","given.","haven't","hell\"","help","here","hold","hood.","i'll","iactionresult","iactionresult,","iactionresult,并标记为","idea:","implement","index","index()","inject","injection)。","injection.","insid","instanc","instead","instead.","interfac","interface,","interface.","intern","isn't","it!","it'","it.","item","itodoitemservic","itodoitemservice,","itodoitemservice.","itodoitemservice:","javascript","job","keep","keyword","keyword!","know","languages,","later","later,","layer:","left","let","line","line).","littl","live","logic","long","look","luck.","made","magic","make","mark","match","mean","meantime,","method","method:","minute).","model","much","multipl","namespace,","necessarili","necessary.","need","needed.","network","network)","new","now","now,","object","obviou","older","on","on.","operation,","order","out","paramet","part","pass","pattern","paus","pick","privat","process","promis","provid","public","put","readi","readonli","real","realli","refer","rememb","render","request","requested.","responds.","result","return","reus","right","rout","same","scoped)","scoped)。我会在","see","seem","sens","separately.","servic","service,","services)","services.addmvc","services.addmvc();","services.addsingleton();","signatur","simpl","singleton","singleton.","someth","sometim","special","specif","startup","startup.c","statement","suppli","sure","system","take","talk","task","task?","task”的意思是说,该方法不能立刻给出一个结果,但是你可以使用关键字","task。“返回一个","task,代替之前的","tell","test","thank","that'","there!","thing","this:","to,","todocontrol","todocontroller(itodoitemservic","todocontroller,","todocontroller)类创建一个新的实例的时候被调用。在构造函数中加入的","todocontroller,你必须提供一个能匹配","todocontroller,当控制器需要一个itodoitemservic","todocontroller,添加一些代码以使用","todoitemservice)","todoitemservice;","told","top:","tri","under","underli","until","up","up\")","updat","us","var","variabl","view","void","wait","want","whenev","won't","work","worri","write","you'll","you'r","you'v","{","}","“回调地狱”,那你现在走运了。在","一章讲解测试相关的内容。)","一章里说明原因。","与之如出一辙:承诺你,肯定会给出一个结果——在未来的某个时候。","了:","从服务层获取","会在","作为幕后的实际服务。可能你觉得这是理所当然的,因为你的itodoitemservice仅有这一个实现,但你后面会为同一个接口提供多个实现,所以,有必要明确指定实现。","依赖于","依赖注入(depend","参数,表示你做出如下声明:要创建一个","可用服务集合","回到","回调函数,task","在命名空间","好了,当一个请求进来,将会被发送到","如果你在老式","异步(async)","当你编写代码访问数据库或者外部","待办事项","或者","或者其它语言里使用过","把下面这行添加到configureservices中的任意位置:","把代码暂停在","把你的服务作为","接口如此有用的原因就在于,因为它们有助于解耦(分离)你程序里的逻辑。既然这个控制器依赖于","接口的对象。","接口,但你还没告诉","接口,而不是任何","操作上,而后,在底层数据库或者网络请求结束时,从暂停的地方恢复执行。就是说,你的程序并没有卡住或者阻塞住,因为它可以处理其它的请求。如果现在想不通也别担心,跟着做下去就行!","方法的签名,以返回一个","方法负责的是把东西添加到","方法返回一个","方法里使用该服务(具体方法,稍后便知)。","方法里,在当前情况里,应该这么写:","方法里,(通过你声明的那个私有变量)使用","既然","时,asp.net","服务容器","服务的时候,task","构造函数(constructor)。构造函数是一个特殊的方法,它会在为(本例中是","模式是很常见的,因为在数据库(或者网络)响应之前,它不可能给出实际的结果。如果你在","添加进服务容器。这意味着,只有一个faketodoitemservice的实例被创建,并在每次被请求的时候都被复用。在后面,当你写另一个服务去跟数据库交互时,你会采用一个不同的方式(叫做","特定的","现在,你终于可以在","的引用。这个变量可以让你在后面的","的说法是服务的集合。","目前的重点就是修改","类的","类,它就不知道也不必关心实际使用的是哪个具体的类。它可以是","系统内部依赖的(你可以试试,把这行代码注释掉)。你在应用里所需的任何其它服务,也都要在这个地方添加到服务容器里。","胜利在望!你已经让","自动化测试","被一个构造函数(或其它什么地方)被请求,就用这个","要声明(或者“关联”)具体的类到每个接口上,需要写在","语句:","跟依附代码打交道要容易得多,这归功于神奇的关键字","运用依赖注入","运用数据库","还记得吗?","这一行告知","这一行给类定义了一个","这个类的第一行声明了一个私有变量,保存","这行添加了一些服务,它们是","里使用","里应付过","里查找并自动给出","里,你同样需要在文件顶部添加一个","里,或者"],"chapters/mvc-basics/finish-controller.html":["(for","(if","5000","=","_todoitemservice.getincompleteitemsasync();","add","already,","although","application,","aspnetcoretodo.models;","aspnetcoretodo.services;","async","automatically,","await","bind","browser","call","code","code),","code,","code.","code),或者在终端窗口里运行","code,当你鼠标指针指向一个红色波浪线时,编辑器会提示你添加这些","compil","control","controllers/todocontroller.c","creat","created,","cursor","data","databas","default.","didn't","directli","do","dotnet","earlier:","edit","editor","errors,","f5","fake","file.","file:","finish","go","haven't","http://localhost:5000/todo","http://localhost:5000/todo,","http://localhost:5000/todo.","http://localhost:5000/todo,但如果导航栏上有一个","index()","it'","item","last","layer,","layout","line.","list","make","model","navbar.","navig","need","new","nicer","now","now).","open","out","port","possibl","press","public","pull","put","red","return","run","run。如果代码通过编译而没有报错,服务器将在默认的","see","server","servic","share","squiggli","start","statement","step","studio","suggest","sure","task","terminal.","test","this,","those","todoviewmodel","todoviewmodel()","todoviewmodel,并把该","top","type","up","us","var","view","view(model);","visual","web","without","you'll","you'r","{","}","};","。你会看到自己创建的视图,展示着(暂时)从伪数据库层提取的数据。","与你先前创建的","启动程序(如果你用的是","如果你用的是","如果你的网络浏览器没自动弹出来,打开它,浏览","如果你还没在文件顶部添加","完成控制器","尽管可以径直浏览","待办事项","我的待办事项","或者","按","最后一步,让我们来完成控制器的编码。控制器现在已经从","服务层","条目就更好了。要达成这个目的,你可以去编辑共享的布局文件。","模型","测试一下","的列表,它应该把这些条目放进一个","端口上运行。","绑定:","获取到一个","视图","语句。","语句,现在加上:"],"chapters/mvc-basics/update-the-layout.html":["\"base\"","(you'll","/todo/index","4.x","4.x,","@html.actionlink()","@html.actionlink()。tag","action","action,","ad","add","asp","asp.net","attribut","attribute.","attributes.","automatically.","befor","call","case,","changes.","chapter).","code","contact","contain","control","core","creat","do","document","don't","each","element","exist","file","find","forms,","gener","hard","helper","helpers.","helper。在视图被渲染之前,asp.net","helper,可以参考位于","home","home:","href","html","https://docs.asp.net","https://docs.asp.net.","includ","instead","instead,","item","items:","later","layout","learn","link","mean","navbar","navbar,","new","notic","now","page.","point","razor","razor,应该会注意到一些语法的差异。生成一个指向","real","recommend","render","rendered,","replac","rout","see","syntax","tag","todo","todo:","todocontrol","todocontroller.","top","updat","url","us","view","view.","views.","views/shared/_layout.cshtml","way","you'll","you'v","中用过","为了向导航栏添加新条目,请先找到原有导航栏的","代码:","会把这些","位于","修改布局","元素中。这意味着你不必硬编码这个指向","元素中的属性","和","如果你在","对表单也很有用(你会在后续章节明白原委)。要学习其它的","属性。在本例中,会生成一个指向路由","并作为","控制器,而要改为指向","是现在的建议的方式,而不是使用","替换成真正的","添加你的条目,不要指向","添加到","的","的布局文件里面存放着所有视图的“基础”html。其中就包括导航栏,它被显示在每个页面的顶端。","的文档。","的路由。而是","自动为你生成。","被称为","链接的时候,tag"],"chapters/add-external-packages/":["\"humanize\"","\"metapackage\"","\"x","(a","(at","(call","(https://www.nuget.org/packages/humanizer)","(or","...",".net","//","8601","8601),","8601)对机器来说很方便,但是人类看着就不爽了。如果看到的是“还剩","@item.dueat.humanize()","@model","@use","ad","add","advantag","anoth","anything:","applic","asp.net","aspnetcoretodo.csproj","aspnetcoretodo.csproj,会看到新增了一行","avail","big","both","call","chapter,","clunki","code","code,","collect","column","command","conveni","convert","core","core)","creat","database.","date","dates,","day","directli","display","don't","dotnet","download","due","dueat","durations,","ecosystem","end","entiti","everyth","extern","fantast","faster","file","file,","file.","first,","format","fortunately,","framework","friendli","good","gui,","help","hood,","https://www.nuget.org).","https://www.nuget.org)。你可以在网页上检索","huge.","human","humanizer'","humanizer.","humanizer。","humans.","hundr","imagine.","import","includ","instal","interact","iso","it'","item","itself,","itself.","last","learn","license.","line","local","machin","manag","matur","method","method:","microsoft.aspnetcore.al","mit","more","much","mvc","need","new","next","nicer","noth","now","now\"?","nuget","number","numbers,","offici","on","on.","open","packag","package,","packagerefer","packagereference,引用了","pars","parti","peek","permiss","plugin","post","problem","project","project,","project.","properti","provid","publish","read","readable:","refer","render","repositori","rewrit","run","search","see","set","simpli","singl","solv","sourc","statement","string,","studio","studio).","system","systems,","task","termin","terminal:","that'","then,","there'","third","this:","through","times,","todoviewmodel","tool","top","twitter.","twitter发帖,包罗万象。asp.net","typic","under","updat","us","usual","view","view,","view:","views/todo/index.cshtml","visual","way,","way.","web,","wouldn't","write","x","xml","xml解析","you'll","you'r","yourself","“截止日期”一栏所展示的日期,这种格式(叫做","上一章结尾处,待办事项","上有着大量的软件包,从","上的软件包","下一章里,你将使用另一套","你完全可以自己写一段代码,把一个日期转换成更人性化的字符串,不过幸运的是,还有个更便捷的方法。","使用","几乎任何东西:日期、时间、时长、数字等等。它是个很好很有用的开源项目,根据","创建的项目文件包含一条指向microsoft.aspnetcore.all软件包的引用,这是个便捷的“元软件包(metapackage)”,它引用了你在项目中所需的所有其它","到","即是包管理工具,也是官方的软件包仓库(位于","在视图中使用","天”这样,不是更好吗?","如果你浏览项目文件","安装软件包","将用于在视图中改写日期,你可以直接在视图里使用它。首先在视图顶端添加一个","待办事项条目","或者说","改写","方法的代码,使用","方法:","既然","机器学习","添加外来软件包","然后,修改那行写着","现在,日期的可读性大大提高了:","的系统),编写代码与数据库进行交互。","看起来是这样的:","程序展示的","自身,在表象之下,也只不过是添加到你项目里的一个","要在代码里使用一个软件包,你通常需要在文件顶端添加一个","要把它加入到你的项目里,在终端窗口运行这个命令:","解决了这种问题,它提供的方法可以“人性化(humanize)”","许可证发布。","语句,以导入该软件包的内容。","语句:","软件包(一个叫","软件包。这样,你就不必在项目文件里添加数百个软件包的引用了。","软件包集合。","软件包,以获取协助,来完成几乎任何能想到的任务和难题。","软件包,并在自己的机器上使用终端(或者","这种成熟的生态系统,其最大的优势之一,就是第三方软件包和插件的量非常庞大。正如其它的软件包系统一样,你可以下载并安装","选择诸如","里的","里的图形界面)安装它们。"],"chapters/use-a-database/":["(document)","(orm)","(pocos).",".net",".net,","abstract","activerecord","actual","ad","agnostic,","applic","asp.net","back","bad","between","big","built","c#","class?","code","code.","connect","control","core","core.","core。ent","creat","databas","database.","decoupl","default:","depend","development,","differ","doing,","dure","easi","easier","entiti","framework","hibern","idea","includ","interact","interfac","it'","itself.","java","know","known","layer","let","make","map","mapper","mapper)","microsoft","model","mongo","mongo.","mysql","mysql,","nosql","nosql(文档)","number","object","on","orm","orms.","orm。","orm,其中有一个由微软开发,并默认包含在","out","over","past","postgresql,","project","provid","provider。","queri","raw","realli","relat","rememb","rubi","server,","server、postgresql","servic","set","sql","sqlite","stay","string","swap","technology.","thing","tricky.","two","types,","underli","unless","up.","us","well","work","write","you'll","you'r","上有多个","与数据库交互的代码写起来坑很多。除非你对其了如指掌,否则在程序代码里粘贴","中的","中,这就是","代码创建数据库查询语句,查询结果映射回","代码可以于具体的数据库实现无关,你可以根据底层以来的数据库技术更换不同的","关系","可以连接到","和","对象","就像一个数据库上的大型接口。你的","就是广为人知的","支持多个不同类型的数据库,并允许你使用","数据库协作。在本项目的开发过程中,你将使用一个","数据库,以简化安装和配置的工作。","映射(object","查询字符串就是个糟糕的决定。一个","模型(poco)。","运用数据库","还记得创建服务接口以解耦控制器和服务的实现类吗?entiti","这种","这种关系型数据库,也可以与","(orm)在你的代码和数据库之间添加一个抽象层,并以此简化了与数据库交互代码的编写。java"],"chapters/use-a-database/connect-to-a-database.html":["(appsettings.json).","(like","(naturally).","+","=>","add","address","alreadi","app.db","app.db。","applicationdbcontext","appsettings.json","asp.net","auth","basic","c#","class","class.","code","configur","configuration.getconnectionstring(\"defaultconnection\")));","configureservic","connect","contain","container,","context","context)是一个","context,","core","core包","creat","data/applicationdbcontext.c","databas","database.","datasource=app.db.","datasource=app.db。","default","defin","development.","directori","doesn't","dotnet","easi","elsewhere,","engin","entiti","entities,","entri","establish","exist","extra","few","file","file.","file:","framework","here'","host","however,","includ","individu","individual认证","instal","interact","it'","items.","lightweight","local","lot","machine,","method","migrat","mvc","name","need","new","new.","options.usesqlite(","order","packages.","point","project","project,","projects.","provid","provider,","quick","read","readi","requir","root","run","save","see,","servic","services.adddbcontext(opt","set","small","sqlite","sqlite)","startup","store","string","string,","string.","stuff","tabl","tell","templat","template:","thank","them:","thing","to.","todoitem","togeth","tool","up","updat","us","used.","what'","whether","without","you!","you'll","you'v","you,","与数据库建立连接。你需要在","为你完成了很多工作!","你的代码就是通过它与数据库交互,进行读写的。data/applicationdbcontext.c","使用","借助","如你所见,dotnet","实体,你需要修改数据库上下文,并对数据库进行变更。","待办事项条目。为了能存储","或","指令,在项目的根目录下生成了小型的","指定","指定所用的","数据库(必须地呀)","数据库。","数据库上下文","数据库上下文(databas","数据库上下文、连接字符串","数据库上下文、连接字符串和数据库类型。感谢项目模板:","数据库已经配置好待用了。但是还没有表用于保存","数据库文件","数据库的","数据库的名字","文件里为你设置好了:","文件里,就保存着一个很基本的数据库上下文。","方法中为","无论你连接本地文件数据库(sqlite)还是位于其它主机的数据库,都需要定义一个字符串,其中包含","是","是一个轻量级数据库引擎,可以运行在你的机器上而不必安装任何额外工具,所以在开发环境下使用起来既方便又快捷。","添加到服务容器里,并通过配置(appsettings.json)中的","用来连接的数据库地址。","类提供的数据库入口点。","类里的","经由","让项目使用了","这一项已经在","这些都默认包括在了所有","这段代码把","连接字符串","连接数据库","连接数据库,需要做一些准备工作。因为你通过","通过","项目中。","项目模板,这些准备已经就绪了:"],"chapters/use-a-database/update-context.html":["\"scaffold","(just","...","//",":","actual","add","alreadi","applicationdbcontext","applicationdbcontext(","applicationdbcontext,","automatically.","base(options)","base.onmodelcreating(builder);","below","builder)","call","chang","class","class,","code","collect","constructor:","context","context,","core","creat","data/applicationdbcontext.c","databas","database\"","database,","database.","database”相关的内容,并阅读微软的关于使用","dbcontext","dbcontextopt","dbset","document","doesn't","engin","entiti","exist","framework","get;","go","identitydbcontext","isn't","item","items,","items.","itself.)","lot","made","microsoft'","migration.","model","need","now","on","onmodelcreating(modelbuild","options)","order","out","overrid","problem:","proper","properti","protect","public","read","reflect","repres","revers","right","scaffold","search","set;","small","store","structur","sync,","tabl","tell","there'","todoitem","tool","updat","us","void","want","web","whole","yet:","you'r","you'v","{","}","为了把“数据库上下文中的改动”反映到数据库里,你需要创建一个","代表数据库里的","你修改了","修改数据库上下文","变更(migration)。","和模型类。","在构造函数的下方,为","如果你已经有一个现存的数据库,请在网络上搜索“scaffold","实体。","属性,可以让","属性:","工具的文档,以此对你的数据库进行逆向工程,自动地为数据库结构生成相应的","或者","数据库上下文","数据库上下文这边所需的工作不多:","添加一个","现在上下文和数据库不同步了,因为数据库里实际上并不存在","的","的类,却产生了一个小问题:","的表里保存","知道,你需要在一个名为","表","这个表。(对数据库上下文代码的修改,并不会改变数据库本身。)","集合。创建一个名为"],"chapters/use-a-database/create-migration.html":["\"dotnet","\"items\");","\"items\",","(...","(admittedli","(and","(or","(roll","(some","(where","(with",".net","//","00_createidentityschema.cs)","3.0","3,使用如下命令进行安装。","=","=>","actual","ad","add","additem","additems。","appli","back","back)","both","bring","call","caus","chang","changes,","chapter,","code)","code...)","column","columns:","command","comment","complet","constraints:","context","context,","context.","core","creat","createidentityschema","current","data/migr","data/migrations/_additems.c","databas","database,","database.","database:","dbset","directori","directory,","directory.","doesn't","dotnet","down","down(migrationbuild","down:","drop","dropped.","dueat","ef","ef\",","ef\",请确保在正确的目录下。","entir","entiti","eras","error","examin","execut","exist","false),","few","file","file,","files:","final","first","first.","fixed,","fledg","follow","found","framework","full","global","go.","hackish)","histori","id","includ","instal","is).","is.","isdon","issu","it!","it.","item","keep","layer.","limit","line","list","list.","made","make","match","method","method.","migrat","migration,","migration.","migration:","migrationbuilder)","migrationbuilder.addforeignkey","migrationbuilder.createtable(","migrationbuilder.dropforeignkey","migrationbuilder.droptable(","migrations,","modif","more)","mysql,","mysql,就不需要这样(有点旁门左道的)绕弯了。","name","name:","need","new","new.","newer","next,","now","on","open","opposite:","out","over","over,","overrid","possibl","prefix","previou","problem","program.c","project","protect","provid","ran","re","readi","remov","right","roll","root","run","same","scaffold","sdk,需要手动安装","second","see","server","servic","set","specify.","sql","sqlite","start","step","structur","sure","tabl","table)","table.column(nullable:","table.primarykey(\"pk_items\",","tables).","that'","time.","timestamp","titl","todoitem","todoitem)","tool","track","tri","true)","true),","two","undo","until","up","up(migrationbuild","updat","update,重新搭建数据库并应用到到当前的变更。","us","void","want","way","won't","workaround","workaround.","workaround:","x","x.id);","you'll","you'r","you'v","{","}","});","},","上一个","上一章节里,你在数据库上下文里添加了一个","会创建一个","你可以用","创建变更","创建变更的最后一步,就是要应用它(们)到数据库中:","变更","变更按时间记录着数据库结构的变化。它们使以下的操作成为可能:撤销(回滚)一部分修改,或创建一个新的数据库——与原有数据库结构一致。有了变更,你有一个完整的数据库历史,记录着对数据库的修改,例如添加或删除字段(以及整个表)。","命令查看一个变更的列表。","和","在","在数据库中创建","如果你使用完善的数据库,如","如果你想回滚数据库,你可以提供","如果你打开","如果你打开一个变更文件,可以看到两个方法,名字分别是","如果你按原样执行变更,会遭遇","如果你看到这样的报错:","将变更应用到数据库时","工具,原因请参考","带有你创建它时候的时间戳。","应用变更","或以上版本的","或者","搞定!","数据库和上下文都已就绪。接下来,你将在服务层使用上下文。","数据库的局限性带来的问题,要修复它,可以这样绕开:","方法。如果你需要完整的抹掉数据库并重新开始,运行","方法刚好相反:当你需要撤销(回滚)变更时,item","方法将会被执行。因为你在数据库上下文里添加了一个","方法里注释掉或删除","然后运行","的局限性","的时候创建并应用的。","目录,你将会看到:","相匹配)。","第一个变更文件(00_createidentityschema.cs),是在你执行","绕开","表。","表将会被丢弃。","表(其列与","译者注:如果你使用","迁移的名称:dotnet","这些命令必须在项目的根目录下执行(program.cs所在目录)。","这将运行所有迟于你指定变更的","这条命令会导致","这行代码通过检查你在数据库上下文里所做的修改,创建了一个新的变更,名为","那些行。","集合。既然现在数据库上下文里包括了一个集合(或者说表),而数据库里没有它,你就需要创建一个变更来修改数据库:",",应用变更时"],"chapters/use-a-database/create-service-class.html":["(and","(it","(languag","(or","(which","*",".toarrayasync();",".where(x","0,","0,或在",":","=","==","=>","_context","_context.item","_context;","abil","access","ad","add","addscop","alreadi","alway","applic","application,","applicationdbcontext","applicationdbcontext。applicationdbcontext","array.","aspnetcoretodo.data;","aspnetcoretodo.models;","aspnetcoretodo.servic","async","asynchron","avail","avoid","await","await(等待)","back","basic","be","blank","blissfulli","c#","call","caus","chang","chapter,","class","class,","classes,","closer","code","code.","complete:","configureservic","connect","contain","context","context)","context,","context;","core","core.","core(以及你的数据库)打交道,如果用单件(或其它)生命周期会引发麻烦,原因在于","creat","databas","database!","database)","database.","dbset","dbset:","delet","depend","directli","document","doesn't","dure","each","easi","entiti","equival","except","express","fake","faketodoitemservic","faketodoitemservice.c","faketodoitemservice.cs,并创建一个新文件:","faketodoitemservice,其中包含硬编码的","false)","featur","file,","file:","filter","finally,","first,","framework","function","get","getincompleteitemsasync","getincompleteitemsasync()","gone,","happen","hard","here","here.","hood","hood,","hood.","http://localhost:5000/todo.","http://localhost:5000/todo。硬编码的那些条目不见了,你的程序对数据库发起了真正的查询。数据库里刚好还没有任何已存的","inject","injected.","inspir","instanc","integr","interact","interface:","intermedi","isdon","it'","it'll","item","items,","items.","items;","items,直接返回查询结果(跟原来功能一样):","itodoitemservic","let'","lifecycl","lifecycle.","lifecycles)","line","linq","linq(languag","littl","look","make","manag","match","mean","method","method,","method.","microsoft.entityframeworkcore;","more","mvc","mvc基础","namespac","navig","need","new","next","nosql","nosql数据库","notic","now","now.","out","pattern","per","privat","problems,","program","properti","public","queri","query)","query),","readonli","real","remov","request","request.","requir","result","return","same","save","saw","scope","select","servic","services.addscoped();","services/todoitemservice.c","shorter,","singleton","start","statement","system.collections.generic;","system.linq;","system.threading.tasks;","system;","take","talk","task","task),","task),所以必须执行一次","tell","test","that'","that,","then,","thing):","time","toarrayasync","todocontrol","todoitemservic","todoitemservice(applicationdbcontext","translat","unawar","under","up","updat","us","value.","var","variabl","web","wire","x.isdon","you'll","{","}","下一章,你将在程序中添加更多的功能,从“创建新","与真实的数据库进行交互!","中所有的","从数据库中获取真实内容。","以获取其中的值。","会以","你创建了一个","你应该注意到相同的依赖注入模式,如你在","依赖于被注入的","修改服务容器","创建服务类","删除文件","取出所有过滤后的数据,并作为一个数组返回。toarrayasync","启动程序并导航至","回顾","如果想使这个方法变简短一点,你可以删除中间变量","将幸福地对这个变化毫无察觉,但在底层,你将使用","已经在configureservic","底层以请求为单位管数据库连接。要避免这些问题,请在跟","待办事项","待办事项:","待办事项。现在你有了数据库上下文,就可以创建一个新的服务类,从而借助","待办事项条目,所以页面目前还是空白的。","打交道的服务上,始终采用","把这个方法翻译成一个类似的语句","接口的那一行:","方法吩咐","方法来自","方法的代码。首先,它用数据库上下文中的","方法里被添加到服务容器里,所以在这里可以直接使用。","方法里配置itodoitemservic","是异步的(返回一个","最后,toarrayasync","添加一个服务类去跟","然后,where","生命周期。","用于过滤出所有“未完成”的条目:","由于你删除了","的","的属性获取","的特性,它受到函数式编程的启发,简化了在程序代码里数据库查询的写法。在底层,entiti","的生命周期把你的服务添加到容器里。这意味着每次","的能力”开始。","章节,","章节所见到的那样,只是这次被注入的服务是","类的新实例就会被创建出来。这对于那些跟数据库打交道的类来说,是必要的。","类,就需要修改","让我们仔细探究","试试看","请求中,一个","里的一个名为","里的一个等效查询。"],"chapters/add-more-features/":["add","application.","connect","core","core,","databas","entiti","featur","first,","form.","framework","item","make","more","new","now","possibl","readi","us","you'll","you'r","you'v","添加新特性","现在,你借助","连接到了数据库,就为“给程序添加更多新特性”做好准备了。首先是这个功能:使用一个表单,添加新的待办事项条目。"],"chapters/add-more-features/add-todo-items.html":["\"could","\"hello\"","(!modelstate.isvalid)","(!successful)","(and","(csrf)","(dto).","(like","(optional)","(the","(title)","(tri","/todo/additem","/todo/additem。眼下这不会有效果,因为还没有任何","/todo/index","/todo/index,后者会刷新页面。","/todo/index,后者会刷新页面并向用户显示新的待办事项列表。","1.","1;","1。","3","400","404","=","==","@await","@model","[required]","[validateantiforgerytoken]","_context.items.add(newitem);","_context.savechangesasync();","_todoitemservice.additemasync(newitem);","accept","action","action,","action.","action:","action,asp.net","action:","actual","ad","add","additem","additem(todoitem","additemasync","additemasync(todoitem","additempartial.cshtml","add,其浏览器会构建一个","again.","along","alreadi","alway","anoth","append","applic","application.","approach","asp","asp.net","assign","async","attacks,","attacks.","attribut","automat","await","bad","badrequest(\"could","badrequest(new","basic","be","befor","begin","below","bind","binder,","binding,","binding.","blank.","block","bound","browser","c#","c#,","call","can't","care","case,","challenge,","chapter","check","choos","click","code","common","complet","complex","consid","construct","contain","context.","control","core","core'","core,该视图需要配合","creat","create:","created,","cross","csrf)","customari","data","data.","databas","database,","database.","date","date)","datetimeoffset.now.adddays(3);","days.","default","definit","depend","display","doesn't","due","dueat","dure","editor","element","element,","element.","empti","ensur","error","error.","errors,","even","everyth","exist","expect","extra","fail","fals","false;","false。如果该操作因为某些原因失败了,act","featur","few","field","file","file.","finally,","first","first,","flag,","for=\"title\"","for=\"title\",让","forgeri","form","form,","form.","form:","form:","found","gener","get","getincompleteitemsasync();","grab","guid.newguid();","handl","happens!)","helper","helper.","here","hidden","html","html.partialasync","html.partialasync(\"additempartial\",","http","id","ignored.","implement","import","includ","incom","inform","initi","input","instead","intellig","interfac","invalid","isdon","isn't","it'","item","item.","item.\"","item.\");","item:","itodoitemservic","itodoitemservice:","javascript","javascript,","keep","know","larger","larger,","last","layer","layer.","line","line,","list","list:","live","look","main","make","malici","match","measur","message.","method","miss","model","model,","model.","modelst","modelstate(模型核验的结果)是否有效。习惯上,这种核验都在","model)","more","more.","mvc","need","new","new,","newitem","newitem)","newitem);","newitem.dueat","newitem.id","newitem.isdon","newitem.titl","newtodoitem)","newtodoitem),仅用于这个","next,","notic","now,","object","object)(dto)。这个模式常见于更大更复杂的项目。","on","onc","oper","organized,","out","page","page.","pair","parameter,","parameter?","partial","pass","path","pattern","perform","picker","piec","place","placehold","possibl","post","prevent","process","projects.","properti","properties.","property.","public","real","reason,","red","redirect","redirecttoaction(\"index\");","refer","refresh","render","rendered.","replac","request","request。","requir","result)","return","reus","right","rout","route,","route.","run","same","save","savechangesasync()","savechangesasync().","saveresult","secur","see","sens","separ","servic","set","simpl","site","site.","small","sometim","specif","squigg","start","step,","steps:","still","stop","store","submit","success","successful,","successfulli","tag","take","task","tell","that'","then,","they'll","thing","titl","todo","todo/index.cshtml","todoconteol","todocontroller:","todoitem","todoitem())","todoitemservic","todoitemservice:","todoitem,以一个空条目初始化该表单。(请尝试添加{","token","token.","top","transfer","tri","trick","true","under","understand","until","up","updat","url","url,就像你将其应用在一个","us","used,","user","user.","valid","valid.","validated.","validation.","validation)。核验操作检查从传入请求绑定到模型的数据,鉴别其合理性和有效性。你可以在模型中添加属性,告知","valu","values.","var","variable.","verif","verifi","verify)","via","view","view.","view:","views/todo/additempartial.cshtml","views/todo/index.cshtml","view)","way","whether","without","won't","words,","work","write","yet.","you'll","you'r","you'v","{","}","});","},看看会发生什么!)","上的其它属性(isdon","下面看到红色的波浪线,因为该方法尚未定义。","中添加一个名为","中,并仅具有特定的字段(title),用于添加新的待办事项条目。模型绑定流程依然要用到,但现在,你分离了两个模型,一个用于在数据库中存储待办事项条目,另一个用于绑定传入的请求数据。这个方案,也被称作","为保持各部分独立且组织良好,你应该以","主视图里引用它:","以怎样的方式进行核验。","会为该表单生成一个","会从表单里提取信息,并存放到那个","会处理","会将浏览器重定向到路由","会自动执行一个称为","会被你创建的","会返回","会返回一个","会连带一个包含","传给它一个","位于","作为复用","作为最后一步,你需要在服务层里添加一个方法。首先,在","作为附加练习,请尝试使用","你需要在","使用列表下面那个简易的表单,用户可以添加新的","元素上那样。在本例中,asp","元素是为","元素里,添加一个","元素,你能预见","再检视一次","出于某种原因无效,浏览器会被重定向到路由","列表里。因为这些条目存储在数据库里,就算你关闭程序后再重新运行,这些条目都还保存在那里。","创建一个","到了此","前它尚未被保存。如果保存操作成功,savechangesasync()","前面的","去查找(并验证)那个隐藏的验证标记,就是由","参数使用,","参数的方式了吗?这是你在","取决于该条目添加到数据库的结果成功与否,additemasync","变量里。","和","在","在控制器里添加一个新的","在服务层添加代码,对数据库进行修改","在模型绑定流程中,模型里的任何属性,如果不能匹配到请求里的字段,都会被忽略掉。由于表单里仅包含一个","在视图里添加一个","处理这个表单","如果","如果你使用的代码编辑器了解","字段","字段上的","字段服务的。","字段的对象,返回","对象。经由","局部视图就这样创建好了。然后,要在","局部视图(partial","属性告知","属性选择一个(可选的)日期。然后,用这个日期替换那个默认的“3天后到期”。","已经由","并为其它字段设置缺省值。然后,这个新条目被加入到数据库上下文中。在调用","当某个用户在你刚刚创建的表单里点击","待办事项","待办事项条目","或者","接下来,控制器调用到服务层,进行实际的数据库操作,保存这个新的待办事项条目:","接受一个","接口里添加它的定义:","攻击。在你编写这个","数据传输对象(data","方法会返回","日期)将为空,或者包含着一个默认值。","最开始的地方进行。","最终,如果操作顺利完成,action","条目","条目:","标签上,应用","标记,dueat","模型。当它在这里作为一个","模型一起使用。它促成了以下功能,在","模型核验操作(model","模型的替代方案,还可以创建一个独立的模型(比如叫","模型绑定","模型绑定流程会查看请求内的数据,并试图智能地把输入的字段和模型里的属性匹配起来。换句话说,当用户提交这个表单,并且浏览器","注意到","添加","添加一个日期选择框,并让用户为","添加一个表单","添加到表单里的那个标记。在处理","添加服务方法(函数)","添加这个功能,需要几个步骤:","然后,在","由于","的代码:首个代码块检查","的同时会在表单里添加一个隐藏字段,其中包含一个验证标记。该验证标记可用于防止","的处理流程。","的形式创建这个表单。局部视图是较大视图的一个小片段,存放于一个独立的文件。","的新","的时候,会验证这个标记。","的时候,这是个重要的安全措施,你的用户可能被欺骗,以至于在一个恶意的网站上提交数据。这里的验证标记被用于确保呈现和提交表单的,是你的程序。","的模型核验器,如果标题缺失或为空,则判定其无效。看一下","的模型绑定器设置,所以,这个方法仅需要分配","的真实地址取代:","的语法,你会在","相关信息的","知晓该","章节中创建的那个,用于存储一个","绑定模型(bind","表单","视图","视图。文件顶部的","视图:","试试看","请求到你应用程序的","请求数据绑定到模型后,asp.net","跨站请求伪造(cross","跨站请求伪造(csrf)","运行程序,使用页面上的表单添加几个条目到","还进行了","这一行的存在,此局部视图在被渲染的时候,期望被传入一个","这个","这个路由。如果你现在去尝试,asp.net","那行告知","里有个占位符,代表","里面添加实现:","错误。"],"chapters/add-more-features/complete-with-checkbox.html":["$('.done","$(document).ready(function()","$(row).addclass('done');","(!successful)","(a","(id","(item","(someth","(the","(without","(yet).",".singleordefaultasync();",".where(x","//","/todo/index","/todo/index,并刷新页面。","0","1","1;","=","==","=>","[validateantiforgerytoken]","_context.item","_context.savechangesasync();","_todoitemservice.markdoneasync(id);","accept","achiev","action","action!","action,","actions.","ad","add","additem","affect","again","anyth","anything,","applic","aren't","asp.net","async","attach","attribut","automat","await","back","badrequest(\"could","base","behavior","binding,","binding/validation,","bit","box","browser","button","call","can't","care","case,","chang","chapter,","check","checkbox","checkbox').on('click',","checkbox,","checkbox.","checkbox.closest('form');","checkbox.closest('tr');","checkbox.dis","checked,","checked.","class","click","clicked,","code","code.","code:","complet","completely,","concret","contain","control","copi","core","couldn't","creat","css","data","data.","database.","definition:","depend","directli","directori","disabl","disappear","doesn't","done","done,","done.\");","dure","each","element","element.","entiti","even","eventu","everyth","exist","experience.","fals","false;","false:","featur","few","field","file","filter","finally,","find","first","first,","foreach","form","form'","form.","form.submit();","found.","framework","frontend","function","function(e)","getincompleteitemsasync()","good,","great,","guessed,","guid","guid,","guid.","guid.empty)","guid.empty.","guid.empty。如果这种情况发生,act","guid。这项功能得益于你在表单里加入的那个名为","guid,则","handl","helper","hidden","id","id)","id);","id,","id.","id:","ideally,","identity,为项目添加安全及认证等特性。","id,以便你的控制器代码辨别是哪个复选框被选中了。(如果没有它,你只能知道","id:","implement","includ","incom","indic","individu","input","instead,","interfac","interface,","isdon","isn't","it'","it'd","it'll","it,","item","item'","item,","item.isdon","item:","itodoitemservic","javascript","javascript.","jqueri","jquery(一个","kept","last","layer","left","let'","library)","line","list","list.","local","login","look","loop","make","mani","mark","markcompleted()","markcompleted(checkbox)","markcompleted(e.target);","markdon","markdone(guid","markdoneasync","markdoneasync(guid","markdoneasync:","markdone:","matter","method","method.","miss","model","modelst","modelstate。取而代之,你可以直接检查","more","name","need","new","next","next,","now","now,","null","null)","null,","null——如果找不到。","null,设置","number","on","onc","one.)","operation.","out","page","page.","paramet","parent","pars","persist","possibl","post","print","probabl","project.","properti","property:","public","reason","redirect","redirecttoaction(\"index\");","refresh","refreshed.","render","request","return","right","row","row.","rule","run","run.","save","savechangesasync()","saveresult","secur","servic","services/itodoitemservice.c","services/todoitemservice.c","set","share","signature.","silli","simpl","simple.","single,","singleordefaultasync()","site.j","step","still","style.css","submit","succeeded:","success","sure","take","task","tell","that'","then,","there'","they'll","thing","things:","through","time","tini","todocontrol","todocontroller:","todoitemservic","todoitemservice:","too.","track","tri","true","true;","under","unlik","until","up","updat","updated)","updated,","us","user","user.","valid.","validity.","valu","var","veri","view","view,","views/todo/index.cshtml","way","went","where()","whether","wire","won't","work","wrap","wrong).","wwwroot/j","wwwroot/js/site.j","x.id","you'd","you'll","you'r","you'v","{","}","});","一旦你确定","不同,那个","不是","中添加具体的实现:","中的","为包含该复选框的行添加","了!","事件。当一个复选框被点击,markcompleted()","代码","代码。","会尝试将其解析为一个","使用复选框标记条目完成","修改该字段仅仅影响该条目的本地拷贝,savechangesasync()","修改过视图和控制器,剩下的就是要添加缺失的服务方法了。","元素包含。然后,添加一个隐藏元素,其中包含条目的","函数就被执行。","函数的功能如下:","列表里添加条目,这功能很棒,但无论如何,这些事项都得被处理掉。在","到","参数缺失了,或者无法解析为一个","向","向视图添加表单元素","和","在控制器里添加","在数据库中按","复选框被选中了,而无法知道是哪个。)","如果你现在立刻运行你的程序,复选框还是没什么作用,因为没有提交按钮通知浏览器,让它根据表单数据构建一个","就让浏览器重定向到","属性到该复选框,避免它再次被点击","属性就是小事一桩了:","并刷新页面。","当视图中的","待办事项","待办事项条目","循环运行并为每个待办事项条目显示一行,每一行都会包含此表单的一个副本。隐藏的输入框包含该","或者","找出页面上的所有复选框,将一些代码关联到其","接下来,控制器需要调用服务层去修改数据库。这个功能,将要由","接口中的一个新方法","提交该表单","方法。首先,该方法接受一个名为","方法中的","方法要么返回该条目(若存在),要么返回","既然你没使用","最终,如果一切顺利,浏览器会被重定向到","来实现,它会根据操作成功与否,返回","某个","查找一个条目。singleordefaultasync()","模型绑定/核验","模型绑定流程,就没有用于有效性检查的","正如你可能已经猜到的那样,你需要在","添加","添加服务方法","添加这一功能。在本例中,你还要写一丁点","点击这个复选框(还)不会导致任何结果。像上一章节一样,你要通过表单和","然后,在","现在,程序里包含一个单一、共享的待办事项列表。如果它为每个用户保存独立的列表,将会更有用。下一章,你将使用","用了一个模型作为参数,还进行了","的","的值将是","的值,以判断它的有效性。如果出于某些原因,请求中的","的参数,","的处理。如果传入的请求中包括一个名为","的隐藏元素。","目录找到文件","类","类型参数。参数","类,这个类会基于","被调用之后才会把修改的内容持久化到数据库里。savechangesasync()","规则,改变该行的外观","视图和前端代码就这样搞定了。是时候添加一个新","视图里,为每个待办事项条目显示了一个复选框:","让我们逐行分析这个","试试看","该方法使用","请求。你可以在每个复选框下面添加一个提交按钮,但这样的用户体验太蠢了。理想的方法是,点击复选框的时候,能够自动地提交该表单。你可以添加一些","辅助库),通过","达成这一点。","过滤器。","运行程序并勾选列表中的某些条目完成掉。刷新页面,它们将自动消失掉,这归功于","返回一个整数,表示在这次保存操作中被更新的条目的数量。在当前的情况下,它要么是1(条目更新了),要么是0(有错误发生)。","这段代码先使用","里添加一个","非常简单,这跟","首先,修改视图,并用让每个复选框都被一个","首先,在接口定义中添加",",并添加如下代码:"],"chapters/security-and-identity/":["\"do","\"doe","(and","(connect","(csrf)","(log","(protect","+","2.0","abil","account","accounts,","add","advantag","against","allow","alreadi","api","api.","applic","ask","asks,","asp.net","aspect","attack","attackers.","attacks)","authent","authenticated.","authentication,","author","box,","broad","built","can't","care","chapter","class","code","concern","confused.","connect","connect.","core","core.","credenti","cross","custom","data","deal","decis","default","design","distinct","domain","easier","ecosystem,","email","email/password","enabl","encryption)","everyth","facebook","facebook,","factor","few","first","flow","focu","form","give","googl","hand","handl","hash","help","http","https(tls),避免在","https,只需寥寥数行代码即可。本章主要关注安全性的","idea","ident","identity,","identity?","identity(一个验证和身份系统,属于","implement.","import","in)","in,","in.","includ","individu","individual验证","inject","input","instal","intercept","internet","involv","is?\"","it'","keep","know","like:","line","log","login","login,","mainli","major","make","manag","modern","multi","mvc","nuget","number","oauth","onc","openid","out","over","packag","part","password","password.","passwords,","permiss","prevent","project","protocol","provid","question,","recovery,","regist","reset,","role","safe","sanit","scaffold","secur","securely,","security:","servic","set","ship","sign","social","sql","sql注入","store","support","support.","system","take","templat","template).","that'","thing","think","top","topic,","travel","tri","two","us","user","users.","veri","view","way","web","well","whether","work!","x?\"","上传输的数据被窃取","中受益,而且已经正常工作了,请试着注册一个账号并用它登录。","之类的身份提供者的","二者常被混淆。验证","你搭建项目的时候,应用了","使用","关心“用户在登录","关心的是用户登录与否,而","包,可以被安装在任何项目中(并且包括在默认的模板中了)。","后","和","和密码进行登录的功能。","处理用户账号的存储、散列并保存密码、还负责管理用户的角色。它支持","多重身份认证流程","安全和身份","安全性是任何现代","密码重置","已经从","带来的身份系统,就像","应用或","或","或者","授权","方面:管理用户的账号(注册、登录),安全地验证用户(登录),并在验证后做出授权决策。","时,考虑到安全性的因素","是","是什么?","是在问:“我知道这个用户是谁吗?”,而","有助于实现这些功能。前两个(防止sql注入和跨域攻击)功能已经内置了,要开启","生态圈中的其它部分,它也是一组","登录、多重身份验证、集成以","登录时的安全性","的一部分)之上。安装后,默认添加了通过","确保用户","社交账号登录、以及借助","等协议连接到其它的服务。","能否做某些事”。你可以认为","视图","设计","身份验证(identity)","输入密码","过滤输入数据,避免","通过社交媒体授权","邮箱地址/密码","都要重点关注的。确保用户或顾客的数据安全并免遭黑客染指,是非常重要的。这个话题所涉甚广,包括了:","问的是:“这个用户有权限做某件事吗?”","防止利用表单(form)进行的跨域(csrf)攻击","项目模板中的","项目模板,该模板中带有几个类,构建在","验证"],"chapters/security-and-identity/require-authentication.html":["(despit","(whether","...","//","/todo","/todo。你会被自动重定向到登录页面:",":","[authorize]","abov","access","action","action,","actual","add","applic","application.","asp.net","attribut","attribute).","authent","author","authorization.","automatically.","be","befor","both","certain","check","class","control","controller.","controller:","controllers/todocontroller.c","core","do","entir","everyon","example,","file:","first","here,","home","in.","later,","line","list","log","login","make","microsoft.aspnetcore.authorization;","name","not),","page","part","particular","public","redirect","requir","run","sens","show","statement","todocontrol","todocontroller,","top","tri","us","user","want","without","you'll","you'r","you'v","{","}","在文件顶部添加这条","在用户访问你程序中某些特定内容时,你通常都会要求他们登录。比如说,把主页向所有人展示是合理的(不管你有没有登录),但只在登录之后才向你展示待办事项列表。","尽管属性的名字是授权(authorize),我们在这里检查的其实是认证(authorization),而非检查授权,很抱歉会有这样的混淆。","属性,要求用户在访问指定的","或整个控制器时,要事先登录过。要为","提示认证","添加认证提示,在这个控制器的第一行上面添加这个属性:","试着运行程序并在未登录的情况下访问","语句:","里的所有","里,你可以使用"],"chapters/security-and-identity/using-identity-in-the-application.html":["\"remember\"","&&","(!modelstate.isvalid)","(!successful)","(but","(currentus","(id","...",".additemasync(newitem,",".getincompleteitemsasync(currentuser);",".markdoneasync(id,",".singleordefaultasync();",".toarrayasync();",".where(x","//",":","=","==","=>","[authorize]","[validateantiforgerytoken]","_context.item","_todoitemservic","_todoitemservice;","_usermanag","_usermanager.getuserasync(user);","_usermanager;","accept","account.","accounts.","action","action:","add","additem","additem(todoitem","additemasync","additemasync(","additemasync(newtodoitem","additemasync(todoitem","additemuserid","again","again.","all)","anoth","appli","applic","applicationus","aren't","asp.net","async","attribut","avail","await","awar","badrequest(\"could","base","befor","between","both","call","can't","case.","challenge()","challenge();","chang","check","check,","class","claus","code","column","complet","construct","contain","context","context,","control","controller.","controllers/todocontroller.c","core","creat","current","currentus","currentuser);","databas","database.","database:","datetimeoffset.now.adddays(3);","definit","detail","differ","disappear","done!","done.\");","dotnet","each","ef","else'","empti","ensur","entiti","ether,","fals","false;","filter","finally,","first,","forc","full","get;","getincompleteitemsasync(","getincompleteitemsasync()","getincompleteitemsasync(),","getincompleteitemsasync(),就该修改","getuserasync()","good","guess","guid","guid.empty)","guid.newguid();","haven't","here","however,","id","id)","id,","idea","ident","identity.","ids:","id,以防止恶意的用户通过猜测","implement","in,","in.","index","index()","index.","inform","information.","inject","interfac","interface,","interface:","it'","it:","item","item.\");","itodoitemservic","itodoitemservice:","lightweight","list","log","look","made","mark","markdon","markdone(guid","markdoneasync","markdoneasync(","markdoneasync(guid","method","method,","method.","methods,","methods:","microsoft.aspnetcore.identity;","migrat","mirror","missing:","model","model.","models/todoitem.c","need","never","new","newitem)","newitem,","newitem.dueat","newitem.id","newitem.isdon","newitem.userid","next","now","null)","null,","null。无论如何,做个明智的检查都没错,以防万一嘛。如果用户信息没找到,你可以用","object","onc","own","paramet","parameter.","part","particular","pass","present","privat","properti","public","queri","readonli","redirecttoaction(\"index\");","regist","return","rogu","run","saniti","see","servic","services/itodoitemservice.c","services/todoitemservic","services/todoitemservice.c","set","set;","share","show","signatur","someon","statement","statement:","stay","step","still","store","string","success","table,","task","terminal:","that,","themselv","ti","todocontrol","todocontroller(itodoitemservic","todocontroller:","todoitem","todoitem:","todoitemservic","todoitemservice,","todoitemservice.","todoitemservice:","todoitemservice;","todoviewmodel()","top","top:","tri","two","unfortunately,","up","updat","updated,","us","user","user'","user)","user);","user,","user.","user.id)","user.id;","userid","usermanag","usermanager)","usermanager;","usermanager:","users,","valu","var","via","view(model);","view,","x.id","x.isdon","x.userid","yet.","you'll","you'r","{","}","};","下一步是修改数据库查询,并添加一层过滤,仅显示当前用户创建的条目。但在做这些之前,你需要在数据库里添加一个新的字段。","下面是","中","中有效:","中注入一个","从","以获取当前用户,如同在","你需要在","使用它,通过","修改","修改了数据库和数据库上下文,你就可以修改","修改数据库","修改服务类","再通过","包含在","参数了,修改","参数传给了","和","因为控制器使用了","在程序中使用身份","如果你现在运行程序并注册或者登录,你将又一次见到一个空的","如果当前用户已经登录,","完成事项","实体上添加一个新的属性,让每个条目都能够“记住”拥有它的用户:","实体模型上所做的修改:","属性中获取当前登录的用户——该属性在当前的","属性就持有一个轻量级的对象,包括了用户的一些(并非全部)信息。usermanag","属性确保了见到","属性,currentus","属性:","并未关联到特定的用户。现在,[authorize]","待办事项列表。糟糕的是,你尝试添加的任何条目也都会凭空消失,因为你还没修改","待办事项列表依然由所有用户共享,因为","待办事项条目","待办事项视图","指令创建一个新的变更:","指令应用到数据库:","接口了:","接口,也就同样需要修改","控制器里对这两个方法的修改:","搞定!请用两个不同的账号尝试一下。待办事项条目现在是每个账户的私密信息了。","操作","方法和其中的","方法在数据库里查找该用户的详细信息。","方法强制用户再次登录:","方法的签名:","方法的顶部添加了新代码,这行代码用","方法里的","方法里,构造一个","既然你修改了数据库上下文里的实体模型,就应该同步修改数据库。在终端窗口里用","既然你现在把一个","最后,修改","查询子句也需要检查用户的","查询子句了:","添加条目","的人一定登录过,在查询数据库的时候,你就可以按照登录者的身份进行过滤了。","的值绝不应该是","的变更,它将给","的操作,并把用户信息存储到条目里:","的方法把其他用户的事项标记为完成状态。","的方法里,使用","的时候,设置","而既然你修改了","表新添一个列,以反映你在","语句:","还要在文件顶部加一个新的","这两个","这两个服务方法现在也必须接受","这个","这个命令新建了一个名为","里。你可以用它在","里定义的接口:","里查找当前用户:","里的","里那样。","里面的实现方法。在","首先,在"],"chapters/security-and-identity/authorization-with-roles.html":["!=","\"admin@todo.local\"","\"admin@todo.local\")","\"admin@todo.local\",","\"administrator\")]","\"administrator\",","\"administrator\";","\"administrator\",创建一个名为","\"error","\"manag","\"notsecure123!!\");","&&","(alreadyexists)","(await","(except","(isadmin)","(signinmanager.issignedin(user))","(testadmin","(the","(var",".getrequiredservice>();",".getusersinroleasync(\"administrator\"))",".roleexistsasync(constants.administratorrole);",".singleordefaultasync();",".toarray();",".toarrayasync();",".where(x","/manageus",":","=","==","=>","@await","@foreach","@if","@inject","@model","@use","@user.email","@user.id","@viewdata[\"title\"]","@{","[authorize(rol","[authorize]","_","_layout.cshtml","_usermanag","_usermanager.us","_usermanager;","abil","access","account","account'","account,","account.","action","action:","ad","add","admin","admin@todo.loc","administr","administrator.","administratorrol","admins,","adminstrator,","alreadi","alreadyexist","anyon","applic","application.","applicationus","applicationuser[]","approach","aren't","aren't,","args)","asp.net","aspnetcoretodo","aspnetcoretodo.control","aspnetcoretodo.model","aspnetcoretodo.models;","assign","async","attribut","author","automatically.","await","await。这是个罕见的例外","await!","bar","befor","below","buildwebhost(args);","button","call","can't","catch","challenge,","chang","check","checks.","class","class.","clean","code","collect","common","const","constant","constants.administratorrole);","constants.c","control","controller:","controllers/manageuserscontroller.c","convent","core","creat","currentus","currentuser,","data","databas","database,","database.","db.\");","delet","deni","detail","determin","directli","display","doesn't","easi","edit","else!","email","ensur","ensurerolesasync(","ensurerolesasync()","ensurerolesasync(rolemanager);","ensuretestadminasync(","ensuretestadminasync()","ensuretestadminasync(usermanager);","error","error.","even","everyon","everywher","ex)","example,","exception.","exist","extra","fact,","featur","file:","finally,","finish","first","first,","folder","get","get;","give","goe","handl","hold","host","host)","host.run();","host.services.createscope())","html.partialasync(\"_adminactionspartial\")","html.partialasync(\"_loginpartial\")","http://localhost:5000/manageus","http://localhost:5000/manageusers.","id","ident","identity.","identityrole(constants.administratorrole));","in.","includ","index","index()","initi","initializeasync(","initializeasync()","initializedatabase():","initializedatabase(host);","initializedatabase(iwebhost","inject","instead","isadmin","iserviceprovid","iserviceprovider(在startup.configureservices()方法中设置过的服务集合)从","isinroleasync()","isinroleasync().","isn't","it'","it,","item","keep","layout,","layout:","link","list","log","logged.","logger","logger.logerror(ex,","logic","look","main","main()","main():","main(string[]","make","manag","manageuserscontrol","manageuserscontroller(","manageusersviewmodel","method","method)","method,","method.","method:","microsoft.aspnetcore.authorization;","microsoft.aspnetcore.ident","microsoft.aspnetcore.identity;","microsoft.aspnetcore.mvc;","microsoft.entityframeworkcore;","microsoft.extensions.dependencyinjection;","model","model.administrators)","model.everyone)","model:","models/manageusersviewmodel.c","modifi","more","name","namespac","navbar","navbar.","navig","need","new","next,","nice","normal","not,","now","null","null)","obviou","occur","on","one.","order","organized,","page","page.","page:","partial","password","password.","perform","permiss","plu","possibl","power","privat","program","program.c","project","project,","properti","public","quickli","rare","readonli","reason","reasons,","regist","repeatedli","required.","rest","return","return;","right:","role","role.","rolemanag","rolemanager)","rolemanager.createasync(","root","rout","run","scope","scope.serviceprovider;","section:","secur","secure!","see","see.","seed","seeddata","seeddata.c","seeddata.initializeasync()","seeddata.initializeasync(services).wait();","seeddata:","seeddata:","servic","services)","set","set;","set;}","share","signinmanag","skipped.","small","someth","start","startup.configureservices()","statement","static","string","succe","sure","system.collections.generic;","system.linq;","system.threading.tasks;","system;","task","task,","task,就必须使用","technic","tell","temporari","test","testadmin","testadmin,","that'","themselves.","then,","they'll","this,","time","time,","top","tri","two","type","underscore,","up","up.","updat","us","user","user,","user.","usermanag","usermanager)","usermanager.addtoroleasync(","usermanager.createasync(","usermanager.getuserasync(user);","usermanager.isinroleasync(","usermanager.us","usermanager;","usernam","users\"","users\";","users.","valu","value:","var","view","view(model);","view),以便在布局中的导航条里添加一个项目:","view?","viewdata[\"title\"]","views/manageus","views/manageusers/index.cshtml","views/shared/_adminactionspartial.cshtml","views/shared/_layout.cshtml","void","wait()","want,","web","well.","whether","write","wrong,","x.usernam","yet!","you'd","you'll","{","}","};","——","下划线开始,但这不是强制性的。","个已登录用户,usermanag","中获取rolemanager和usermanager。","作为练习,请在这个页面添加更多管理功能特性。例如,添加一个按钮,为管理员提供","你可以在该应用程序第一次启动的时候,将这个","你可以把","使用这个常量值。","做这件事,但是因为某些技术原因,你无法在","出于显而易见的安全因素,对于任何人来说,都不能自主的注册成为一个管理员账号。事实上,administr","创建一个名为views/manageusers的文件夹和一个视图:","创建一个测试用的管理员账号","删除一个用户","判断用户是否已经登录。如果没有登录,其余的代码就都被跳过。如果这","启动程序,并以普通用户身份登录,尝试去访问一下","和","因为initializeasync()返回一个","在","在initializeasync()方法下面再添加两个方法,第一个,ensurerolesasync()方法:","在此项目中,你将添加一个","在网络应用里,角色是用于处理","在视图里查看认证状态","在项目的根目录创建一个新类,取名为","填充(seeding)","如果你愿意,也可以修改之前创建的","如果你用管理员账号登录,将在右上角见到一个新的导航项:","如果数据库里不存在一个用户名为","字段,可以确保用户必须已经登录","就被用于查找用户详细信息,并用","属性让控制器里执行认证操作变得很方便,但是如果你需要在视图里进行认证操作呢?比如,在导航条上为登入的管理员用户显示一个“管理用户”的链接。","属性里加入","并且","并在导航条部分添加:","并把这个","当你再次启动程序,admin@todo.loc","所有其它地方你都应该用","拒绝访问","按惯例,通常把局部视图的名字以","按角色进行授权","授权","接下来是","接下来,你需要提醒你的程序,在它启动的时候,执行这个逻辑。修改program.cs,并更新main()去调用一个新的方法initializedatabase():","接下来,创建一个视图模型:","数据库。","方法中使用","方法以确保它在应用程序启动前完成。你一般是用","方法使用一个","方法:","是","最后,为","此方法查看数据库里是否存在一个","此方法获取seeddata.initializeasync()所需的服务集合,然后执行它以便初始化数据库。如果出现错误,将会记录一条错误日志。","添加用户管理页面","然后,在main()的下面添加这个新方法:","用户管理","的功能。","的小类以保存它的值:","的常见方法。例如,通常会为管理员创建一个","的用户,这个方法将创建它并给它一个临时的密码。在你初次登录之后,就应该改为一个更安全的密码。","的页面,你将看到一个列表,列出了本程序的所有注册用户。","直接注入到视图里来进行这些操作。为保持你视图整洁有序,创建一个新的局部视图(partial","被分配了","要在主布局中包含这个局部视图,编辑","角色。如果没有,它就创建一个。为免反复地输入字符串","角色。请尝试用这个账号登录,并浏览位于","角色外加一个测试用的管理员账号添加到数据库中。向数据库添加初始数据的行为,被称为初始化,或者","角色才能查看这个页面。","角色,相对于普通用户,他们拥有更多的权限和能力。","许可","语句添加到文件顶部:","路径。你会见到这样的","这个局部视图首先使用","这个角色。","这个角色,在数据库中尚不存在。","这个账号会被创建并被赋予","这是因为注册用户不会自动获得","进行认证检查。如果所有检查都通过了,并且该用户是一个管理员,导航条上就会加入一个","链接。","页面,仅对管理员们可见。如果普通用户试图访问它,将会看到错误提示。","页面:","首先,创建一个新控制器:"],"chapters/security-and-identity/more-resources.html":["(multi","account","activ","add","advanc","altern","amount","anoth","application.","approach","asp.net","authentication,","avail","azur","b2c","best","both","built","case.","cloud","code","common","complex","control","core","data","databas","database.","directori","do","do,","document","dotnet","easi","experi","expert!","factor","fantast","featur","features.","federation),","fit.","free","functionality.","give","great","handl","help","host","http://docs.asp.net","i'd","ident","identity:","identity:你免费获得随模板而来的大量代码,易于上手。对于进阶的情形,你依然需要写一部分代码,并维护一个数据库以存储用户信息。","information.","isn't","learn","login","login.","lot","maintain","make","more","much","need","new","okta","option","part","password","plus,","pre","pretti","progression:","project,","projects,","quickly.","recommend","recommended,","recovery,","reduc","registr","research","reset","resourc","run","scenario","scenarios,","secur","security:","sensit","servic","services.","significantli","simpl","social","started.","still","store","such","templat","templates,","there'","think","understand","unless","up","us","user","view","way","write","you'll","yourself","以及","在本项目里,asp.net","基于云的身份鉴别服务:这种服务既处理简单情况也处理复杂情况(多步验证、账号找回,),并且能极大地缩减你需要编写的代码量,和维护程序的工作量。另外,用户数据的敏感部分并不会保存在你的数据库里。","帮助你添加诸如","并非添加身份鉴别的唯一方式。另外一种选择是使用诸如","指定的模板带给你预先构建好的视图和控制器,用以处理这些常见情景,以便你快速上手和运行。","登录、注册","的文档非常适合用来学习这些特性。","的替代品","自己处理安全性:不推荐,除非你是一个安全性方面的专家!","还有很多其它功能,例如密码重置以及社交账户登录。位于","这些安全及身份鉴别的特性到程序里。dotnet","这种云端的服务为你的程序处理身份验证。你可以把这些选项看作发展的各个环节:","附加资源","非常适合。对于更复杂的项目,我建议对各选项都作一些研究和尝试,以便找到你所需的最佳方案。"],"chapters/automated-testing/":["(sometim","application.","asp.net","autom","avoid","both","break","bugs,","bug,并使你后续重构代码的工作轻松些,以免破坏现有功能或引入新的问题。","build","call","chapter","chunk","code","core","easier","exercis","find","function","help","import","integr","introduc","larger","later","layer","learn","logic","make","method","multipl","new","part","problems.","properly.","real","refactor","scenario","simul","singl","small","sure","test","tests)","unit","without","work","world","write","you'll","以检验你的","功能性","单元测试","和","在本章里,你将学习如何编写","测试)较大,模拟实际的应用场景,并检验你程序里的多个层次或组件。","测试的编写在构建任何程序时都很重要。测试代码有助于发现及避免","程序。单元测试较小,用来确保单个方法或者逻辑块工作良好。集成测试(有时候也叫","自动化测试","集成测试"],"chapters/automated-testing/unit-testing.html":["\"db\"","\"db\")","\"fake","\"fake@example.com\"","\"mocked\"","\"test_addnewitem\").options;","\"testing?\"","(arrang","(asserts)","(connect","(etc...)","(even","(give","(in","(isdon","(make","(mark","(not","(the","(thi","(var","...","../aspnetcoretodo/aspnetcoretodo.csproj",".items.countasync();",".net",".useinmemorydatabase(databasename:","//","0.","000\",","1.","1.9074","1;","3","=","==",">","[fact]","_context.items.add(newitem);","_context.savechangesasync();","aaa","aaa(布置","accident","act","action","actual","add","additemasync(","additemasync()","additemasync():","addnewitemasincompletewithduedate()","alreadi","alway","and,","applic","applicationdbcontext","applicationdbcontext(options))","applicationdbcontext,","applicationdbcontext.","applicationdbcontext。(你可以画一条线表示","applicationdbcontext,后者通常连接到你的开发或生产环境里的数据库。你不该把这些数据库用于测试。相反,你可以在测试代码里使用","applicationdbcontext,这种方式被称为","applicationus","asp.net","aspnetcoretodo","aspnetcoretodo).","aspnetcoretodo.csproj","aspnetcoretodo.data;","aspnetcoretodo.models;","aspnetcoretodo.services;","aspnetcoretodo.unittest","aspnetcoretodo.unittests.csproj","aspnetcoretodo.unittests/","aspnetcoretodo.unittests/todoitemserviceshould.c","aspnetcoretodo/","aspnetcoretodo)。然后使用以下命令搭建出一个新的测试项目:","assert","assert)","assert.equal(\"testing?\",","assert.equal(1,","assert.equal(false,","assert.true(differ","assert)模式:对象和数据首先被建立出来,然后执行一些动作,最后测试程序检查(断言)预期表现的存在。","assum","assumpt","async","attribut","autom","automat","await","away","back","becom","befor","behavior","below","best","block:","both","busi","call","case),","cd","challenge,","chang","changed!","changes).","check","check:","class","class.","classes,","close","code","code,","code.","code,你可能需要关闭并重新打开","come","command","compar","complet","complex","compon","configur","connect","cons.","contain","context","context.items.firstasync();","controllers/","copi","core","core'","correctly,","coverag","creat","created.","current","data","databas","database.","database.)","database:","date","datetim","datetimeoffset.now.adddays(3)","datetimeoffset.now.adddays(3);","day","dbcontextoptionsbuild","dbcontextoptionsbuilder()","decis","defin","delet","depend","dependencies.","dependencies:","differ","difference!","different.","directori","directory):","directory,","directory.","discovered:","discovering:","doesn't","don't","dotnet","doubl","draw","due","dueat","each","else,","ensure:","entir","entiti","equal","even","everyth","example,","execut","execution,","exist","expect","extra","fail","failed:","fakeus","fakeuser);","fals","false)","false;","false)","feel","file","final","finds.","finished:","first","first,","firstasync","focus","follow","forgot","framework","free","getincompleteitemsasync()","graph","graph).","guid.newguid();","hand,","handl","harder","hasn't","id","idea","id,","imagin","implement","import","important!","includ","incomplet","inject","inside)","instal","instead,","integr","intern","introduc","is,","isol","it!","it'","it,","item","item)","item.dueat;","item.isdone);","item.title);","itemsindatabas","itemsindatabase);","itodoitemservic","keep","kept","know","large,","larger","last","less","level.","line","littl","live","logic","logic.","look","main","make","mani","mark","markdoneasync()","mean","memori","memory)","memory,","method","method'","method.","microsoft.entityframeworkcore;","millisecond","mock","more","much","name","name,","namespac","need","need.","never","new","newitem,","newitem.dueat","newitem.id","newitem.isdon","newitem.titl","newitem.userid","next","normal","normally,","noth","now","nuget","number","o","object","occurred.","on","option","organ","out","output","own","packag","package,","part","particular","pass","passed:","pattern:","perform","performed,","pleas","popular","postfix","practic","prevent","pro","project","project'","project,","project.","project:","proper","properti","provid","provider,","provider。因为整个数据库都存在于内存里,每次测试重新开始的时候,他就会被清空。并且,因为这是个合乎规格的","provider,todoitemservic","provider,然后对","public","ran","read","readabl","readi","realiz","refactor","refer","reli","reopen","requir","restarted.","retriev","return","root","run","saniti","save","saveresult","scaffold","scan","second","second)","see","seem","sentenc","separ","servic","service,","service.additemasync(new","set","short","similar","singl","skipped:","small,","someon","start","starting:","still","structur","studio","style!","successful.","sure","system","system.threading.tasks;","system;","take","task","tell","templat","terminal,","test","test,","test.","testing.","testing?","testing?,","tests,","tests.","tests:","that'","thing","this:","those","time","time.","time:","titl","to:","todocontrol","todoitem","todoitemservic","todoitemservice(context);","todoitemservice,","todoitemservice.","todoitemservice:","todoitemserviceshould","total","track","tri","tricky,","true","true,","turn,","two","typic","unit","unittest1.c","unittest1.cs。你已经为第一个测试的编写准备就绪了。","unlik","up","us","user","user'","user)","user.id;","userid","usermanager.","usermanager。todoitemservic","usernam","valid","valu","value.","values.","var","verifi","version","visual","wait...","want","way","window","wipe","without","won't","words,","work","write","xunit","xunit.net","xunit;","you'll","you'r","yourself.","{","}","},","};","。dotnet","一层。(这个目录也叫做","不会察觉有什么异样。","不论是单元测试还是集成测试,都遵循","中的逻辑,在你的测试项目中创建一个新类:","为测试创建独立的项目是一个良好的实践,以便把它们和你的程序代码分离开。新的测试项目应该被置于你主项目的同级目录(而非在主项目目录内)。","为验证业务逻辑执行的正确性,请在原有的","代码块下编写新内容:","代码的测试框架,可用于编写单元和集成测试。像其它组件一样,它也是一组nuget","你现在有了测试程序,覆盖了","你的目录结构看起来应该是这样:","例如,todocontrol","依赖图)。","写一个服务测试","写到数据库里去。)","出来的其它类,以便在一个时时刻专注在一个点上。","创建一个测试项目","删除自动创建的文件","前缀,使方法名构成一个可读性良好的句子,不过你可以按自己的意愿选择命名风格。","包里带来的,它把这个方法标记为一个测试方法。","包,可被安装在任意项目中","单元测试","单元测试是短小的测试,检查单个方法或类的行为。当你测试的代码依赖其它方法或类时,单元测试依赖于","发起一个调用:","另一方面,当你写单元测试的时候,你需要自己处理这个依赖图。典刑的做法是,提供这些依赖的","只返回某个特定用户的条目","命令在当前的项目里查找测试方法(本例中,由","和","在终端窗口,运行以下命令(请确保你位于","如果传入一个不存在的","如果你当前在你项目目录里,向上","如果你用的是","属性应该被设置为用户的","属性是","属性标记出来),然后运行它找到的所有测试,你会看到类似这样的输出:","已经包括了你所需的一切。","当一个有效的条目被标记为完成状态,","当程序运转正常的时候,","或者","执行","接下来又依赖于","断言——arrang","断言一个日期时间值有点棘手,因为比较两个日期值的时候,就算是只有毫秒部分不同,两个值也是不等的。替代方案是,检查","新条目应该总是从现在开始3天后过期","新条目应该总是未完成状态(isdon","新条目的标题应该复制自","方法取出存储的条目,然后断言其中的属性被设置了预期的值。","方法,并遗漏了某些以上的业务逻辑。你程序的行为,会在你意识不到的情况下变掉!你有办法避免这个情况,方法是编写一个测试,用以复核这些业务逻辑并未发生变化(就算是该方法的内部实现已经发生了变化)。","方法:","既然测试项目要使用你主项目中的类,你需要添加一个引用指向主项目:","是一个常用的针对","最后一行创建了一个新的名为","有两个依赖:","有很多不同的方法可以命名和组织测试,它们都有着各自的优缺点。我喜欢给测试类加上","来配置内存数据库的","测试专用","版本。这意味着你可以把正在测试的类或者方法的逻辑隔离出来。(这很重要!如果你在测试一个服务,显然不应该一失手","用一个","的","的值距离期望值小于一秒。","的内存数据库","的待办事项,并通知服务将其存储到(内存)数据库里。","的服务容器和依赖注入系统在","的测试范围。作为一个补充练习,请写出单元测试以确保:","目录):","看一下","窗口,以便代码完成功能在新项目里生效。","第一个验证步骤是个明智的检查:内存数据库里保存的条目绝不会超过一条。假设这个检查通过了,测试会使用","虚构","虚构(mocking)","被创建时,把这些对象逐一地注入到依赖图里。","要编写一个单元测试来检验","设想一下,如果你或者其他什么人重构了这个","该方法在把新条目真正存入数据库之前,做了多个判断与假设(换句话说,在新条目上执行了业务逻辑):","运行测试","返回","这种情形——你意识不到自己改变了业务逻辑,虽然现在看起来好像不会发生,但是在一个更大更复杂的项目中,这会因为各种决策和假设而变得难以追踪。在越大的项目中,确保业务逻辑稳定的自动化检查就越重要。","里面的","需要一个","顺带"],"chapters/automated-testing/integration-testing.html":["\"..\\\\..\\\\..\\\\..\\\\aspnetcoretodo\"));","\"/login?returnurl=%2ftodo\",","\"/todo\");","\"http://localhost:8888/account\"","(etc...)","(https://docs.asp.net)","(includ","(javascript)","(not","(really)","+","../aspnetcoretodo/aspnetcoretodo.csproj",".configureappconfiguration((context,",".usestartup()","//","/todo","/todo,并验证浏览器被重定向到了登录页面。","0.","1.","2.0588",":","=","=>","[authorize]","[authorize],","[fact]","_client","_client.sendasync(request);","_client;","_server","_server.createclient();","_server.dispose();","_server;","access","accident","act:","add","alternative:","anonym","answer","applic","application:","applications.","arrang","asp.net","aspnetcoretodo","aspnetcoretodo.csproj","aspnetcoretodo.integrationtest","aspnetcoretodo.integrationtests.csproj","aspnetcoretodo.integrationtests/","aspnetcoretodo.integrationtests/testfixture.c","aspnetcoretodo.integrationtests/todorouteshould.c","aspnetcoretodo.unittests.csproj","aspnetcoretodo.unittests/","aspnetcoretodo/","assert.equal(","assert:","async","attribut","automat","await","base","befor","better","book","broad","browser","builder","call","candid","care","cd","challengeanonymoususer()","chapter","class","class.","clean","client","client.baseaddress","client.dispose();","clutter","code,","command","common","compar","complete.","compon","config)","config.addjsonfile(\"appsettings.json\");","config.setbasepath(path.combine(","configur","control","controller,","controllers,","controllers/","core","creat","current","databas","defin","delet","deserv","directori","directory,","directory.","directory.getcurrentdirectory(),","discovered:","discovering:","dispose()","document","doesn't","dotnet","durat","each","easi","ensur","entir","everyone.","everything'","execut","execution,","exercis","fact","failed:","few","file","find","finished:","fixture)","fixture.client;","frontend","get;","good","great","hand","help","host","however,","http","http://localhost:5000.","httpclient","httpmethod.get,","httprequestmessage(","httpstatuscode.redirect,","iclassfixtur","idispos","in)","instead","integr","involv","isol","it'","keep","knowledg","larg","larger","learn","learn.","level","log","login","look","lot","main","make","manual","mark","message:","method,","microsoft.aspnetcore.hosting;","microsoft.aspnetcore.testhost","microsoft.aspnetcore.testhost;","microsoft.aspnetcore.testhost:","microsoft.extensions.configuration;","more","much","multipl","namespac","need","new","new.","now","nuget","o","on","on.","order","overflow","own.","packag","package:","page","page.","passed:","perform","pleas","practic","prefer,","privat","probabl","project","project,","project.","project:","projects,","properly:","provid","public","readi","readonli","redirect","refer","remov","request","resourc","respons","response.headers.location.tostring());","response.statuscode);","right,","root","rout","routing),","routing,","run","same","scaffold","scenario","scope.","second","see","sent","separ","separately.","server","services,","set","setup","should,","skill","skipped:","slower","small","split","stack","stack.","stackoverflow","start","starting:","stop","structur","stuck.","success","successful.","system,","system.collections.generic;","system.io;","system.net.http;","system.net;","system.threading.tasks;","system;","take","task","termin","test","test,","test.","testfixtur","testfixture()","testfixture:","tests,","tests.","tests:","testserv","testserver(builder);","testserver,","testserver,并使测试代码干净利索。","test,如果一切工作顺利,你会看到这样的成功信息:","that'","themselv","there'","thing","this:","tidy.","time:","todorouteshould","todorouteshould(testfixtur","todorouteshould:","togeth","topic,","total","touch","typic","ui","unit","unittest1.c","unittest1.cs,这样你就为集成测试的编写准备就绪了。","up","uri(\"http://localhost:8888\");","us","user","var","verifi","view","void","wait...","web","webhostbuilder()","whole","won't","work","would.","wrap","write","xunit","xunit;","you'll","you'r","{","}","});","与单元测试相比,集成测试在范围上大得多。它检验整个程序栈。集成测试并不会把一个类或组件隔离出来,而是确保你程序的所有组件协作良好,这些组件包括:路由、控制器、服务、数据库访问等等。","与单元测试相比,集成测试较慢,并且涵盖的范围较大,所以,一般来说,一个项目会有大量的单元测试内容,而集成测试的内容则屈指可数。","为了测试整个程序栈(包括控制器路由),集成测试往往像网络浏览器那样向程序发起","你现在的目录结构看起来应该是这样:","像以往一样,asp.net","创建一个测试项目","删除","到上一层的","包","在每次集成测试执行之前,需要进行一些配置。为免配置相关的代码把测试代码弄的乱七八糟,你可以把配置相关的内容提取到一个独立的类里。创建一个名为","在终端窗口运行","如果你愿意,可以把单元测试和集成测试放置在同一个项目里。对大型项目而言,通常会把它们分开,以便于它们各自独立运行。","如果你此刻位于项目目录,cd","属性,从而导致待办事项视图对所有人可见。","提供了一个上佳的替代品:testserv","文档(https://docs.asp.net)和","既然这个测试项目要用到主项目中的类,你需要添加一个引用指向主项目:","本章总结","测试是个宽泛的话题,还有很多东西需要学习。本章节没有涉及","测试,也没有对前端(javascript)代码进行测试——它本身可能就需要一整本书去讲述。不过,你应该已经掌握了一些基本的技能和知识,可用于实践并学习更多相关测试程序的编写。","现在你(真的)可以开始编写集成测试了。创建一个名为","的类:","目录,使用以下命令搭建一个新项目:","等等。这是个良好的测试点,因为它确保你不会意外地弄丢了","类。这个类能够在测试期间托管你的程序,并在测试完成之后自动关闭它。","编写集成测试","要执行一个集成测试,你也可以启动程序,并手动向http://localhost:5000发起请求。不过,asp.net","请求。","还需要添加","这个测试发起一个匿名(未登录)的请求到路径","这个类配置好了一个","这是个很适合集成测试的使用场景,因为它涵盖了程序的多个组件:路由系统、控制器、控制器被标记了","都是用于了解更多知识以及遇到问题时查找答案的好资源。","集成测试","默认创建的文件"],"chapters/deploy-the-application/":["(and","(if","(more","(thi","(with","(连同","amazon","apach","app","applic","application,","application.","applications.","asp.net","automatically.","azur","azure,","azure.","azure,这些就都是自动为你处理的。在","balanc","behind","below.)","brows","call","capabl","care","chapter,","cheaper)","cli","come","common","contain","containers),","core","cover","creat","deploy","deployed,","differ","digitalocean","docker","docker.","doesn't","don't","done","dotnet","easier","easiest)","ec2","environment,","environments:","especi","familiar","fast,","featur","feel","files.","fine.","free","front","go","great","gut","have.","host","host.","however,","http://localhost:5000","http://localhost:5000.","i'll","ii","imag","includ","incom","instructions,","internet","it'","it'll","kestrel","kestrel,","kestrel.","kestrel。但强烈建议你在","later.)","lightweight","linux","linux,","linux(和","live.","load","long","mac,","machin","machines).","manag","matur","microsoft","more","nativ","need","next","nginx","nginx)","nginx).","not,","number","on","onc","option","pair","prefer","product","project","proxi","proxy.","put","quick","quit","ran","receiv","recommend","request","revers","rout","route,","run","same","scenes.","section.","sections.","server","set","share","show","skip","step","still","subscription,","support","thing.","time","two","typic","up","upload","us","usual","veri","virtual","want","way","way,","web","winddow","window","windows,","windows.","windows、mac","windows,ii","work","world!","worry!","yet.","you'r","you'v","yourself,","一部","万事俱备,只欠东风。当一个良好的程序构建完成,就应该与全世界分享它了。","上使用","上,你拥有多种部署程序的方式。这一章里,我将教给你最常用(也是最简单)的上线方式。","主机","之前添加一个反向代理,因为","也能处理这个工作。","以及","任何有能力托管","你可以在","反向代理","反向代理配对工作。(下面有更详细的","和","因为","在","如果你不在意","如果你不想用","如果你把程序托管在","完成这种操作。","容器的机器都能用来托管","容器)里,你可以用","对","并上传你的项目文件即可。下一节,我会介绍通过","并不具有负载均衡和其它更成熟的","并浏览","开发服务器。你每次运行","微软的","或者","托管的程序。如果你用的是","更容易(也更便宜),不过你要是愿意自己管理","服务器所具有的其它特性。","服务器接收从互联网上传入的请求,并派发到你用","服务器(这包括亚马逊的","服务器,这也是个可行的方案。","的快速轻量级的","的情况下。(如果你还不熟悉,别担心!我会在后面逐步介绍。)","的时候,用的就是这个服务器。当你把程序部署到生产环境的时候,它仍会在幕后使用","相关内容。)","程序。一般来说,部署到","程序。创建","程序托管工作的细节,而只希望参考分步的指导,可以跳转到后续两小节的任一个继续阅读。","程序提供原生的支持。如果你有一个","程序能够运行在","网络服务器托管","虚拟机)上托管程序。通常把","订阅,你只要创建一个","跟","进行反向代理。","通常会部署到下列环境之一:","那一节,我会讲述如何配置","那个方式,依然可以在任意","部署方式","部署程序","里包含一个名为","镜像是个非常快捷的部署程序的方式,尤其是在你熟悉"],"chapters/deploy-the-application/deploy-to-azure.html":["\".deployment\",","\".deployment\",以此避免被添加一个","\"first","($10/month)","(follow","(mytodoapp","(on","(the","(use",".",".deploy",".deployment,而不带有什么其它的零碎儿。(在",".txt","=","[config]","above)","account","add","added.)","alreadi","app","app!","app,","app.","applic","application,","application:","appservic","around","asp.net","aspnetcoretodo","aspnetcoretodo.integrationtest","aspnetcoretodo.unittest","aspnetcoretodo/aspnetcoretodo.csproj","aspnetcoretodogroup","aspnetcoretodoplan","away","az","azur","azure,","azure.","be","brows","call","check","cli","cli)","cli.","clipboard,","cli(按照","closer","command","commit","commit!\"","complete,","config","configur","copi","core","cover","creat","created,","created:","custom","d1","d1($10/月)或更高级的方案。","default","deploy","deployment:","dir","directori","directory,","domain","extens","f1","far","few","file","filename,","find","fine)","first","fix","follow","format:","free","g","git","git(使用","global","group","group):","higher.","http://mytodoapp.azurewebsites.net","http://yourappname.azurewebsites.net","https://github.com/azure/azur","https://nate@mytodoapp.scm.azurewebsites.net/mytodoapp.git","i'll","init","instal","installed)","instruct","isn't","it'","items:","know","l","latter.","level","line","list","local","locat","log","login","ls","m","machine.","make","master","messag","multipl","mytodoapp","mytodoapp)在","n","name","name.","nate","need","new","next,","now","now,","on","onc","once.","out","p","part","password","password.","plan","plan.","plan:","portal,","prevent","project","projects),","prompt","publish.","push","put","quot","region.","remot","remote:","repo,","repository:","resourc","root","run","save","see","servic","set","sku","sourc","spit","step","steps.","stream","structur","structure:","subscript","sure","take","test","then,","this,","through","time,","top","track","tsv","two","uniqu","up","up:","url","url:","url:","url:http://mytodoapp.azurewebsites.net","us","us)地区创建了一个资源组。如果你距离美国西部很远,请使用","us,","user","usernam","veri","version","want","web","webapp","west","western","westu","whenev","window","windows,","won't","you'll","you'r","you.","一个","上必须是全局唯一的。一旦这个应用创建好了,会具有一个以下格式的默认","上,你可能需要把文件名用引号括起来,比如","仓库管理,执行下列命令进行设置:","以检验结果。","你只需要执行这些步骤一次。现在开始,任何时候,你需要推送程序文件到","你可以用","准备材料","创建部署配置文件","到剪切板,并把它在本地仓库里添加为一个","只需要简单几步。你可以通过","命令确认它已经安装了)","命令获取一个地点列表,并找出距离你比较近的一个。","命令行工具里实施。我会讲解后者。","命令,应该看到如下的内容:","因为你的目录结构里存在多个项目(web项目和两个测试项目),azur","复制这个","如果你在顶层目录里执行","如果你的","并不知道该把哪个发布出去。为解决这个问题,在你的目录结构顶层创建一个名为","并按照提示在你的电脑上登录,然后,为这个程序创建一个新的","应用:","得到一个","或者","才初次安装完成,运行:","扩展名。)","把你的","把程序文件推送到","把项目文件部署到","按提示创建密码。然后用","接下来,为部署工作创建一个","接下来,在你刚刚创建的组里,创建一个","提示:f1","方案。如果想在你的应用上使用自己指定的域名,请使用","方案里创建一个","方案:","是免费的","现在,在这个","用户名和密码,","的指示进行安装)","的文件:","的时候,你会看到一系列的日志信息。","的网上门户实施,也可以在","确保你把这个文件保存为","程序部署到","网络应用。如果你本地目录尚未作为一个","订阅(免费的订阅就可以了)","设置","资源","资源组(resourc","输出结束之后,浏览","这个命令在美国西部(west","这个应用的名称(上面的","部署到","里提交它们,然后运行:","项目的根目录里要有一个部署配置文件",",只需要在"],"chapters/deploy-the-application/deploy-with-docker.html":["\"80\"","\"80:80\"","\"amazon","\"aspnetcoretodo.dll\"]","\"digitalocean","\"get","$host;","$http_upgrade;","'keep","(.c","(but","(for","(in","(like","(mac/windows/linux)\"","(no","(output","(port","(search","(the","(when","(you'll",".","./","./app/aspnetcoretodo/","./aspnetcoretodo/","./dockerfil","./nginx","./nginx/dockerfil",".csproj","/","/app","/app/aspnetcoretodo","/app/aspnetcoretodo/","/app/aspnetcoretodo/.","/app/aspnetcoretodo/out","/etc/nginx/nginx.conf","/p:publishwithaspnetcoretargetmanifest=\"false\"","1","1.1;","100","1024;","5000","80","80).","80,","80.","8080","8080!).","8080:80","8080!)。nginx","80;","80?","80端口。打开你的浏览器,浏览地址","[\"dotnet\",","accomplish","actual","ad","add","again","alive';","amazon","app","app,","applic","application.","application:","applications.","architectur","aren't","asp.net","aspnetcore_url","aspnetcoretodo","aspnetcoretodo.dll.","aspnetcoretodo.dll。这条命令告诉","aspnetcoretodo/*.csproj","aspnetcoretodo/.","aspnetcoretodo_sampl","avail","azur","azure,","background).","befor","begin","bind","book,","both","browser","build","build:","built","c.","cach","call","case,","cd.","cd。dockerfil","chang","chapter,","cli","cli。搜索","code","code,","command","commands:","communicate.","compil","compos","compose.yml","compose.yml:","compose.yml:","configur","conflict","connect","consist","contain","container","container!","container'","container,","containers.","containers:","control","copi","core","correctli","creat","create.","created,","current","c。","default","defin","depend","deploy","depth","describ","develop","development,","digitalocean","digitalocean,因为他们把入门的门槛降得非常低。digitalocean","direct","directori","directory,","directory.","docker","docker\"","docker\").","dockerfil","dockerfile,","dockerfile.","dockerfile。","dockerfile。为避免跟你刚才创建那个","dockerfile(没有扩展名)的文件。用你常用的编辑器打开它,输入下面这行:","dockerfile,它就像个清单,告诉","docker”","docker”)。","don't","dotnet","dotnet,使用先前由","dure","earlier.","easi","easier,","ec2","ec2,","editor.","entir","entrypoint","env","environ","environment,","equival","event","everyth","example)","example,","execut","explicitli","extension)","fast.","favorit","few","file","file),","file.","file:","files)","files,","final","first","flag","flavor","folder.","follow","forward","from=build","full","get","good","header","help","host","host.","hostnam","http","http://+:80","http://kestrel:80.","http://kestrel:80;","http://kestrel:80。(你马上就会知道为什么要使用","http://localhost","http://localhost:8080","http://localhost(不是","https://github.com/aspnet/announcements/issues/295","imag","image,","image:","incom","information,","insid","instal","instead","instruct","instructions.","interact","interfac","it'","keep","kestrel","kestrel.","kestrel:","kestrel:kestrel","kestrel。这两个容器显式地链接在一起,所以它们可以互相通信。","know","known","last","let","level","line:","lines:","link","links:","linux","list","listen","local","locat","look","machin","machine,","machine.","made","make","map","mean","mention","microsoft","microsoft/dotnet:2.0","minute.","miss","mkdir","mode","modern","moment.)","more","multi","multipl","name","navig","need","needs,","network","new","next","next,","nginx","nginx.conf","nginx/dockerfil","nginx/nginx.conf","nginx:","nginx,用","none","note","now","nuget","o","offici","on","onc","open","oppos","optim","option","out","out.","outsid","overal","p","packag","packages.","path","period!","platform","point,","point.","port","port)","ports:","pre","press","process","processes,","produc","product","project","project,","proxi","proxy_cache_bypass","proxy_http_vers","proxy_pass","proxy_set_head","publish","put","realli","rebuild","recip","recipe,","recipe.","rememb","request","rest","restart","restor","restrict","revers","rm","root","root,","root:","run","run,","run.","running:","runtim","run,它一步就完成了这些事情。)","same","saved,","scale","scope","sdk","search","see","see:","select","server","server_nam","servers.","service.","set","setup","simpli","small.","smaller","specif","spend","spin","start","start,","started.","step.","step.)","stop","super","sure","t","technolog","tell","terminal,","test","then,","there'","they'v","thing","this,","this:","time","togeth","told","too.","tool","top","trail","tri","tutori","two","ubuntu)","ubuntu)都可以搭建成一个","up","upgrad","us","valid","values.","values)。更多信息请参见:https://github.com/aspnet/announcements/issues/295","variabl","verifi","version","virtual","want","web","website.","work","workdir","worker_connect","write","yet.","you'll","you'r","{","}","“amazon","一旦镜像创建完成,你可以运行","上。这件事也可以用","下。注意实际的代码(.c","不要漏掉结尾那个句点!它告诉","个容器和","个容器所需要的工作是一样的。","中之后的命令都会在这个","中定义的那些程序所需的","为基础创建你的镜像。这个镜像是微软发布的,其中包含了执行","之前","之类的反向代理服务器,把请求代理到","也便于把你的应用扩展为多个服务器。一旦你创建了一个镜像,用它来创建","于镜像中重建这些包,docker","以","以交互模式运行这个容器(输出到终端,而不是在后台运行)。当你想要停止这个容器的时候,按","以获取说明。","作为主机名。)","你可以运行以下指令来启动这个多容器程序:","你的","你程序的构建和运行需要些什么。","使用","冲突,在","创建","创建一个新的","创建一个虚拟机,在上面安装","创建一个镜像","包。在添加其它代码","去查看运行在容器中的程序。","去监听","发行版(例如","可以优化镜像生成过程并使它容量紧凑。","命令再次被用到,以选择一个较小的镜像,其中仅含有运行程序所需的依赖。env","命令列出你本地电脑上的全部镜像。要通过容器尝试一下,请执行:","命令创建一个镜像:","命令创建的。","命令用于容器中的设置环境变量,环境变量","命令给","命令编译项目,而","命令重建在","在","在当前目录下查找","在本章开头,我提到过,你应该使用一个","在程序根目录,也就是最外层的","头字段为一个已知的有效值(known","如果你不使用","完整的","官网的提示内容。要检验是否安装成功,可以执行:","容器的","容器监听","容器自己也需要一个","宿主。例如,你可以用亚马逊","宿主机上作为容器启动起来就行了。","将有能力缓存这些重建的包。然后,当你修改代码(而没修改项目文件中定义的包)时,重建这个","已经保存好了,然后用","并执行","并添加这些行:","并监听","应该把服务绑定到哪个网卡和端口上(本例中时","开始之前,需要在你的开发机上安装","当你把程序部署到生产环境,你应该添加","我更喜欢用","打开一个浏览器并导航至","托管的","把","把接到的请求转发到","指令复制","指令,并验证及限定","指出了在被运行的时候去执行","指示","接下来,创建一个","接下来,添加这一行:","搭建","整体架构会包括两个容器:一个","文件夹内执行,该文件夹是上一步的","文件夹里,创建一个名为","文件)并未复制到镜像里。你稍后即可弄清个中缘由。","文件:","既有现成的","是","是个帮助你创建并运行多容器程序的工具。这个配置文件定义了两个容器:","服务器","服务,为此你可以搜索","来做。","标识会将结果输出到一个名为","标识告诉","添加","清单创建","现在,就到了复制其余代码并编译程序的时候了:","用","电脑的","的深度教程(请搜索“digitalocean","的目录里。","的默认)端口上进行监听,并把请求转发到由","看起来是这样的:","确保","程序。","程序根目录新建一个目录:","程序的根目录,创建","程序部署到你自己服务器上的工作。不再需要浪费时间在一个服务器上配置你程序所需的依赖、复制文件、重启进程,你只需要创建一个","端口吗?这里的","端口映射到","端口的容器。","端口)。","端口,把请求转发到另一个运行着","编译出来的文件启动你的程序。(当你在开发时运行","编译程序所需的工具和依赖。以这个预编译镜像为基础,docker","虚拟机,也有关于搭建和运行","设置","详尽的设置指令超出了这本书的范畴,但是任何较新的","运行","还记得环境变量","还需要创建一个文件,回到","这个配置文件告诉","这些编译好的文件,将会通过这最终的几条命令,运行起这个程序:","这指示","这条","这样的容器化技术能极大地简化把","这样的平台,像","进行部署","选项指示","里的","镜像将会非常迅速。","镜像,里面包含你程序运行所需的一切,然后在任何","项目文件到镜像里的路径","首先需要的就是一个","(http"],"chapters/conclusion/":["(2017","(2018","(@nbarbettini)","(https://www.recaffeinate.co).","(includ","(or","(simplifi","(turkish)","(土耳其语)","(简体中文)",".net","01","03):","05","06","09","0xnf","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","10","11","11):","13):","15):","18):","20):","23):","[welkie]","[zhilich]","account","action.","ad","add","ajax","alway","amaz","amazon","andrew","angular","api","app","asp.net","aspnetcor","asset","author","avail","back","best","blog","blog.","book","book!","book,","book/releas","book:","bookstore.","bug","bug修正和一些小改进。","build","bundl","caffein","changelog","chapter","chines","chinese)","clarifi","coding!","comment","commun","comprehensive,","conclus","contain","container)的生命周期添加说明,阐释服务端口和","contributor","core","core.","correct","couldn't","coupon,","cours","cover","crazi","credit.","deep","deployment.","depth","design!","detail","directives.","dive","docker","document","documentation.","don't","email","email:","end","explan","facebook","fantast","featur","fit","fix","flag,","follow","found","fuel","full,","give","happi","hear","help","here:","hey,","highli","hope","http://docs.asp.net","https://docs.asp.net,其中包含了一些有关这些主题的,深入详尽的教程。本人强烈推荐。","https://github.com/nbarbettini/littl","https://twitter.com/nbarbettini","https://www.recaffeinate.co","https://www.recaffeinate.co.","i'd","i'm","ideas.","improv","improvements.","includ","initi","instruct","issu","it!","jennifer,","jennifer,她总是支持我各种疯狂的点子。","latest","learn","lifecycles,","link","linkedin","littl","local","lock","login","long,","lot","love","make","mani","matt","microservic","minifi","more","more:","mvc","nate!","nate'","nate@barbettini.com.","nate!我在一个漫长的灌着咖啡的周末写了这本","need","new!","new,","not),","notic","number","o","offici","page","pattern.","pluralsight","pluralsight.","polyglot","port","practices.","programm","raman","razor","reach","react","readers.","recommend","reflect","release.","remov","rest","rework","sahinyanlik","secur","semicolon","send","server","servic","short","signalr","significantli","simplifi","singl","small","someth","special","sport","stack","static","stay","streamlin","suggest","support","test","thank","there'","thorough","thoughts.","topics.","touch","translat","translations.","truly).","tutori","twitter","twitter:","twitter(@nbarbettini)上和我保持联系,或者在我的博客上(https://www.recaffeinate.co)。你还可以通过电子邮件(nate@barbettini.com)联系我。","typo","updat","us","via","videos,","want","way","way.","websocket","weekend","welk","whole","windsting,","windsting、yuyi","write","wrote","your","yuyi","zhylich","一章,深入地使用了整个","上发表看法:https://twitter.com/nbarbettini","上就有很多非常精彩(其中某些就是来自于你们读者)。如果你在上面没有账号或者想要一张优惠券,请发信到:nate@barbettini.com。","上有也写一些有关","上的教程","为服务容器(servic","以下这些很棒的各国程序员,翻译了本书:","以下这些贡献者,提升了这本书的质量:","你可以在","修正了读者们发现的一些笔误。","关于作者","初次发布。","单页面应用,例如","博客","变更记录","和","和其它主题的博文。","嗨,我是","大幅度重写了","如果你更喜欢通过视频学习,在","如果要深入学习,以下这些方式可供参考:","官方的","微服务","感谢你读完了这本简明","我在自己的博客","手册!如果这本书有点(或者没有)用处,我很乐于倾听您的想法。请在","手册,因为我热爱","打包和压缩静态资源","把","指令以反映最新的优秀实践。修正了笔误,添加了来自读者的建议。还弄了个新改良的封面得瑟了一下!","指令后的分号。修正中文版译者信息。修正其它笔误和读者反馈的问题。","文档","文档位于","更多的bug修正和一些小改进。添加译版的链接。","更深入的学习","构建","框架并移除了","模式。移除","添加新特性","特别致谢","用于","登录以简化安全章节、流水线式的测试和部署。修改了","的","社区,并希望以我的微薄之力付出回报。希望它帮助你学了一点儿新东西。","祝你代码敲得愉快!","笔误修正和一些读者建议的改进。","简明","结束语","还有很多功能,但是无法纳入到这本小册子里,包括:","选项,移除","需要完整、详尽的变更记录,可以到:","页面"]},"length":34},"tokenStore":{"root":{"0":{"0":{"0":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}},"docs":{},"_":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},"s":{"docs":{},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}},"1":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"3":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"5":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"6":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"9":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}}},"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},",":{"docs":{},"或":{"docs":{},"在":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}},"x":{"docs":{},"n":{"docs":{},"f":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}},"1":{"0":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"2":{"4":{"docs":{},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"docs":{}},"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"x":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"1":{"3":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}},"docs":{}},"docs":{}}},"1":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"3":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"5":{"docs":{},".":{"3":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754}}},"docs":{}},"p":{"docs":{},"x":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"8":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},".":{"0":{"docs":{},".":{"0":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"1":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"2":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"3":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"4":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"1":{"docs":{},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},".":{"0":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"1":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"docs":{}}},"5":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"9":{"0":{"7":{"4":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},"docs":{}},"docs":{}},"docs":{}},"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"2":{"0":{"0":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}},"1":{"7":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754}}},"8":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}},"docs":{}},"docs":{},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"3":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"docs":{},".":{"0":{"5":{"8":{"8":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"docs":{}},"docs":{}},"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"用":{"docs":{},"于":{"docs":{},"创":{"docs":{},"建":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"1":{"docs":{},".":{"1":{"0":{"4":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.03076923076923077}}},"docs":{}},"docs":{}},"docs":{}}},"docs":{}}},"3":{"8":{"7":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{}},"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},"级":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},".":{"0":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"docs":{}},",":{"docs":{},"使":{"docs":{},"用":{"docs":{},"如":{"docs":{},"下":{"docs":{},"命":{"docs":{},"令":{"docs":{},"进":{"docs":{},"行":{"docs":{},"安":{"docs":{},"装":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}},"4":{"0":{"0":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},"4":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},"docs":{}},"3":{"docs":{},"e":{"docs":{},"c":{"0":{"9":{"docs":{},"f":{"2":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}},"docs":{}}},"docs":{}},"docs":{}}}},"8":{"docs":{},"e":{"docs":{},"c":{"6":{"8":{"7":{"4":{"6":{"0":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}}},"docs":{"./":{"ref":"./","tf":0.00265017667844523}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"0":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{},"x":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}},",":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}},"f":{"4":{"docs":{},"b":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}},"docs":{}}},"5":{"0":{"0":{"0":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"docs":{}},"docs":{}},"docs":{"./":{"ref":"./","tf":0.0035335689045936395}},",":{"docs":{},"而":{"docs":{},"后":{"docs":{},"者":{"docs":{},"的":{"docs":{},"名":{"docs":{},"字":{"docs":{},"最":{"docs":{},"终":{"docs":{},"被":{"docs":{},"改":{"docs":{},"成":{"docs":{},"了":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}},"6":{"5":{"0":{"1":{"1":{"docs":{},"d":{"5":{"7":{"8":{"1":{"docs":{},"b":{"docs":{},"b":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}},"7":{"5":{"6":{"1":{"5":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{}},"docs":{}},"docs":{}},"docs":{},"f":{"7":{"0":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}},"docs":{}},"docs":{}}},"8":{"0":{"8":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"!":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},":":{"8":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}},"docs":{}},"docs":{}},"!":{"docs":{},")":{"docs":{},"。":{"docs":{},"n":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"docs":{}},"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.004248088360237893}},")":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"?":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"端":{"docs":{},"口":{"docs":{},"。":{"docs":{},"打":{"docs":{},"开":{"docs":{},"你":{"docs":{},"的":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"地":{"docs":{},"址":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}},"6":{"0":{"1":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},")":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},")":{"docs":{},"对":{"docs":{},"机":{"docs":{},"器":{"docs":{},"来":{"docs":{},"说":{"docs":{},"很":{"docs":{},"方":{"docs":{},"便":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"人":{"docs":{},"类":{"docs":{},"看":{"docs":{},"着":{"docs":{},"就":{"docs":{},"不":{"docs":{},"爽":{"docs":{},"了":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"看":{"docs":{},"到":{"docs":{},"的":{"docs":{},"是":{"docs":{},"“":{"docs":{},"还":{"docs":{},"剩":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"9":{"5":{"5":{"9":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}},"docs":{}},"docs":{}},"7":{"8":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{}},"docs":{}},"docs":{},"\"":{"8":{"0":{"docs":{},"\"":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},":":{"8":{"0":{"docs":{},"\"":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"docs":{}},"docs":{}}},"docs":{}},"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"\"":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"w":{"docs":{},"n":{"docs":{},"l":{"docs":{},"o":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}},"e":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"b":{"docs":{},"\"":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}},"i":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"o":{"docs":{},"t":{"docs":{},"\"":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"m":{"docs":{},"b":{"docs":{},"e":{"docs":{},"r":{"docs":{},"\"":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"b":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{},"\"":{"docs":{},")":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"\"":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"\"":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}},"f":{"docs":{},"r":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{},"\"":{"docs":{},")":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}},"a":{"docs":{},"k":{"docs":{},"e":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"@":{"docs":{},"e":{"docs":{},"x":{"docs":{},"a":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"\"":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}},"i":{"docs":{},"r":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}},"h":{"docs":{},"e":{"docs":{},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}},"\"":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}},"u":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"\"":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},":":{"8":{"8":{"8":{"8":{"docs":{},"/":{"docs":{},"a":{"docs":{},"c":{"docs":{},"c":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"t":{"docs":{},"\"":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}}}}}}}}}},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},"s":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"d":{"docs":{},"\"":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}}}}}},"e":{"docs":{},"t":{"docs":{},"a":{"docs":{},"p":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"\"":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}},"p":{"docs":{},"l":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"a":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"@":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"\"":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"\"":{"docs":{},")":{"docs":{},"]":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"z":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"d":{"docs":{},"l":{"docs":{},"l":{"docs":{},"\"":{"docs":{},"]":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"\"":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"n":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},"\"":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"y":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"\"":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}},"e":{"docs":{},"a":{"docs":{},"r":{"docs":{},"n":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}}}},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"b":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}},"w":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"x":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"s":{"docs":{},"c":{"docs":{},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"o":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}},"e":{"docs":{},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}},"n":{"docs":{},"o":{"docs":{},"t":{"docs":{},"s":{"docs":{},"e":{"docs":{},"c":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"1":{"2":{"3":{"docs":{},"!":{"docs":{},"!":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"_":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"\"":{"docs":{},")":{"docs":{},".":{"docs":{},"o":{"docs":{},"p":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"?":{"docs":{},"\"":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}},".":{"docs":{},".":{"docs":{},"\\":{"docs":{},"\\":{"docs":{},".":{"docs":{},".":{"docs":{},"\\":{"docs":{},"\\":{"docs":{},".":{"docs":{},".":{"docs":{},"\\":{"docs":{},"\\":{"docs":{},".":{"docs":{},".":{"docs":{},"\\":{"docs":{},"\\":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"\"":{"docs":{},")":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"e":{"docs":{},"p":{"docs":{},"l":{"docs":{},"o":{"docs":{},"y":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},",":{"docs":{},"以":{"docs":{},"此":{"docs":{},"避":{"docs":{},"免":{"docs":{},"被":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}},"/":{"docs":{},"l":{"docs":{},"o":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"?":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"n":{"docs":{},"u":{"docs":{},"r":{"docs":{},"l":{"docs":{},"=":{"docs":{},"%":{"2":{"docs":{},"f":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}},"docs":{}}}}}}}}}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"(":{"2":{"0":{"1":{"7":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.017278617710583154}}},"8":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.012958963282937365}}},"docs":{}},"docs":{}},"docs":{},".":{"1":{"docs":{},".":{"1":{"0":{"4":{"docs":{},")":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}}},"docs":{}},"docs":{}},"docs":{}}},"docs":{}}},"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"a":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792}}}},"l":{"docs":{},"s":{"docs":{},"o":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"y":{"docs":{},"e":{"docs":{},"x":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"r":{"docs":{},"e":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}},"r":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"t":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"p":{"docs":{},"p":{"docs":{},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"s":{"docs":{},".":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}},"w":{"docs":{},"a":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}},"c":{"docs":{},"#":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"h":{"docs":{},"i":{"docs":{},"n":{"docs":{},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"s":{"docs":{},"r":{"docs":{},"f":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"m":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"n":{"docs":{},"n":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"u":{"docs":{},"r":{"docs":{},"r":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}}}}}}}}}}},"e":{"docs":{},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"v":{"docs":{},"e":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"x":{"docs":{},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}},"t":{"docs":{},"c":{"docs":{},".":{"docs":{},".":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"w":{"docs":{},"w":{"docs":{},"w":{"docs":{},".":{"docs":{},"n":{"docs":{},"u":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},".":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},"/":{"docs":{},"p":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"/":{"docs":{},"h":{"docs":{},"u":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}},"j":{"docs":{},"v":{"docs":{},"m":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"u":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"/":{"docs":{},"b":{"docs":{},"o":{"docs":{},"o":{"docs":{},"k":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"a":{"docs":{},"y":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"n":{"docs":{},"g":{"docs":{},"u":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}},"o":{"docs":{},"g":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"r":{"docs":{},"e":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"v":{"docs":{},"c":{"docs":{},")":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"a":{"docs":{},"k":{"docs":{},"e":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"r":{"docs":{},"k":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"c":{"docs":{},"/":{"docs":{},"w":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"o":{"docs":{},"w":{"docs":{},"s":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"u":{"docs":{},"x":{"docs":{},")":{"docs":{},"\"":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}}}}}}}},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}},"o":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"m":{"docs":{},")":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"p":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"a":{"docs":{},"l":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"n":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"u":{"docs":{},"t":{"docs":{},"p":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"t":{"docs":{},"h":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"i":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"u":{"docs":{},"r":{"docs":{},"k":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},"r":{"docs":{},"u":{"docs":{},"e":{"docs":{},"/":{"docs":{},"f":{"docs":{},"a":{"docs":{},"l":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},"i":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"s":{"docs":{},"i":{"docs":{},"m":{"docs":{},"i":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"f":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"g":{"docs":{},"n":{"docs":{},"i":{"docs":{},"n":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"i":{"docs":{},"s":{"docs":{},"s":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"n":{"docs":{},"(":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"o":{"docs":{},"m":{"docs":{},"e":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}},"h":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"e":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}},"a":{"docs":{},"r":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"t":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"i":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"i":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"n":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"t":{"docs":{},"e":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"c":{"docs":{},"l":{"docs":{},"u":{"docs":{},"d":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"f":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"e":{"docs":{},"m":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}},"d":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}},"s":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"n":{"docs":{},"o":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"a":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}},"不":{"docs":{},"带":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"r":{"docs":{},"u":{"docs":{},"b":{"docs":{},"i":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"o":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}},"e":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"e":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"d":{"docs":{},"e":{"docs":{},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"s":{"docs":{},"p":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}},"o":{"docs":{},"c":{"docs":{},"u":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},")":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"v":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}},"i":{"docs":{},"a":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},".":{"docs":{},".":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}}},"c":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"e":{"docs":{},"t":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}},"p":{"docs":{},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},"s":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}},"r":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"r":{"docs":{},"o":{"docs":{},"t":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}},"!":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"i":{"docs":{},"s":{"docs":{},"v":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"d":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"u":{"docs":{},"c":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"f":{"docs":{},"u":{"docs":{},"l":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}}}}}}}}}}}},"b":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"g":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},"连":{"docs":{},"同":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"$":{"1":{"0":{"docs":{},"/":{"docs":{},"m":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"h":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}},"docs":{}},"docs":{}},"@":{"docs":{},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},")":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}},"土":{"docs":{},"耳":{"docs":{},"其":{"docs":{},"语":{"docs":{},")":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"简":{"docs":{},"体":{"docs":{},"中":{"docs":{},"文":{"docs":{},")":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.038869257950530034},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0213903743315508},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.046153846153846156},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.017804154302670624},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.011049723756906077},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"标":{"docs":{},"准":{"1":{"docs":{},".":{"0":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"5":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{}}},"2":{"docs":{},".":{"0":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"docs":{}}},"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"命":{"docs":{},"名":{"docs":{},"有":{"docs":{},"些":{"docs":{},"混":{"docs":{},"乱":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"在":{"docs":{},"此":{"docs":{},"做":{"docs":{},"一":{"docs":{},"简":{"docs":{},"短":{"docs":{},"的":{"docs":{},"释":{"docs":{},"疑":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"c":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"(":{"docs":{},"(":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},"/":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"/":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}}}}}}},"e":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"c":{"docs":{},"u":{"docs":{},"r":{"docs":{},"r":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},">":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"\"":{"docs":{},")":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},"a":{"docs":{},"r":{"docs":{},"r":{"docs":{},"a":{"docs":{},"y":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}},"x":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}},"w":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{},"(":{"docs":{},"x":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{},"e":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{},"e":{"docs":{},"f":{"docs":{},"a":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"r":{"docs":{},"k":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"i":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"e":{"docs":{},"x":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"i":{"docs":{},"n":{"docs":{},"m":{"docs":{},"e":{"docs":{},"m":{"docs":{},"o":{"docs":{},"r":{"docs":{},"y":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"u":{"docs":{},"p":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}},"d":{"docs":{},"e":{"docs":{},"p":{"docs":{},"l":{"docs":{},"o":{"docs":{},"y":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.012962962962962963}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},",":{"docs":{},"而":{"docs":{},"不":{"docs":{},"带":{"docs":{},"有":{"docs":{},"什":{"docs":{},"么":{"docs":{},"其":{"docs":{},"它":{"docs":{},"的":{"docs":{},"零":{"docs":{},"碎":{"docs":{},"儿":{"docs":{},"。":{"docs":{},"(":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}},"/":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"/":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"/":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"/":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}},"n":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"/":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"b":{"docs":{},"o":{"docs":{},"v":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}},"e":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},",":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}},"u":{"docs":{},"t":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}}},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"s":{"docs":{},"o":{"docs":{},"l":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}},"i":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"c":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.034375},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.00963855421686747},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.01744186046511628},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.024007386888273315},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.012850467289719626},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.022556390977443608},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"名":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},",":{"docs":{},"把":{"docs":{},"那":{"docs":{},"句":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},",":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"!":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"v":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464}}}}}}}}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}},"c":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"u":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"p":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"'":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}},"h":{"docs":{},"i":{"docs":{},"e":{"docs":{},"v":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"d":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.008310249307479225},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0064794816414686825}},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.016574585635359115},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.09375},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.019390581717451522},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.017523364485981307},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.010945273631840797},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0069767441860465115},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.015228426395939087},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.007761966364812419},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.009259259259259259},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"e":{"docs":{},"m":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.00909090909090909},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.007386888273314866},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}},"s":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"(":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},"(":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}}}}}}}}}},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"p":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},",":{"docs":{},"其":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"会":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"d":{"docs":{},"u":{"docs":{},"e":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"v":{"docs":{},"a":{"docs":{},"n":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}}},"t":{"docs":{},"a":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}},"@":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}}}}}}}}}}},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.020155038759689922}},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"i":{"docs":{},"c":{"docs":{},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"s":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"h":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"l":{"docs":{},"o":{"docs":{},"n":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"!":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.00530035335689046},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.01048951048951049},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"y":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},"e":{"docs":{},"x":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}},"i":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"u":{"docs":{},"g":{"docs":{},"h":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}},"e":{"docs":{},"r":{"docs":{},"n":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}},"w":{"docs":{},"a":{"docs":{},"y":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},"'":{"docs":{},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}},"n":{"docs":{},"o":{"docs":{},"t":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"n":{"docs":{},"y":{"docs":{},"m":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"y":{"docs":{},"t":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"w":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}}}}},"o":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"d":{"docs":{},"r":{"docs":{},"o":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756}}}}},"e":{"docs":{},"w":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"g":{"docs":{},"u":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}},"s":{"docs":{},"w":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"p":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}}}}},"i":{"docs":{"./":{"ref":"./","tf":0.011484098939929329},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}},"。":{"docs":{},"值":{"docs":{},"得":{"docs":{},"指":{"docs":{},"出":{"docs":{},"的":{"docs":{},"是":{"docs":{},",":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"这":{"docs":{},"是":{"docs":{},"你":{"docs":{},"将":{"docs":{},"要":{"docs":{},"安":{"docs":{},"装":{"docs":{},"到":{"docs":{},"机":{"docs":{},"器":{"docs":{},"上":{"docs":{},",":{"docs":{},"用":{"docs":{},"来":{"docs":{},"构":{"docs":{},"建":{"docs":{},"和":{"docs":{},"运":{"docs":{},"行":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.016666666666666666},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"l":{"docs":{},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.00909090909090909},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"c":{"docs":{"./":{"ref":"./","tf":0.006183745583038869},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.003875968992248062},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00646830530401035},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.02077922077922078},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.009345794392523364}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"_":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.015228426395939087},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0375},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"!":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.013157894736842105},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"(":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806}},"o":{"docs":{},"p":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},")":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}}}}}}}}}},",":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"。":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}},"(":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"画":{"docs":{},"一":{"docs":{},"条":{"docs":{},"线":{"docs":{},"表":{"docs":{},"示":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},",":{"docs":{},"后":{"docs":{},"者":{"docs":{},"通":{"docs":{},"常":{"docs":{},"连":{"docs":{},"接":{"docs":{},"到":{"docs":{},"你":{"docs":{},"的":{"docs":{},"开":{"docs":{},"发":{"docs":{},"或":{"docs":{},"生":{"docs":{},"产":{"docs":{},"环":{"docs":{},"境":{"docs":{},"里":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{},"你":{"docs":{},"不":{"docs":{},"该":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"用":{"docs":{},"于":{"docs":{},"测":{"docs":{},"试":{"docs":{},"。":{"docs":{},"相":{"docs":{},"反":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"测":{"docs":{},"试":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"这":{"docs":{},"种":{"docs":{},"方":{"docs":{},"式":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01791044776119403},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}},"e":{"docs":{},"r":{"docs":{},"[":{"docs":{},"]":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"p":{"docs":{},"r":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"s":{"docs":{},".":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}}}}}}}}}}}}},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}},"\"":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"d":{"docs":{},"b":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"!":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"g":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}},"c":{"docs":{},"h":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"u":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}},"r":{"docs":{},"a":{"docs":{},"y":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"n":{"docs":{},"g":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},"s":{"docs":{},"p":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.023255813953488372},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.008310249307479225}},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.052120141342756186},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.03208556149732621},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":2.516949152542373},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.024390243902439025},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.01927710843373494},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.012362637362637362},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.029069767441860465},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.01569713758079409},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.05113636363636364},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.05583756345177665},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.04155844155844156},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.038876889848812095}},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.02401129943502825},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},",":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"新":{"docs":{},"增":{"docs":{},"了":{"docs":{},"一":{"docs":{},"行":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.007207207207207207},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"s":{"docs":{},";":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},"中":{"docs":{},")":{"docs":{},",":{"docs":{},"它":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"条":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"。":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{},"是":{"docs":{},"一":{"docs":{},"种":{"docs":{},"组":{"docs":{},"织":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},"l":{"docs":{},"l":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"。":{"docs":{},"这":{"docs":{},"条":{"docs":{},"命":{"docs":{},"令":{"docs":{},"告":{"docs":{},"诉":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"u":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.012089810017271158},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"s":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}},"/":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"h":{"docs":{},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.018111254851228976},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"s":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}},"/":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"f":{"docs":{},"i":{"docs":{},"x":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"h":{"docs":{},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},")":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"/":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}}}}}}}}}}}}}}}}}},"*":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}},")":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},"使":{"docs":{},"用":{"docs":{},"以":{"docs":{},"下":{"docs":{},"命":{"docs":{},"令":{"docs":{},"搭":{"docs":{},"建":{"docs":{},"出":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.014814814814814815}}}}}}},"p":{"docs":{},"l":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}}}}}},"_":{"docs":{},"s":{"docs":{},"a":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}},"_":{"docs":{},"u":{"docs":{},"r":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}}}}}}}}}}}}},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.013930348258706468},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"h":{"docs":{},"r":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"o":{"docs":{},"u":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"m":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}},"r":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{},"(":{"1":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}},"\"":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"?":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}},"f":{"docs":{},"a":{"docs":{},"l":{"docs":{},"s":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}},"t":{"docs":{},"r":{"docs":{},"u":{"docs":{},"e":{"docs":{},"(":{"docs":{},"d":{"docs":{},"i":{"docs":{},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}},")":{"docs":{},"模":{"docs":{},"式":{"docs":{},":":{"docs":{},"对":{"docs":{},"象":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"首":{"docs":{},"先":{"docs":{},"被":{"docs":{},"建":{"docs":{},"立":{"docs":{},"出":{"docs":{},"来":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"执":{"docs":{},"行":{"docs":{},"一":{"docs":{},"些":{"docs":{},"动":{"docs":{},"作":{"docs":{},",":{"docs":{},"最":{"docs":{},"后":{"docs":{},"测":{"docs":{},"试":{"docs":{},"程":{"docs":{},"序":{"docs":{},"检":{"docs":{},"查":{"docs":{},"(":{"docs":{},"断":{"docs":{},"言":{"docs":{},")":{"docs":{},"预":{"docs":{},"期":{"docs":{},"表":{"docs":{},"现":{"docs":{},"的":{"docs":{},"存":{"docs":{},"在":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},"u":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"p":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"t":{"docs":{},"t":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"h":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"r":{"docs":{},"i":{"docs":{},"b":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.03007518796992481},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},")":{"docs":{},".":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}},"o":{"docs":{},"m":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},"、":{"docs":{},"s":{"docs":{},"u":{"docs":{},"b":{"docs":{},"l":{"docs":{},"i":{"docs":{},"m":{"docs":{},"e":{"docs":{},"、":{"docs":{},"n":{"docs":{},"o":{"docs":{},"t":{"docs":{},"e":{"docs":{},"p":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}}},"v":{"docs":{},"a":{"docs":{},"i":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"o":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.022727272727272728},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.03007518796992481}},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}},"o":{"docs":{},"r":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.005426356589147287},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"i":{"docs":{},"z":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}},"o":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"m":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},",":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}},"w":{"docs":{},"a":{"docs":{},"y":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"i":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.01098901098901099},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.01263537906137184},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.009345794392523364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01791044776119403},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.018604651162790697},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0069084628670120895},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"罕":{"docs":{},"见":{"docs":{},"的":{"docs":{},"例":{"docs":{},"外":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},",":{"docs":{},"以":{"docs":{},"确":{"docs":{},"保":{"docs":{},"你":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"暂":{"docs":{},"停":{"docs":{},",":{"docs":{},"直":{"docs":{},"到":{"docs":{},"结":{"docs":{},"果":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"才":{"docs":{},"继":{"docs":{},"续":{"docs":{},"执":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}},"(":{"docs":{},"等":{"docs":{},"待":{"docs":{},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"!":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"r":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"e":{"docs":{},"s":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"m":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"a":{"docs":{},"z":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"o":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"z":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.025925925925925925}},"u":{"docs":{},"r":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.023376623376623377},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":5.055555555555555},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"就":{"docs":{},"都":{"docs":{},"是":{"docs":{},"自":{"docs":{},"动":{"docs":{},"为":{"docs":{},"你":{"docs":{},"处":{"docs":{},"理":{"docs":{},"的":{"docs":{},"。":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"a":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"(":{"docs":{},"布":{"docs":{},"置":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"j":{"docs":{},"a":{"docs":{},"x":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}},"b":{"2":{"docs":{},"c":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294}},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}},"g":{"docs":{},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}}}}},"s":{"docs":{},"i":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{},"f":{"docs":{},"#":{"docs":{},")":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"来":{"docs":{},"编":{"docs":{},"写":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}},"e":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"(":{"docs":{},"o":{"docs":{},"p":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806}}}}}}}}}}},".":{"docs":{},"o":{"docs":{},"n":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"(":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"r":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"c":{"docs":{},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}}}}}},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"e":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"c":{"docs":{},"a":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"n":{"docs":{},"e":{"docs":{},"f":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"t":{"docs":{},"w":{"docs":{},"e":{"docs":{},"e":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"h":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}},"a":{"docs":{},"v":{"docs":{},"i":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}}}}}}}},"s":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"i":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"g":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},")":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}},"d":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"/":{"docs":{},"v":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}},"o":{"docs":{},"o":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.01060070671378092},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"/":{"docs":{},"b":{"docs":{},"o":{"docs":{},"o":{"docs":{},"k":{"docs":{},"/":{"docs":{},")":{"docs":{},"的":{"docs":{},"版":{"docs":{},"本":{"docs":{},"更":{"docs":{},"新":{"docs":{},"。":{"docs":{},"有":{"docs":{},"关":{"docs":{},"版":{"docs":{},"本":{"docs":{},"信":{"docs":{},"息":{"docs":{},"和":{"docs":{},"更":{"docs":{},"新":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"请":{"docs":{},"查":{"docs":{},"阅":{"docs":{},"本":{"docs":{},"书":{"docs":{},"的":{"docs":{},"最":{"docs":{},"后":{"docs":{},"一":{"docs":{},"页":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"s":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"t":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"p":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}}},"x":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"t":{"docs":{},"h":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"t":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"w":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"a":{"docs":{},"d":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"e":{"docs":{},"a":{"docs":{},"k":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}},"p":{"docs":{},"o":{"docs":{},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"s":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}},"u":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"s":{"docs":{},",":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}},",":{"docs":{},"并":{"docs":{},"使":{"docs":{},"你":{"docs":{},"后":{"docs":{},"续":{"docs":{},"重":{"docs":{},"构":{"docs":{},"代":{"docs":{},"码":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"轻":{"docs":{},"松":{"docs":{},"些":{"docs":{},",":{"docs":{},"以":{"docs":{},"免":{"docs":{},"破":{"docs":{},"坏":{"docs":{},"现":{"docs":{},"有":{"docs":{},"功":{"docs":{},"能":{"docs":{},"或":{"docs":{},"引":{"docs":{},"入":{"docs":{},"新":{"docs":{},"的":{"docs":{},"问":{"docs":{},"题":{"docs":{},"。":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"修":{"docs":{},"正":{"docs":{},"和":{"docs":{},"一":{"docs":{},"些":{"docs":{},"小":{"docs":{},"改":{"docs":{},"进":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0088339222614841},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.016042780748663103},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.01524390243902439},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.009345794392523364},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},")":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403}}}}},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},"(":{"docs":{},"a":{"docs":{},"r":{"docs":{},"g":{"docs":{},"s":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}}}}},"n":{"docs":{},"d":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"t":{"docs":{},"t":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"s":{"docs":{},"i":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.009915014164305949},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}}}}},"l":{"docs":{},"o":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"c":{"docs":{},"k":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"g":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"a":{"docs":{},"n":{"docs":{},"k":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"i":{"docs":{},"s":{"docs":{},"s":{"docs":{},"f":{"docs":{},"u":{"docs":{},"l":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}},"c":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"#":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":2.5326409495548963},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.014414414414414415},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.014457831325301205},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.030927835051546393},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"、":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},"、":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}},"里":{"docs":{},"的":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},"总":{"docs":{},"是":{"docs":{},"可":{"docs":{},"空":{"docs":{},"的":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"没":{"docs":{},"必":{"docs":{},"要":{"docs":{},"给":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"l":{"docs":{},"l":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"b":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"c":{"docs":{},"u":{"docs":{},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"s":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"d":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"r":{"docs":{},"e":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"t":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}},"u":{"docs":{},"s":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"p":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}},"c":{"docs":{},"h":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"r":{"docs":{},"t":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"e":{"docs":{},"l":{"docs":{},"o":{"docs":{},"g":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},")":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"d":{"docs":{},"!":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"p":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}},")":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}},"l":{"docs":{},"l":{"docs":{},"e":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}}}}},"a":{"docs":{},"n":{"docs":{},"o":{"docs":{},"n":{"docs":{},"y":{"docs":{},"m":{"docs":{},"o":{"docs":{},"u":{"docs":{},"s":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"c":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.022556390977443608},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"b":{"docs":{},"o":{"docs":{},"x":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.015186915887850467}},"'":{"docs":{},")":{"docs":{},".":{"docs":{},"o":{"docs":{},"n":{"docs":{},"(":{"docs":{},"'":{"docs":{},"c":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"k":{"docs":{},"'":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"c":{"docs":{},"l":{"docs":{},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"(":{"docs":{},"'":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{},"'":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}},"t":{"docs":{},"r":{"docs":{},"'":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}},"d":{"docs":{},"i":{"docs":{},"s":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"s":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"a":{"docs":{},"p":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"o":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"o":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"u":{"docs":{},"n":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}},"i":{"docs":{},"n":{"docs":{},"e":{"docs":{},"s":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},")":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.014414414414414415},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.014164305949008499},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.012362637362637362},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.01263537906137184},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.008527131782945736},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0069084628670120895},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0129366106080207}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"?":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}},"r":{"docs":{},"i":{"docs":{},"f":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"u":{"docs":{},"d":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}}}}},"i":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.009259259259259259},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},")":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},")":{"docs":{},"确":{"docs":{},"保":{"docs":{},"一":{"docs":{},"切":{"docs":{},"正":{"docs":{},"常":{"docs":{},"工":{"docs":{},"作":{"docs":{},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}}}},"c":{"docs":{},"k":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}},".":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}},"d":{"docs":{},"i":{"docs":{},"s":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"p":{"docs":{},"b":{"docs":{},"o":{"docs":{},"a":{"docs":{},"r":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},"(":{"docs":{},"按":{"docs":{},"照":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"。":{"docs":{},"搜":{"docs":{},"索":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"u":{"docs":{},"n":{"docs":{},"k":{"docs":{},"i":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.01060070671378092},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.03208556149732621},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.01483679525222552},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.012711864406779662},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0169971671388102},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.030927835051546393},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.015228426395939087},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},".":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}}}}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"\"":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},"”":{"docs":{},"再":{"docs":{},"按":{"docs":{},"指":{"docs":{},"令":{"docs":{},"操":{"docs":{},"作":{"docs":{},"即":{"docs":{},"可":{"docs":{},"。":{"docs":{},"(":{"docs":{},"译":{"docs":{},"者":{"docs":{},"的":{"docs":{},"话":{"docs":{},":":{"docs":{},"别":{"docs":{},"用":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"免":{"docs":{},"费":{"docs":{},"、":{"docs":{},"跨":{"docs":{},"平":{"docs":{},"台":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},",":{"docs":{},"对":{"docs":{},"于":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}}},")":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"用":{"docs":{},"的":{"docs":{},"是":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}},",":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},")":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"在":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"里":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}},",":{"docs":{},"当":{"docs":{},"你":{"docs":{},"鼠":{"docs":{},"标":{"docs":{},"指":{"docs":{},"针":{"docs":{},"指":{"docs":{},"向":{"docs":{},"一":{"docs":{},"个":{"docs":{},"红":{"docs":{},"色":{"docs":{},"波":{"docs":{},"浪":{"docs":{},"线":{"docs":{},"时":{"docs":{},",":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"会":{"docs":{},"提":{"docs":{},"示":{"docs":{},"你":{"docs":{},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"些":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"可":{"docs":{},"能":{"docs":{},"需":{"docs":{},"要":{"docs":{},"关":{"docs":{},"闭":{"docs":{},"并":{"docs":{},"重":{"docs":{},"新":{"docs":{},"打":{"docs":{},"开":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"m":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"m":{"docs":{},"e":{"docs":{},"r":{"docs":{},"c":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},")":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"u":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.023076923076923078},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.008902077151335312},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}},"s":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"!":{"docs":{},"\"":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"i":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"r":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"s":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"x":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"r":{"docs":{},"i":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},"e":{"docs":{},"h":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"o":{"docs":{},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},":":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}},"s":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},"e":{"docs":{},".":{"docs":{},"y":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"b":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"r":{"docs":{},"n":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"s":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"l":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}},"u":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646}},"e":{"docs":{},"s":{"docs":{},"(":{"docs":{},"i":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"l":{"docs":{},"l":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"n":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"d":{"docs":{},"e":{"docs":{},"f":{"docs":{},"a":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"n":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"\"":{"docs":{},")":{"docs":{},")":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{},"e":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"s":{"docs":{},".":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"p":{"docs":{},"a":{"docs":{},"t":{"docs":{},"h":{"docs":{},"(":{"docs":{},"p":{"docs":{},"a":{"docs":{},"t":{"docs":{},"h":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"b":{"docs":{},"i":{"docs":{},"n":{"docs":{},"e":{"docs":{},"(":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"n":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.03496503496503497},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"o":{"docs":{},"r":{"docs":{},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"t":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.009345794392523364},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}}},"s":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"!":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"'":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},")":{"docs":{},"的":{"docs":{},"生":{"docs":{},"命":{"docs":{},"周":{"docs":{},"期":{"docs":{},"添":{"docs":{},"加":{"docs":{},"说":{"docs":{},"明":{"docs":{},",":{"docs":{},"阐":{"docs":{},"释":{"docs":{},"服":{"docs":{},"务":{"docs":{},"端":{"docs":{},"口":{"docs":{},"和":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186}},"(":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}}},")":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},")":{"docs":{},",":{"docs":{},"由":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.013986013986013986},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.021929824561403508},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.008635578583765112}},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},".":{"docs":{},"f":{"docs":{},"i":{"docs":{},"r":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}},"r":{"docs":{},"i":{"docs":{},"b":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"o":{"docs":{},"r":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"o":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.046875},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.014285714285714285},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.01744186046511628},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},")":{"docs":{},"、":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},",":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{},"由":{"docs":{},"中":{"docs":{},"间":{"docs":{},"件":{"docs":{},"构":{"docs":{},"成":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"处":{"docs":{},"理":{"docs":{},"管":{"docs":{},"线":{"docs":{},"。":{"docs":{},"它":{"docs":{},"基":{"docs":{},"于":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}},"架":{"docs":{},"构":{"docs":{},"的":{"docs":{},"组":{"docs":{},"件":{"docs":{},"。":{"docs":{},"下":{"docs":{},"一":{"docs":{},"章":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"一":{"docs":{},"探":{"docs":{},"他":{"docs":{},"们":{"docs":{},"三":{"docs":{},"者":{"docs":{},"的":{"docs":{},"究":{"docs":{},"竟":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"构":{"docs":{},"建":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}},"s":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},"放":{"docs":{},"置":{"docs":{},"着":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"/":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},":":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"u":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"s":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.02373887240356083},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"e":{"docs":{},".":{"docs":{},"w":{"docs":{},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"e":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"h":{"docs":{},"e":{"docs":{},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"r":{"docs":{},"u":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"o":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.003875968992248062}},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}}}}}}}}}}}}}},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"s":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"v":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"i":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},"r":{"docs":{},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}},"p":{"docs":{},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"r":{"docs":{},"i":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}}},"i":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.018691588785046728}}}},"r":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.04858657243816254},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0481283422459893},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.008902077151335312},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":2.516949152542373},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.021341463414634148},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.024096385542168676},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.01098901098901099},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.023255813953488372},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.013812154696132596},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.041237113402061855},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.038461538461538464},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.00909090909090909},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.021660649819494584},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.01569713758079409},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.045454545454545456},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.06091370558375635},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.04155844155844156},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0367170626349892}},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"\"":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}},"”":{"docs":{},",":{"docs":{},"在":{"docs":{},"微":{"docs":{},"软":{"docs":{},"为":{"docs":{},"你":{"docs":{},"所":{"docs":{},"在":{"docs":{},"平":{"docs":{},"台":{"docs":{},"提":{"docs":{},"供":{"docs":{},"的":{"docs":{},"下":{"docs":{},"载":{"docs":{},"页":{"docs":{},"面":{"docs":{},",":{"docs":{},"获":{"docs":{},"取":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125}}},"、":{"docs":{},"c":{"docs":{},"#":{"docs":{},"和":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{},"模":{"docs":{},"式":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}},",":{"docs":{},"你":{"docs":{},"想":{"docs":{},"把":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"在":{"docs":{},"任":{"docs":{},"何":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"只":{"docs":{},"要":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},"该":{"docs":{},"视":{"docs":{},"图":{"docs":{},"需":{"docs":{},"要":{"docs":{},"配":{"docs":{},"合":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},")":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"包":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"(":{"docs":{},"以":{"docs":{},"及":{"docs":{},"你":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},")":{"docs":{},"打":{"docs":{},"交":{"docs":{},"道":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"用":{"docs":{},"单":{"docs":{},"件":{"docs":{},"(":{"docs":{},"或":{"docs":{},"其":{"docs":{},"它":{"docs":{},")":{"docs":{},"生":{"docs":{},"命":{"docs":{},"周":{"docs":{},"期":{"docs":{},"会":{"docs":{},"引":{"docs":{},"发":{"docs":{},"麻":{"docs":{},"烦":{"docs":{},",":{"docs":{},"原":{"docs":{},"因":{"docs":{},"在":{"docs":{},"于":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"'":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"p":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"c":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"i":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"a":{"docs":{},"g":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"u":{"docs":{},"p":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"r":{"docs":{},"s":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"l":{"docs":{},"d":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"l":{"docs":{},"o":{"docs":{},"r":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}},"l":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}},"u":{"docs":{},"m":{"docs":{},"n":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"s":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}},"s":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.01483679525222552},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.016363636363636365},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.006463527239150508},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.008527131782945736},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.025925925925925925},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.011045029736618521}},"i":{"docs":{},"v":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},"e":{"docs":{},"d":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},"s":{"docs":{},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"o":{"docs":{},"s":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}}},"a":{"docs":{},"z":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.014457831325301205},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"、":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},"、":{"docs":{},"图":{"docs":{},"片":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}},"h":{"docs":{},"a":{"docs":{},"r":{"docs":{},"p":{"docs":{},"h":{"docs":{},"e":{"docs":{},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.02967359050445104}},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"j":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"f":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.01483679525222552},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.014124293785310734},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"。":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}},"t":{"docs":{},"r":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"+":{"docs":{},"c":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}}}}},"u":{"docs":{},"r":{"docs":{},"s":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}},"r":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.008955223880597015},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}},"s":{"docs":{},"t":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"a":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"y":{"docs":{},"c":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"d":{"1":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"(":{"docs":{},"$":{"1":{"0":{"docs":{},"/":{"docs":{},"月":{"docs":{},")":{"docs":{},"或":{"docs":{},"更":{"docs":{},"高":{"docs":{},"级":{"docs":{},"的":{"docs":{},"方":{"docs":{},"案":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}},"docs":{}},"docs":{}}}},"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.008522727272727272},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.014414414414414415},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0113314447592068},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.008241758241758242},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.05154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.05244755244755245},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.021929824561403508},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.025454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.008955223880597015},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.013986013986013986},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"\"":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}},"”":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"并":{"docs":{},"阅":{"docs":{},"读":{"docs":{},"微":{"docs":{},"软":{"docs":{},"的":{"docs":{},"关":{"docs":{},"于":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"!":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"/":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403}}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"i":{"docs":{},"g":{"docs":{},"r":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"/":{"docs":{},"_":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"o":{"docs":{},"u":{"docs":{},"r":{"docs":{},"c":{"docs":{},"e":{"docs":{},"=":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},".":{"docs":{},"d":{"docs":{},"b":{"docs":{},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}},"e":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.013812154696132596},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"/":{"docs":{},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"o":{"docs":{},"f":{"docs":{},"f":{"docs":{},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"?":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}},",":{"docs":{},"c":{"docs":{},"#":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},".":{"docs":{},"n":{"docs":{},"o":{"docs":{},"w":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"d":{"docs":{},"a":{"docs":{},"y":{"docs":{},"s":{"docs":{},"(":{"1":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}},"2":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}},"3":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"y":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},"s":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"u":{"docs":{},"p":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}}}},"i":{"docs":{},"d":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},"s":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121}},"e":{"docs":{},"d":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}},"f":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"i":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"a":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},":":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"i":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}},"l":{"docs":{},"o":{"docs":{},"y":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.015584415584415584},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.018518518518518517},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}},"t":{"docs":{},"h":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"v":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"b":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"v":{"docs":{},"e":{"docs":{},"l":{"docs":{},"o":{"docs":{},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}},"t":{"docs":{},"a":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"s":{"docs":{},".":{"docs":{},".":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}}}}}}}}},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}},"b":{"docs":{},"u":{"docs":{},"g":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}}},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"n":{"docs":{},"i":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"e":{"docs":{},"p":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"i":{"docs":{},"d":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},"!":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"t":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"v":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},".":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}},"r":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.015536723163841809},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}}}},"y":{"docs":{},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},")":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"u":{"docs":{},"r":{"docs":{},"r":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"d":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"y":{"docs":{},"(":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}},"l":{"docs":{},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"y":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}},"s":{"docs":{},"p":{"docs":{},"l":{"docs":{},"a":{"docs":{},"y":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}},"p":{"docs":{},"p":{"docs":{},"e":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"c":{"docs":{},"o":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"他":{"docs":{},"们":{"docs":{},"把":{"docs":{},"入":{"docs":{},"门":{"docs":{},"的":{"docs":{},"门":{"docs":{},"槛":{"docs":{},"降":{"docs":{},"得":{"docs":{},"非":{"docs":{},"常":{"docs":{},"低":{"docs":{},"。":{"docs":{},"d":{"docs":{},"i":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"j":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"o":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"o":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"e":{"docs":{},"s":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"e":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},".":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}},"!":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"w":{"docs":{},"n":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.01090909090909091}},"l":{"docs":{},"o":{"docs":{},"a":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}},"(":{"docs":{},"m":{"docs":{},"i":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.046153846153846156},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.04154302670623145},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.01694915254237288},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.011049723756906077},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.017482517482517484},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.03090909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.006044905008635579},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.01784197111299915}},",":{"docs":{},"使":{"docs":{},"用":{"docs":{},"先":{"docs":{},"前":{"docs":{},"由":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"c":{"docs":{},"u":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.008902077151335312},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.033766233766233764},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":3.389408099688473},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"\"":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},")":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0118946474086661}},"e":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"为":{"docs":{},"避":{"docs":{},"免":{"docs":{},"跟":{"docs":{},"你":{"docs":{},"刚":{"docs":{},"才":{"docs":{},"创":{"docs":{},"建":{"docs":{},"那":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"(":{"docs":{},"没":{"docs":{},"有":{"docs":{},"扩":{"docs":{},"展":{"docs":{},"名":{"docs":{},")":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},"。":{"docs":{},"用":{"docs":{},"你":{"docs":{},"常":{"docs":{},"用":{"docs":{},"的":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"打":{"docs":{},"开":{"docs":{},"它":{"docs":{},",":{"docs":{},"输":{"docs":{},"入":{"docs":{},"下":{"docs":{},"面":{"docs":{},"这":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"它":{"docs":{},"就":{"docs":{},"像":{"docs":{},"个":{"docs":{},"清":{"docs":{},"单":{"docs":{},",":{"docs":{},"告":{"docs":{},"诉":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}},"”":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},")":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"m":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},",":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}},"u":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"r":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"o":{"docs":{},"p":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}},"p":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}},"a":{"docs":{},"w":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"u":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.010810810810810811},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}},"e":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.02631578947368421}},"o":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.03508771929824561},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},".":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.008177570093457943},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"s":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"s":{"docs":{},"t":{"docs":{},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"r":{"docs":{},"l":{"docs":{},"i":{"docs":{},"e":{"docs":{},"r":{"docs":{},":":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"c":{"2":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"docs":{},"o":{"docs":{},"s":{"docs":{},"y":{"docs":{},"s":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},"f":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.02727272727272727},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}},"f":{"docs":{},"i":{"docs":{},"c":{"docs":{},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"y":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"\"":{"docs":{},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},",":{"docs":{},"请":{"docs":{},"确":{"docs":{},"保":{"docs":{},"在":{"docs":{},"正":{"docs":{},"确":{"docs":{},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}},"l":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616}},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"s":{"docs":{},"e":{"docs":{},"!":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"w":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}},"'":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"n":{"docs":{},"c":{"docs":{},"o":{"docs":{},"u":{"docs":{},"r":{"docs":{},"a":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"r":{"docs":{},"y":{"docs":{},"p":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"o":{"docs":{},"u":{"docs":{},"g":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"t":{"docs":{},"i":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"t":{"docs":{},"i":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.030927835051546393},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.03496503496503497},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.013157894736842105},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.02527075812274368},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.0625},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},"y":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"r":{"docs":{},"i":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"y":{"docs":{},"p":{"docs":{},"o":{"docs":{},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}}}}}}}}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"v":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.004248088360237893}},"i":{"docs":{},"r":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},":":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}},"s":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"e":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"y":{"docs":{},"t":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"'":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"o":{"docs":{},"n":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.007751937984496124}},"e":{"docs":{},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"w":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"u":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"x":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}},"a":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"i":{"docs":{},"n":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"c":{"docs":{},"t":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"e":{"docs":{},"c":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}},"r":{"docs":{},"c":{"docs":{},"i":{"docs":{},"s":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"p":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"t":{"docs":{},"!":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}}}}},"l":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}},"e":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"i":{"docs":{},"c":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"l":{"docs":{},"i":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}},"r":{"docs":{},"n":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"r":{"docs":{},"a":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"e":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"s":{"docs":{},"t":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.013157894736842105},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"o":{"docs":{},"t":{"docs":{},"i":{"docs":{},"c":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.016042780748663103},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"s":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},",":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"b":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},",":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},"a":{"docs":{},"s":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"m":{"docs":{},"p":{"docs":{},"t":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"i":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"a":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"/":{"docs":{},"p":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}},"p":{"docs":{},"e":{"docs":{},"c":{"docs":{},"i":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"q":{"docs":{},"u":{"docs":{},"i":{"docs":{},"v":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"a":{"docs":{},"l":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"t":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"f":{"1":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556}}},"5":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525}}},"docs":{},"#":{"docs":{},")":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"a":{"docs":{},"m":{"docs":{},"i":{"docs":{},"l":{"docs":{},"i":{"docs":{},"a":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"n":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"s":{"docs":{},"t":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"v":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}},"l":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},"。":{"docs":{},"你":{"docs":{},"后":{"docs":{},"面":{"docs":{},"会":{"docs":{},"编":{"docs":{},"写":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"在":{"docs":{},"用":{"docs":{},"户":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"里":{"docs":{},"点":{"docs":{},"击":{"docs":{},"某":{"docs":{},"个":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"时":{"docs":{},",":{"docs":{},"修":{"docs":{},"改":{"docs":{},"这":{"docs":{},"个":{"docs":{},"属":{"docs":{},"性":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"如":{"docs":{},"果":{"docs":{},"该":{"docs":{},"操":{"docs":{},"作":{"docs":{},"因":{"docs":{},"为":{"docs":{},"某":{"docs":{},"些":{"docs":{},"原":{"docs":{},"因":{"docs":{},"失":{"docs":{},"败":{"docs":{},"了":{"docs":{},",":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}}},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"k":{"docs":{},"e":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646}},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"因":{"docs":{},"为":{"docs":{},"服":{"docs":{},"务":{"docs":{},"是":{"docs":{},"从":{"docs":{},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"里":{"docs":{},"“":{"docs":{},"注":{"docs":{},"入":{"docs":{},"(":{"docs":{},"i":{"docs":{},"n":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},")":{"docs":{},"”":{"docs":{},"的":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"模":{"docs":{},"式":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"是":{"docs":{},"其":{"docs":{},"它":{"docs":{},"读":{"docs":{},"写":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"类":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"别":{"docs":{},"的":{"docs":{},"什":{"docs":{},"么":{"docs":{},"类":{"docs":{},"。":{"docs":{},"只":{"docs":{},"要":{"docs":{},"它":{"docs":{},"符":{"docs":{},"合":{"docs":{},"该":{"docs":{},"接":{"docs":{},"口":{"docs":{},"的":{"docs":{},"要":{"docs":{},"求":{"docs":{},",":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"就":{"docs":{},"能":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{},"这":{"docs":{},"使":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"轻":{"docs":{},"而":{"docs":{},"易":{"docs":{},"举":{"docs":{},"地":{"docs":{},",":{"docs":{},"独":{"docs":{},"立":{"docs":{},"测":{"docs":{},"试":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"各":{"docs":{},"部":{"docs":{},"分":{"docs":{},"。":{"docs":{},"(":{"docs":{},"我":{"docs":{},"会":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"硬":{"docs":{},"编":{"docs":{},"码":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}},".":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"s":{"docs":{},",":{"docs":{},"并":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"文":{"docs":{},"件":{"docs":{},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}},"i":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"d":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},"c":{"docs":{},"e":{"docs":{},"b":{"docs":{},"o":{"docs":{},"o":{"docs":{},"k":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"o":{"docs":{},"r":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"r":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.0625},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}},"e":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},"w":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"d":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}},"e":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"d":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"s":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"x":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.012958963282937365}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"d":{"docs":{},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},".":{"docs":{},"c":{"docs":{},"l":{"docs":{},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}},"r":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},":":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}},"l":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.01483679525222552},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.012962962962962963},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}},"s":{"docs":{},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},")":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}},"e":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"o":{"docs":{},"c":{"docs":{},"u":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"s":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"r":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075}}}}},"o":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"m":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0110803324099723},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.008177570093457943},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"a":{"docs":{},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},".":{"docs":{"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"s":{"docs":{},"u":{"docs":{},"b":{"docs":{},"m":{"docs":{},"i":{"docs":{},"t":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"'":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"e":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}},"t":{"docs":{},"u":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}},"=":{"docs":{},"\"":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},"\"":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},",":{"docs":{},"让":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"c":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"w":{"docs":{},"a":{"docs":{},"r":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},")":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"r":{"docs":{},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.007067137809187279},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.012195121951219513},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.041237113402061855},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.03496503496503497},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.02527075812274368},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.0625},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}},")":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"e":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"l":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"m":{"docs":{},"=":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}},"u":{"docs":{},"n":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025}},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},".":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}},"(":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"l":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"e":{"docs":{},"l":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"l":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"v":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"e":{"docs":{},"x":{"docs":{},"i":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"d":{"docs":{},"g":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"o":{"docs":{},"w":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"g":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.011111111111111112}},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{},"或":{"docs":{},"者":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"n":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.01744186046511628},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},";":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.021621621621621623},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}}},"i":{"docs":{},"n":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}},"(":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.005970149253731343}},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},";":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},",":{"docs":{},"就":{"docs":{},"该":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.014124293785310734},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.05}},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"'":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}}}}}}},"(":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"v":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"n":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"l":{"docs":{},"o":{"docs":{},"b":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"a":{"docs":{},"x":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"o":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"o":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"?":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"g":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}}},"!":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"n":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}},"e":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"e":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.009259259259259259}},")":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"a":{"docs":{},"b":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"p":{"docs":{},"h":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},")":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"a":{"docs":{},"t":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}},"m":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"u":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"s":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"g":{"docs":{},"u":{"docs":{},"i":{"docs":{},"d":{"docs":{},")":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"由":{"docs":{},"字":{"docs":{},"母":{"docs":{},"和":{"docs":{},"数":{"docs":{},"字":{"docs":{},"组":{"docs":{},"成":{"docs":{},"的":{"docs":{},"长":{"docs":{},"长":{"docs":{},"的":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},",":{"docs":{},"看":{"docs":{},"起":{"docs":{},"来":{"docs":{},"是":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"是":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"则":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"g":{"docs":{},"u":{"docs":{},"i":{"docs":{},"d":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}},"e":{"docs":{},"m":{"docs":{},"p":{"docs":{},"t":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"这":{"docs":{},"种":{"docs":{},"情":{"docs":{},"况":{"docs":{},"发":{"docs":{},"生":{"docs":{},",":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"这":{"docs":{},"项":{"docs":{},"功":{"docs":{},"能":{"docs":{},"得":{"docs":{},"益":{"docs":{},"于":{"docs":{},"你":{"docs":{},"在":{"docs":{},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"加":{"docs":{},"入":{"docs":{},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"t":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"h":{"docs":{},"a":{"docs":{},"l":{"docs":{},"f":{"docs":{},"w":{"docs":{},"a":{"docs":{},"y":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"n":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.015228426395939087},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"、":{"docs":{},"p":{"docs":{},"u":{"docs":{},"g":{"docs":{},"、":{"docs":{},"r":{"docs":{},"a":{"docs":{},"z":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"r":{"docs":{},"d":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"v":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"s":{"docs":{},"h":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"c":{"docs":{},"k":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}},"p":{"docs":{},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"s":{"docs":{},"!":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"e":{"docs":{},"a":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"l":{"docs":{},"p":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.040697674418604654},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},"。":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"被":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"参":{"docs":{},"考":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"l":{"docs":{},"o":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":2.5178041543026706},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}},"\"":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"r":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"'":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"y":{"docs":{},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"o":{"docs":{},"m":{"docs":{},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.01744186046511628},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"你":{"docs":{},"访":{"docs":{},"问":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}},"l":{"docs":{},"d":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"o":{"docs":{},"d":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}},"s":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01818181818181818},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"r":{"docs":{},"u":{"docs":{},"n":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"c":{"docs":{},"o":{"docs":{},"p":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"w":{"docs":{},"e":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"p":{"docs":{},"e":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"m":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"e":{"docs":{},"s":{"docs":{},"/":{"docs":{},"b":{"docs":{},"y":{"docs":{},"/":{"4":{"docs":{},".":{"0":{"docs":{},"/":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"docs":{}}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"w":{"docs":{},"w":{"docs":{},"w":{"docs":{},".":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"u":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},".":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},")":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"网":{"docs":{},"页":{"docs":{},"上":{"docs":{},"检":{"docs":{},"索":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},")":{"docs":{},"有":{"docs":{},"几":{"docs":{},"个":{"docs":{},"示":{"docs":{},"例":{"docs":{},"可":{"docs":{},"以":{"docs":{},"参":{"docs":{},"考":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"有":{"docs":{},"关":{"docs":{},"这":{"docs":{},"些":{"docs":{},"主":{"docs":{},"题":{"docs":{},"的":{"docs":{},",":{"docs":{},"深":{"docs":{},"入":{"docs":{},"详":{"docs":{},"尽":{"docs":{},"的":{"docs":{},"教":{"docs":{},"程":{"docs":{},"。":{"docs":{},"本":{"docs":{},"人":{"docs":{},"强":{"docs":{},"烈":{"docs":{},"推":{"docs":{},"荐":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"n":{"docs":{},".":{"docs":{},"w":{"docs":{},"i":{"docs":{},"k":{"docs":{},"i":{"docs":{},"p":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"a":{"docs":{},".":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},"/":{"docs":{},"w":{"docs":{},"i":{"docs":{},"k":{"docs":{},"i":{"docs":{},"/":{"docs":{},"f":{"docs":{},"u":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"_":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{},"_":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"m":{"docs":{},"i":{"docs":{},"s":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"/":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}}}}}},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"/":{"docs":{},"a":{"docs":{},"n":{"docs":{},"n":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},"/":{"docs":{},"i":{"docs":{},"s":{"docs":{},"s":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"/":{"2":{"9":{"5":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"@":{"docs":{},"m":{"docs":{},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},".":{"docs":{},"s":{"docs":{},"c":{"docs":{},"m":{"docs":{},".":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"/":{"docs":{},"m":{"docs":{},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},".":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}},"(":{"docs":{},"t":{"docs":{},"l":{"docs":{},"s":{"docs":{},")":{"docs":{},",":{"docs":{},"避":{"docs":{},"免":{"docs":{},"在":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},",":{"docs":{},"只":{"docs":{},"需":{"docs":{},"寥":{"docs":{},"寥":{"docs":{},"数":{"docs":{},"行":{"docs":{},"代":{"docs":{},"码":{"docs":{},"即":{"docs":{},"可":{"docs":{},"。":{"docs":{},"本":{"docs":{},"章":{"docs":{},"主":{"docs":{},"要":{"docs":{},"关":{"docs":{},"注":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},"的":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"a":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{},"c":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},".":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},":":{"5":{"0":{"0":{"0":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"。":{"docs":{},"你":{"docs":{},"将":{"docs":{},"看":{"docs":{},"到":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"/":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}},",":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},".":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},",":{"docs":{},"但":{"docs":{},"如":{"docs":{},"果":{"docs":{},"导":{"docs":{},"航":{"docs":{},"栏":{"docs":{},"上":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}},"。":{"docs":{},"硬":{"docs":{},"编":{"docs":{},"码":{"docs":{},"的":{"docs":{},"那":{"docs":{},"些":{"docs":{},"条":{"docs":{},"目":{"docs":{},"不":{"docs":{},"见":{"docs":{},"了":{"docs":{},",":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"对":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"发":{"docs":{},"起":{"docs":{},"了":{"docs":{},"真":{"docs":{},"正":{"docs":{},"的":{"docs":{},"查":{"docs":{},"询":{"docs":{},"。":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"刚":{"docs":{},"好":{"docs":{},"还":{"docs":{},"没":{"docs":{},"有":{"docs":{},"任":{"docs":{},"何":{"docs":{},"已":{"docs":{},"存":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"8":{"0":{"8":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}},"(":{"docs":{},"不":{"docs":{},"是":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}},"m":{"docs":{},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},".":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"r":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{},".":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"+":{"docs":{},":":{"8":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}},"docs":{}},"docs":{}}},"k":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"e":{"docs":{},"l":{"docs":{},":":{"8":{"0":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"。":{"docs":{},"(":{"docs":{},"你":{"docs":{},"马":{"docs":{},"上":{"docs":{},"就":{"docs":{},"会":{"docs":{},"知":{"docs":{},"道":{"docs":{},"为":{"docs":{},"什":{"docs":{},"么":{"docs":{},"要":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}},"docs":{}},"docs":{}}}}}}}}}}}},"c":{"docs":{},"l":{"docs":{},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}}}}}}},"m":{"docs":{},"e":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"d":{"docs":{},".":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"m":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"(":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.029069767441860465},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},"(":{"docs":{},"\"":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}}}}}}}}}}}}},"_":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"\"":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}},"l":{"docs":{},"o":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"\"":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"这":{"docs":{},"些":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},",":{"docs":{},"偶":{"docs":{},"尔":{"docs":{},"掺":{"docs":{},"杂":{"docs":{},"一":{"docs":{},"点":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"g":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.04419889502762431}},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"r":{"docs":{},"'":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}},"s":{"docs":{},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"r":{"docs":{},"e":{"docs":{},"f":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186}}}}},"i":{"docs":{},"b":{"docs":{},"e":{"docs":{},"r":{"docs":{},"n":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464}}}}}},"s":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}},"d":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616}}}}}},"g":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"l":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"i":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01038961038961039},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"d":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"m":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.009009009009009009},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.015186915887850467},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}},"e":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.028409090909090908},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.07614213197969544}},"i":{"docs":{},"f":{"docs":{},"i":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"t":{"docs":{},"y":{"docs":{},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403}}}}}}}}}}},",":{"docs":{},"为":{"docs":{},"项":{"docs":{},"目":{"docs":{},"添":{"docs":{},"加":{"docs":{},"安":{"docs":{},"全":{"docs":{},"及":{"docs":{},"认":{"docs":{},"证":{"docs":{},"等":{"docs":{},"特":{"docs":{},"性":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}},"?":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},"(":{"docs":{},"一":{"docs":{},"个":{"docs":{},"验":{"docs":{},"证":{"docs":{},"和":{"docs":{},"身":{"docs":{},"份":{"docs":{},"系":{"docs":{},"统":{"docs":{},",":{"docs":{},"属":{"docs":{},"于":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"(":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}},":":{"docs":{},"你":{"docs":{},"免":{"docs":{},"费":{"docs":{},"获":{"docs":{},"得":{"docs":{},"随":{"docs":{},"模":{"docs":{},"板":{"docs":{},"而":{"docs":{},"来":{"docs":{},"的":{"docs":{},"大":{"docs":{},"量":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"易":{"docs":{},"于":{"docs":{},"上":{"docs":{},"手":{"docs":{},"。":{"docs":{},"对":{"docs":{},"于":{"docs":{},"进":{"docs":{},"阶":{"docs":{},"的":{"docs":{},"情":{"docs":{},"形":{"docs":{},",":{"docs":{},"你":{"docs":{},"依":{"docs":{},"然":{"docs":{},"需":{"docs":{},"要":{"docs":{},"写":{"docs":{},"一":{"docs":{},"部":{"docs":{},"分":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"并":{"docs":{},"维":{"docs":{},"护":{"docs":{},"一":{"docs":{},"个":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"以":{"docs":{},"存":{"docs":{},"储":{"docs":{},"用":{"docs":{},"户":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453}}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"、":{"docs":{},"一":{"docs":{},"个":{"docs":{},"标":{"docs":{},"题":{"docs":{},"或":{"docs":{},"者":{"docs":{},"名":{"docs":{},"称":{"docs":{},"、":{"docs":{},"该":{"docs":{},"事":{"docs":{},"项":{"docs":{},"是":{"docs":{},"否":{"docs":{},"已":{"docs":{},"经":{"docs":{},"完":{"docs":{},"成":{"docs":{},",":{"docs":{},"以":{"docs":{},"及":{"docs":{},"截":{"docs":{},"至":{"docs":{},"日":{"docs":{},"期":{"docs":{},"是":{"docs":{},"什":{"docs":{},"么":{"docs":{},"时":{"docs":{},"候":{"docs":{},"。":{"docs":{},"每":{"docs":{},"行":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"这":{"docs":{},"个":{"docs":{},"类":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"属":{"docs":{},"性":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"以":{"docs":{},"便":{"docs":{},"你":{"docs":{},"的":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"代":{"docs":{},"码":{"docs":{},"辨":{"docs":{},"别":{"docs":{},"是":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"被":{"docs":{},"选":{"docs":{},"中":{"docs":{},"了":{"docs":{},"。":{"docs":{},"(":{"docs":{},"如":{"docs":{},"果":{"docs":{},"没":{"docs":{},"有":{"docs":{},"它":{"docs":{},",":{"docs":{},"你":{"docs":{},"只":{"docs":{},"能":{"docs":{},"知":{"docs":{},"道":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"防":{"docs":{},"止":{"docs":{},"恶":{"docs":{},"意":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},"通":{"docs":{},"过":{"docs":{},"猜":{"docs":{},"测":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"i":{"docs":{},"s":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}},"i":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}},"o":{"docs":{},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{},"!":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"v":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0064794816414686825}},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}}}}}},"a":{"docs":{},"g":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.012744265080713678}},"i":{"docs":{},"n":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},"e":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"f":{"docs":{},"o":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.03076923076923077}},"r":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}},"p":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}},"e":{"docs":{},"d":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"n":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}},"r":{"docs":{},"u":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"i":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"e":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"p":{"docs":{},"i":{"docs":{},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"r":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"f":{"docs":{},"a":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0113314447592068},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"p":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"e":{"docs":{},"r":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"n":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"m":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},"作":{"docs":{},"为":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"记":{"docs":{},"录":{"docs":{},"的":{"docs":{},"标":{"docs":{},"识":{"docs":{},",":{"docs":{},"但":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"配":{"docs":{},"置":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"这":{"docs":{},"个":{"docs":{},"数":{"docs":{},"字":{"docs":{},"在":{"docs":{},"添":{"docs":{},"加":{"docs":{},"新":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},"始":{"docs":{},"终":{"docs":{},"增":{"docs":{},"长":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.015523932729624839}}}},"l":{"docs":{},"l":{"docs":{},"i":{"docs":{},"g":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"r":{"docs":{},"o":{"docs":{},"d":{"docs":{},"u":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"t":{"docs":{"./":{"ref":"./","tf":10.000883392226148}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"c":{"docs":{},"l":{"docs":{},"u":{"docs":{},"d":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"o":{"docs":{},"m":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}},"d":{"docs":{},"i":{"docs":{},"v":{"docs":{},"i":{"docs":{},"d":{"docs":{},"u":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}},"a":{"docs":{},"l":{"docs":{},"认":{"docs":{},"证":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"验":{"docs":{},"证":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}}}}}}}},"c":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"e":{"docs":{},"x":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"(":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.008241758241758242},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}},"i":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"v":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}},"o":{"docs":{},"l":{"docs":{},"v":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},")":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"s":{"docs":{},")":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"b":{"docs":{},"n":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},":":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.010810810810810811},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"o":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558}},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"s":{"docs":{},"u":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"?":{"docs":{},"\"":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"v":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{},"在":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"u":{"docs":{},"p":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"(":{"docs":{},")":{"docs":{},"方":{"docs":{},"法":{"docs":{},"中":{"docs":{},"设":{"docs":{},"置":{"docs":{},"过":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"集":{"docs":{},"合":{"docs":{},")":{"docs":{},"从":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"t":{"docs":{},"'":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01038961038961039},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"l":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}}}},"d":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"s":{"docs":{},"e":{"docs":{},"l":{"docs":{},"f":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},")":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"!":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"e":{"docs":{},"m":{"1":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}},"2":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034}}},"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.016867469879518072},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.01510989010989011},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.04285714285714286},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.02631578947368421},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.012727272727272728},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.023465703971119134},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.009233610341643583},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.017523364485981307},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01791044776119403},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.011226252158894647}},"'":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075}},"\"":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}},"i":{"docs":{},"s":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682}},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}},"d":{"docs":{},"u":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},",":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}},",":{"docs":{},"直":{"docs":{},"接":{"docs":{},"返":{"docs":{},"回":{"docs":{},"查":{"docs":{},"询":{"docs":{},"结":{"docs":{},"果":{"docs":{},"(":{"docs":{},"跟":{"docs":{},"原":{"docs":{},"来":{"docs":{},"功":{"docs":{},"能":{"docs":{},"一":{"docs":{},"样":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.023351648351648352},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.009025270758122744},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.008955223880597015},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"l":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{},"f":{"docs":{},"i":{"docs":{},"x":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"o":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},",":{"docs":{},"并":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.008177570093457943}},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}},"d":{"docs":{},"e":{"docs":{},"、":{"docs":{},"p":{"docs":{},"u":{"docs":{},"g":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"y":{"docs":{},",":{"docs":{},"便":{"docs":{},"于":{"docs":{},"你":{"docs":{},"快":{"docs":{},"捷":{"docs":{},"地":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}},"(":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"u":{"docs":{},"g":{"docs":{},"g":{"docs":{},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"o":{"docs":{},"b":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"e":{"docs":{},"n":{"docs":{},"n":{"docs":{},"i":{"docs":{},"f":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},",":{"docs":{},"她":{"docs":{},"总":{"docs":{},"是":{"docs":{},"支":{"docs":{},"持":{"docs":{},"我":{"docs":{},"各":{"docs":{},"种":{"docs":{},"疯":{"docs":{},"狂":{"docs":{},"的":{"docs":{},"点":{"docs":{},"子":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}},"k":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395}}}}}}},"i":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"ı":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}},"n":{"docs":{},"o":{"docs":{},"w":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}},"n":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"l":{"docs":{},"e":{"docs":{},"d":{"docs":{},"g":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}},"e":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"e":{"docs":{},"p":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"y":{"docs":{},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"!":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.02077922077922078},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}}},"。":{"docs":{},"但":{"docs":{},"强":{"docs":{},"烈":{"docs":{},"建":{"docs":{},"议":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}},"这":{"docs":{},"两":{"docs":{},"个":{"docs":{},"容":{"docs":{},"器":{"docs":{},"显":{"docs":{},"式":{"docs":{},"地":{"docs":{},"链":{"docs":{},"接":{"docs":{},"在":{"docs":{},"一":{"docs":{},"起":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"它":{"docs":{},"们":{"docs":{},"可":{"docs":{},"以":{"docs":{},"互":{"docs":{},"相":{"docs":{},"通":{"docs":{},"信":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"k":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}}}}},"l":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"u":{"docs":{},"a":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"e":{"docs":{},"s":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}},"r":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"l":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"g":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}},")":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"s":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.00963855421686747},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"s":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"e":{"docs":{},"a":{"docs":{},"r":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.017278617710583154}},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"g":{"docs":{},"a":{"docs":{},"c":{"docs":{},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"'":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"v":{"docs":{},"e":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"f":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"s":{"docs":{},"s":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"i":{"docs":{},"b":{"docs":{},"r":{"docs":{},"a":{"docs":{},"r":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}},"y":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"c":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"n":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"s":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}}}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"u":{"docs":{},"x":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.015584415584415584},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},".":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"(":{"docs":{},"和":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}},"e":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.03076923076923077},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"s":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"q":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"(":{"docs":{},"l":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"u":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.00530035335689046},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.01079913606911447}}}}},"s":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.004248088360237893}}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}},"\"":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{},"b":{"docs":{},"u":{"docs":{},"l":{"docs":{},"b":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}}}}}},"w":{"docs":{},"e":{"docs":{},"i":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"v":{"docs":{},"e":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"m":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}},"f":{"docs":{},"e":{"docs":{},"c":{"docs":{},"y":{"docs":{},"c":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}},"e":{"docs":{},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"s":{"docs":{},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"o":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.03759398496240601},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.008522727272727272},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},".":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.009915014164305949},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.006044905008635579}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"g":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},".":{"docs":{},"l":{"docs":{},"o":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"r":{"docs":{},"(":{"docs":{},"e":{"docs":{},"x":{"docs":{},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"o":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"p":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"l":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.011111111111111112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},":":{"5":{"0":{"0":{"0":{"docs":{},"/":{"docs":{},"h":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}},"e":{"docs":{},"/":{"docs":{},"a":{"docs":{},"b":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}}}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625}}}}}}}}}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}}}}}}},"k":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"a":{"docs":{},"d":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"w":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"v":{"docs":{},"e":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"u":{"docs":{},"c":{"docs":{},"k":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"s":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}},"m":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"a":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"h":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"e":{"docs":{},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}},"k":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.015463917525773196},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"e":{"docs":{},"r":{"docs":{},";":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674}}}}}}}}}}}}}}}}}}},"i":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"t":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}},"u":{"docs":{},"r":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"v":{"docs":{},"e":{"docs":{},"n":{"docs":{},")":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},")":{"docs":{},"上":{"docs":{},"有":{"docs":{},"成":{"docs":{},"千":{"docs":{},"上":{"docs":{},"万":{"docs":{},"的":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"。":{"docs":{},"有":{"docs":{},"现":{"docs":{},"成":{"docs":{},"的":{"docs":{},"包":{"docs":{},"可":{"docs":{},"用":{"docs":{},"来":{"docs":{},"完":{"docs":{},"成":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"(":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"[":{"docs":{},"]":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"l":{"docs":{},"i":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"t":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}}}}}}}},"r":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"k":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.007207207207207207},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103}}},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"c":{"docs":{},"k":{"docs":{},"b":{"docs":{},"o":{"docs":{},"x":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}},"e":{"docs":{},".":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717}},"e":{"docs":{},"(":{"docs":{},"g":{"docs":{},"u":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},"(":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},"g":{"docs":{},"u":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}},"p":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"p":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},")":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}},"d":{"docs":{},"e":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"s":{"docs":{},"s":{"docs":{},"i":{"docs":{},"v":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}},"g":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"i":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"j":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"s":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"u":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"t":{"docs":{},"a":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}},"h":{"docs":{},"o":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.01098901098901099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.006965174129353234},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.009499136442141624}},"s":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"'":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"s":{"docs":{},"s":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"e":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"m":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}}},"y":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"i":{"docs":{},"c":{"docs":{},"r":{"docs":{},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"o":{"docs":{},"f":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"'":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},".":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}},"a":{"docs":{},"l":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"z":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},";":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}}}},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},"f":{"docs":{},"r":{"docs":{},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"k":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}},"x":{"docs":{},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{},"d":{"docs":{},"e":{"docs":{},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"y":{"docs":{},"i":{"docs":{},"n":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}}}}}}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}},"/":{"docs":{},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},":":{"2":{"docs":{},".":{"0":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.008496176720475786}}},"docs":{}}},"docs":{}}}}}}}}}}}}}}}},"d":{"docs":{},"d":{"docs":{},"l":{"docs":{},"e":{"docs":{},"w":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"n":{"docs":{},"i":{"docs":{},"f":{"docs":{},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"u":{"docs":{},"t":{"docs":{},"e":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"s":{"docs":{},"s":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384}}},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.03272727272727273},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"k":{"docs":{},"e":{"docs":{},"y":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},"(":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}},"d":{"docs":{},"r":{"docs":{},"o":{"docs":{},"p":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"k":{"docs":{},"e":{"docs":{},"y":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},"(":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}},"r":{"docs":{},"r":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"l":{"docs":{},"l":{"docs":{},"i":{"docs":{},"s":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"r":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.01875},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.023423423423423424},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.014457831325301205},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.01098901098901099},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.014285714285714285},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.014773776546629732},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"、":{"docs":{},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"s":{"docs":{},",":{"docs":{},"和":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}},"/":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"(":{"docs":{},"模":{"docs":{},"型":{"docs":{},"核":{"docs":{},"验":{"docs":{},"的":{"docs":{},"结":{"docs":{},"果":{"docs":{},")":{"docs":{},"是":{"docs":{},"否":{"docs":{},"有":{"docs":{},"效":{"docs":{},"。":{"docs":{},"习":{"docs":{},"惯":{"docs":{},"上":{"docs":{},",":{"docs":{},"这":{"docs":{},"种":{"docs":{},"核":{"docs":{},"验":{"docs":{},"都":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"取":{"docs":{},"而":{"docs":{},"代":{"docs":{},"之":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"直":{"docs":{},"接":{"docs":{},"检":{"docs":{},"查":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"s":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}},"e":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"y":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"u":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}},"i":{"docs":{},"f":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"r":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.0625},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.02030456852791878},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.01079913606911447}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"v":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}},"b":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"n":{"docs":{},"g":{"docs":{},"o":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},"d":{"docs":{},"b":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},".":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"u":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},",":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}},"c":{"docs":{},"k":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"u":{"docs":{},"c":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"l":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"u":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"t":{"docs":{},"h":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"p":{"docs":{},"l":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"v":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"c":{"docs":{"./":{"ref":"./","tf":0.00530035335689046},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":5.054878048780488},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756}}},"、":{"docs":{},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"板":{"docs":{},"和":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"。":{"docs":{},"你":{"docs":{},"将":{"docs":{},"使":{"docs":{},"用":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}},"(":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"模":{"docs":{},"型":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},",":{"docs":{},"那":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"基":{"docs":{},"础":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}},")":{"docs":{},"发":{"docs":{},"送":{"docs":{},"到":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{},"他":{"docs":{},"们":{"docs":{},"都":{"docs":{},"可":{"docs":{},"以":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{},"模":{"docs":{},"型":{"docs":{},",":{"docs":{},"我":{"docs":{},"将":{"docs":{},"称":{"docs":{},"后":{"docs":{},"者":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"k":{"docs":{},"d":{"docs":{},"i":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"y":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},",":{"docs":{},"就":{"docs":{},"不":{"docs":{},"需":{"docs":{},"要":{"docs":{},"这":{"docs":{},"样":{"docs":{},"(":{"docs":{},"有":{"docs":{},"点":{"docs":{},"旁":{"docs":{},"门":{"docs":{},"左":{"docs":{},"道":{"docs":{},"的":{"docs":{},")":{"docs":{},"绕":{"docs":{},"弯":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}},")":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"n":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.014814814814814815}},"a":{"docs":{},"m":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}},"s":{"docs":{},"p":{"docs":{},"a":{"docs":{},"c":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.007207207207207207},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.012747875354107648},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"t":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"'":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"@":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}}}}}}}}}}},"!":{"docs":{},"我":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"漫":{"docs":{},"长":{"docs":{},"的":{"docs":{},"灌":{"docs":{},"着":{"docs":{},"咖":{"docs":{},"啡":{"docs":{},"的":{"docs":{},"周":{"docs":{},"末":{"docs":{},"写":{"docs":{},"了":{"docs":{},"这":{"docs":{},"本":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"v":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"v":{"docs":{},"i":{"docs":{},"g":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},".":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},",":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186}}}}}}}},"e":{"docs":{},"e":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.026737967914438502},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.010810810810810811},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.01048951048951049},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"s":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"w":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.03560830860534125},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.015536723163841809},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.01524390243902439},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.017482517482517484},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.00909090909090909},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.009025270758122744},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.013850415512465374},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.010945273631840797},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.010077519379844961},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.02072538860103627},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.018111254851228976},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},"e":{"docs":{},"r":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}},".":{"docs":{},"d":{"docs":{},"u":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},"s":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{},",":{"docs":{},"仅":{"docs":{},"用":{"docs":{},"于":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"x":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"2":{"docs":{},".":{"0":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}}},"docs":{}}},"docs":{}}}}}}}},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"a":{"docs":{},"r":{"docs":{},"i":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"y":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"i":{"docs":{},"n":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"。":{"docs":{},"整":{"docs":{},"个":{"docs":{},"框":{"docs":{},"架":{"docs":{},"已":{"docs":{},"经":{"docs":{},"针":{"docs":{},"对":{"docs":{},"速":{"docs":{},"度":{"docs":{},"和":{"docs":{},"运":{"docs":{},"行":{"docs":{},"时":{"docs":{},"效":{"docs":{},"率":{"docs":{},"进":{"docs":{},"行":{"docs":{},"了":{"docs":{},"优":{"docs":{},"化":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"c":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"r":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{},"j":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"/":{"docs":{},"e":{"docs":{},"x":{"docs":{},"p":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"、":{"docs":{},"p":{"docs":{},"y":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"n":{"docs":{},"、":{"docs":{},"r":{"docs":{},"u":{"docs":{},"b":{"docs":{},"y":{"docs":{},"、":{"docs":{},"g":{"docs":{},"o":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"p":{"docs":{},"a":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},"i":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"h":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},")":{"docs":{},",":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"w":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}},"\"":{"docs":{},"?":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"(":{"docs":{},"文":{"docs":{},"档":{"docs":{},")":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"n":{"docs":{},"e":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"p":{"docs":{},"m":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"、":{"docs":{},"r":{"docs":{},"u":{"docs":{},"b":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},")":{"docs":{},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}},"u":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.03314917127071823},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"(":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"m":{"docs":{},"b":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"l":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406}}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},"—":{"docs":{},"—":{"docs":{},"如":{"docs":{},"果":{"docs":{},"找":{"docs":{},"不":{"docs":{},"到":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},",":{"docs":{},"设":{"docs":{},"置":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"。":{"docs":{},"无":{"docs":{},"论":{"docs":{},"如":{"docs":{},"何":{"docs":{},",":{"docs":{},"做":{"docs":{},"个":{"docs":{},"明":{"docs":{},"智":{"docs":{},"的":{"docs":{},"检":{"docs":{},"查":{"docs":{},"都":{"docs":{},"没":{"docs":{},"错":{"docs":{},",":{"docs":{},"以":{"docs":{},"防":{"docs":{},"万":{"docs":{},"一":{"docs":{},"嘛":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"用":{"docs":{},"户":{"docs":{},"信":{"docs":{},"息":{"docs":{},"没":{"docs":{},"找":{"docs":{},"到":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"级":{"docs":{},"架":{"docs":{},"构":{"docs":{},"。":{"docs":{},"在":{"docs":{},"某":{"docs":{},"些":{"docs":{},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"层":{"docs":{},"级":{"docs":{},"被":{"docs":{},"隔":{"docs":{},"离":{"docs":{},"在":{"docs":{},"完":{"docs":{},"全":{"docs":{},"分":{"docs":{},"离":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},",":{"docs":{},"也":{"docs":{},"有":{"docs":{},"时":{"docs":{},"候":{"docs":{},"这":{"docs":{},"仅":{"docs":{},"仅":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},"各":{"docs":{},"个":{"docs":{},"类":{"docs":{},"之":{"docs":{},"间":{"docs":{},"组":{"docs":{},"织":{"docs":{},"和":{"docs":{},"调":{"docs":{},"用":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"。":{"docs":{},"重":{"docs":{},"点":{"docs":{},"在":{"docs":{},"于":{"docs":{},"考":{"docs":{},"量":{"docs":{},"如":{"docs":{},"何":{"docs":{},"把":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"分":{"docs":{},"割":{"docs":{},"成":{"docs":{},"多":{"docs":{},"个":{"docs":{},"可":{"docs":{},"管":{"docs":{},"理":{"docs":{},"的":{"docs":{},"部":{"docs":{},"分":{"docs":{},",":{"docs":{},"以":{"docs":{},"避":{"docs":{},"免":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"或":{"docs":{},"者":{"docs":{},"某":{"docs":{},"些":{"docs":{},"臃":{"docs":{},"肿":{"docs":{},"的":{"docs":{},"类":{"docs":{},"试":{"docs":{},"图":{"docs":{},"去":{"docs":{},"处":{"docs":{},"理":{"docs":{},"所":{"docs":{},"有":{"docs":{},"事":{"docs":{},"情":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.02077922077922078},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.013593882752761258}},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}},"/":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}},"n":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},",":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"o":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"c":{"docs":{},"c":{"docs":{},"a":{"docs":{},"s":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"u":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"f":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"f":{"docs":{},"i":{"docs":{},"c":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}}}},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"l":{"docs":{},"y":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"c":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"e":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"(":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403}}}}}}}}}}}}}}}}}}}}}}}}}}},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}}},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"o":{"docs":{},"n":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"s":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},".":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"(":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}}}}}}}}}}}}},")":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806}}}},"a":{"docs":{},"l":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}},"r":{"docs":{},"i":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"g":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"m":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},"s":{"docs":{},".":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}},"。":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"由":{"docs":{},"微":{"docs":{},"软":{"docs":{},"开":{"docs":{},"发":{"docs":{},",":{"docs":{},"并":{"docs":{},"默":{"docs":{},"认":{"docs":{},"包":{"docs":{},"含":{"docs":{},"在":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}},"p":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"r":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}}}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"f":{"docs":{},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"a":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"w":{"docs":{},"i":{"docs":{},"n":{"docs":{},"/":{"docs":{},"k":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}}}}}},"n":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"s":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.046153846153846156}}},"b":{"docs":{},"j":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"\"":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},")":{"docs":{},"”":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"'":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},")":{"docs":{},"(":{"docs":{},"d":{"docs":{},"t":{"docs":{},"o":{"docs":{},")":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"模":{"docs":{},"式":{"docs":{},"常":{"docs":{},"见":{"docs":{},"于":{"docs":{},"更":{"docs":{},"大":{"docs":{},"更":{"docs":{},"复":{"docs":{},"杂":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"v":{"docs":{},"i":{"docs":{},"o":{"docs":{},"u":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}},"k":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},"和":{"4":{"0":{"4":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"docs":{}},"docs":{}},"docs":{}},"t":{"docs":{},"a":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}}}}},"l":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"a":{"docs":{},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}}}}},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{},"a":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.049723756906077346},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},".":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}},")":{"docs":{},",":{"docs":{},"你":{"docs":{},"不":{"docs":{},"需":{"docs":{},"要":{"docs":{},"经":{"docs":{},"常":{"docs":{},"手":{"docs":{},"动":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"这":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"。":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"r":{"docs":{},"e":{"docs":{},"f":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},",":{"docs":{},"引":{"docs":{},"用":{"docs":{},"了":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"g":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"s":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"?":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"r":{"docs":{},"a":{"docs":{},"n":{"docs":{},"o":{"docs":{},"i":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"m":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"?":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"i":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}},"c":{"docs":{},"u":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"s":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"s":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"h":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"n":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"w":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"e":{"docs":{},"d":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},"t":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}},"u":{"docs":{},"s":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"i":{"docs":{},"r":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"d":{"docs":{},"f":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"、":{"docs":{},"电":{"docs":{},"子":{"docs":{},"书":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"打":{"docs":{},"印":{"docs":{},"版":{"docs":{},",":{"docs":{},"请":{"docs":{},"查":{"docs":{},"阅":{"docs":{},"官":{"docs":{},"网":{"docs":{},"(":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"/":{"docs":{},"b":{"docs":{},"o":{"docs":{},"o":{"docs":{},"k":{"docs":{},",":{"docs":{},"中":{"docs":{},"文":{"docs":{},"版":{"docs":{},"为":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"o":{"docs":{},"p":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"m":{"docs":{},"i":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}},"s":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"i":{"docs":{},"o":{"docs":{},"d":{"docs":{},"!":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"e":{"docs":{},"k":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"i":{"docs":{},"c":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"e":{"docs":{},"r":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"e":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"p":{"docs":{},"e":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}},"e":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"t":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"c":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"h":{"docs":{},"o":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"y":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"n":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"a":{"docs":{},"s":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}},"u":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"r":{"docs":{},"a":{"docs":{},"l":{"docs":{},"s":{"docs":{},"i":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0064794816414686825}},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}},"o":{"docs":{},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"p":{"docs":{},"u":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"w":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"s":{"docs":{},"h":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}},"l":{"docs":{},")":{"docs":{},",":{"docs":{},"并":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}},"。":{"docs":{},"一":{"docs":{},"路":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}},"r":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.00594732370433305},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"a":{"docs":{},"l":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"s":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}},"s":{"docs":{},"s":{"docs":{},"i":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},"g":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}},"f":{"docs":{},"i":{"docs":{},"x":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"c":{"docs":{},"o":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},"l":{"docs":{},"y":{"docs":{},"g":{"docs":{},"l":{"docs":{},"o":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"r":{"docs":{},"e":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"v":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"i":{"docs":{},"o":{"docs":{},"u":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}},"f":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"i":{"docs":{},"x":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"s":{"docs":{},"s":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"v":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}}}},"c":{"docs":{},"e":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"o":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"d":{"docs":{},"u":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"t":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.017804154302670624},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"m":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.00265017667844523}}}}}}},"!":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}},"c":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}}}}}},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},":":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.01483679525222552},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.022598870056497175},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.011049723756906077},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.006044905008635579},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.009259259259259259},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"'":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"v":{"docs":{},"i":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},"r":{"docs":{},"。":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},"因":{"docs":{},"为":{"docs":{},"整":{"docs":{},"个":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"都":{"docs":{},"存":{"docs":{},"在":{"docs":{},"于":{"docs":{},"内":{"docs":{},"存":{"docs":{},"里":{"docs":{},",":{"docs":{},"每":{"docs":{},"次":{"docs":{},"测":{"docs":{},"试":{"docs":{},"重":{"docs":{},"新":{"docs":{},"开":{"docs":{},"始":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"他":{"docs":{},"就":{"docs":{},"会":{"docs":{},"被":{"docs":{},"清":{"docs":{},"空":{"docs":{},"。":{"docs":{},"并":{"docs":{},"且":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"合":{"docs":{},"乎":{"docs":{},"规":{"docs":{},"格":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},",":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}},"然":{"docs":{},"后":{"docs":{},"对":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},"s":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},".":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"m":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"i":{"docs":{},"s":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121}},"e":{"1":{"docs":{},",":{"docs":{},"这":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"它":{"docs":{},"的":{"docs":{},"原":{"docs":{},"因":{"docs":{},"是":{"docs":{},",":{"docs":{},"这":{"docs":{},"将":{"docs":{},"是":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}},"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"c":{"docs":{},"r":{"docs":{},"a":{"docs":{},"s":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"p":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"t":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.01981981981981982},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"y":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"l":{"docs":{},"y":{"docs":{},".":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"t":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}}}}},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"x":{"docs":{},"i":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}},"y":{"docs":{},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"_":{"docs":{},"c":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"_":{"docs":{},"b":{"docs":{},"y":{"docs":{},"p":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"_":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}},"p":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"_":{"docs":{},"h":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}}}}}}}}}}}}}},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}},"u":{"docs":{},"r":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"g":{"docs":{},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"b":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.01875},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.025225225225225224},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.019230769230769232},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.03508771929824561},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.01444043321299639},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.021890547263681594},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.017054263565891473},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.018111254851228976}}},"s":{"docs":{},"h":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0076465590484282074}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}},"l":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}},"s":{"docs":{},"h":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}}}}},"y":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"r":{"docs":{},"a":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"、":{"docs":{},"d":{"docs":{},"j":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"o":{"docs":{},"、":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}},"z":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.014457831325301205},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}},")":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},",":{"docs":{},"应":{"docs":{},"该":{"docs":{},"会":{"docs":{},"注":{"docs":{},"意":{"docs":{},"到":{"docs":{},"一":{"docs":{},"些":{"docs":{},"语":{"docs":{},"法":{"docs":{},"的":{"docs":{},"差":{"docs":{},"异":{"docs":{},"。":{"docs":{},"生":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{},"指":{"docs":{},"向":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"d":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"w":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},"r":{"docs":{},"e":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}},"e":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},"a":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"i":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"/":{"docs":{},"w":{"docs":{},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"o":{"docs":{},"n":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}}}}},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}}}}}}},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"i":{"docs":{},"z":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}},"c":{"docs":{},"h":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"d":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"i":{"docs":{},"b":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"t":{"docs":{},"o":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}}}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"c":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}},"f":{"docs":{},"l":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.011049723756906077},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},"?":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"h":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"g":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.008522727272727272},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"r":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"a":{"docs":{},"r":{"docs":{},"d":{"docs":{},"l":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"e":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.015463917525773196}}}},"i":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"m":{"docs":{},"e":{"docs":{},"m":{"docs":{},"b":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"i":{"docs":{},"x":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"o":{"docs":{},"v":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0064794816414686825}}},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556}},"e":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.012048192771084338},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"p":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}},"o":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"y":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}},"e":{"docs":{},"d":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.009233610341643583},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.007761966364812419},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}},"s":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"i":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.03007518796992481},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}}}},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"a":{"docs":{},"r":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}},"p":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"e":{"docs":{},".":{"docs":{},"h":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},".":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{},"t":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"(":{"docs":{},")":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{},"c":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}},"d":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"o":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0076465590484282074}}}},"r":{"docs":{},"i":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"o":{"docs":{},"u":{"docs":{},"r":{"docs":{},"c":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556}}}}}}},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0084985835694051},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.01263537906137184},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.014773776546629732},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.017523364485981307},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.023880597014925373},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}},"r":{"docs":{},"i":{"docs":{},"e":{"docs":{},"v":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"u":{"docs":{},"s":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"w":{"docs":{},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384}}}}},"o":{"docs":{},"r":{"docs":{},"k":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"c":{"docs":{},"e":{"docs":{},"i":{"docs":{},"v":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"o":{"docs":{},"m":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}},"i":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01038961038961039},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"o":{"docs":{},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"i":{"docs":{},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"c":{"docs":{},"h":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}},"u":{"docs":{},"b":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464}}},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"。":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}},"n":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.020771513353115726},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.011299435028248588},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.00909090909090909},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00646830530401035},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.020390824129141887}},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}},"e":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"代":{"docs":{},"码":{"docs":{},"通":{"docs":{},"过":{"docs":{},"编":{"docs":{},"译":{"docs":{},"而":{"docs":{},"没":{"docs":{},"有":{"docs":{},"报":{"docs":{},"错":{"docs":{},",":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"将":{"docs":{},"在":{"docs":{},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"n":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},",":{"docs":{},"它":{"docs":{},"一":{"docs":{},"步":{"docs":{},"就":{"docs":{},"完":{"docs":{},"成":{"docs":{},"了":{"docs":{},"这":{"docs":{},"些":{"docs":{},"事":{"docs":{},"情":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}},"l":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"o":{"docs":{},"o":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00847457627118644},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"u":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"e":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},")":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"w":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"l":{"docs":{},"l":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"e":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.007751937984496124}},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.005426356589147287}},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},".":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"u":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"m":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"s":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"i":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"m":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"v":{"docs":{},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"c":{"docs":{},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}}}}}},"d":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"y":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"w":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"f":{"docs":{},"e":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"h":{"docs":{},"i":{"docs":{},"n":{"docs":{},"y":{"docs":{},"a":{"docs":{},"n":{"docs":{},"l":{"docs":{},"i":{"docs":{},"k":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}}}}},"c":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"c":{"docs":{},"h":{"docs":{},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"e":{"docs":{},"e":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},")":{"docs":{},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"o":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"n":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"l":{"docs":{},"e":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"o":{"docs":{},"p":{"docs":{},"e":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"d":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},")":{"docs":{},"。":{"docs":{},"我":{"docs":{},"会":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"v":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"n":{"docs":{},"a":{"docs":{},"r":{"docs":{},"i":{"docs":{},"o":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"s":{"docs":{},",":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"e":{"docs":{},"c":{"docs":{},"u":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.008522727272727272},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},":":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"e":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"!":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}}},"s":{"docs":{},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}},"e":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.003875968992248062},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"m":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},",":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"d":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},".":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},")":{"docs":{},".":{"docs":{},"w":{"docs":{},"a":{"docs":{},"i":{"docs":{},"t":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"r":{"docs":{},"i":{"docs":{},"o":{"docs":{},"u":{"docs":{},"s":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"v":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01818181818181818},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.004248088360237893},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},",":{"docs":{},"m":{"docs":{},"y":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{},",":{"docs":{},"m":{"docs":{},"o":{"docs":{},"n":{"docs":{},"g":{"docs":{},"o":{"docs":{},"d":{"docs":{},"b":{"docs":{},",":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"s":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"什":{"docs":{},"么":{"docs":{},"其":{"docs":{},"它":{"docs":{},"稀":{"docs":{},"奇":{"docs":{},"古":{"docs":{},"怪":{"docs":{},"的":{"docs":{},"玩":{"docs":{},"意":{"docs":{},"儿":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"的":{"docs":{},"行":{"docs":{},"或":{"docs":{},"者":{"docs":{},"记":{"docs":{},"录":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"、":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},"g":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}},"_":{"docs":{},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"s":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"i":{"docs":{},"c":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.015580736543909348},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.023351648351648352},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.018050541516245487},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0029850746268656717},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"s":{"docs":{},"/":{"docs":{},"f":{"docs":{},"a":{"docs":{},"k":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},"e":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}}}},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},".":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}}}}}}},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"n":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}}}}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"p":{"docs":{},"e":{"docs":{},"d":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}}}}}}},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{},"(":{"docs":{},"o":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"r":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"l":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.01048951048951049},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.00594732370433305}},";":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.01981981981981982},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"}":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}}},"u":{"docs":{},"p":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"s":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}},"i":{"docs":{},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"l":{"docs":{},"y":{"docs":{},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"m":{"docs":{},"i":{"docs":{},"c":{"docs":{},"o":{"docs":{},"l":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}},"h":{"docs":{},"a":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385}},"r":{"docs":{},"e":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"o":{"docs":{},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"c":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"w":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"i":{"docs":{},"f":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294}}}},"p":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}},"u":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}}},"i":{"docs":{},"m":{"docs":{},"i":{"docs":{},"l":{"docs":{},"a":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"p":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"f":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},"s":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"c":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}},"e":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"u":{"docs":{},"l":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}},"t":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}},"j":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}},"d":{"docs":{},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"t":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},".":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{},"e":{"docs":{},"f":{"docs":{},"a":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}},"g":{"docs":{},"n":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"a":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},")":{"docs":{},"。":{"docs":{},"该":{"docs":{},"方":{"docs":{},"法":{"docs":{},"不":{"docs":{},"需":{"docs":{},"要":{"docs":{},"任":{"docs":{},"何":{"docs":{},"参":{"docs":{},"数":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"l":{"docs":{},"r":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}},"i":{"docs":{},"n":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674}}}}}}}},"f":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}},"l":{"docs":{},"l":{"docs":{},"i":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"k":{"docs":{},"i":{"docs":{},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"p":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},"l":{"docs":{},"l":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"u":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}},"o":{"docs":{},"m":{"docs":{},"e":{"docs":{},"t":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"i":{"docs":{},"m":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"o":{"docs":{},"n":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"r":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}},"l":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}}}},"v":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},"c":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}},"p":{"docs":{},"e":{"docs":{},"c":{"docs":{},"i":{"docs":{},"f":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}},"y":{"docs":{},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"e":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"n":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"a":{"docs":{},"s":{"docs":{},"h":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"r":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"i":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"o":{"docs":{},"r":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{},"a":{"docs":{},"r":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.007950530035335688}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"u":{"docs":{},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"c":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475}},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"t":{"docs":{},"i":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.010852713178294573},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"u":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"m":{"docs":{},"p":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"y":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"c":{"docs":{},"k":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},"o":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}},"r":{"docs":{},"u":{"docs":{},"c":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.01048951048951049},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993}}},".":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},"e":{"docs":{},"a":{"docs":{},"m":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"u":{"docs":{},"f":{"docs":{},"f":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"d":{"docs":{},"i":{"docs":{},"o":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.06417112299465241},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.022598870056497175},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.0380952380952381},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},")":{"docs":{},",":{"docs":{},"下":{"docs":{},"面":{"docs":{},"这":{"docs":{},"几":{"docs":{},"个":{"docs":{},"有":{"docs":{},"益":{"docs":{},"的":{"docs":{},"小":{"docs":{},"技":{"docs":{},"巧":{"docs":{},"将":{"docs":{},"帮":{"docs":{},"你":{"docs":{},"轻":{"docs":{},"松":{"docs":{},"上":{"docs":{},"手":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"直":{"docs":{},"接":{"docs":{},"打":{"docs":{},"开":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}},")":{"docs":{},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}},"c":{"docs":{},"k":{"docs":{},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.009009009009009009},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939}}}},"p":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"i":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}}}},"c":{"docs":{},"k":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}},"e":{"docs":{},"p":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"s":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},".":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"y":{"docs":{},"l":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"s":{"docs":{},"h":{"docs":{},"e":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603}}}}}}},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}},"!":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"u":{"docs":{},"p":{"docs":{},"p":{"docs":{},"o":{"docs":{},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"r":{"docs":{},"f":{"docs":{},"a":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"e":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"b":{"docs":{},"l":{"docs":{},"i":{"docs":{},"m":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},"m":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682}}}}},"d":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}},"c":{"docs":{},"h":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}},"c":{"docs":{},"e":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"s":{"docs":{},"s":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"f":{"docs":{},"u":{"docs":{},"l":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"l":{"docs":{},"i":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}},"e":{"docs":{},"d":{"docs":{},"e":{"docs":{},"d":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"g":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}},"y":{"docs":{},"s":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"、":{"docs":{},"i":{"docs":{},"i":{"docs":{},"s":{"docs":{},"、":{"docs":{},"和":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"l":{"docs":{},"l":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{},"g":{"docs":{},"e":{"docs":{},"n":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{},"c":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"p":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},".":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"a":{"docs":{},"n":{"docs":{},"n":{"docs":{},"o":{"docs":{},"t":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"q":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}},"t":{"docs":{},"h":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},".":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"k":{"docs":{},"s":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}},"i":{"docs":{},"o":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},".":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}}}}}}},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},";":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"s":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"m":{"docs":{},"b":{"docs":{},"o":{"docs":{},"l":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"n":{"docs":{},"t":{"docs":{},"a":{"docs":{},"x":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}},"c":{"docs":{},",":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}},"d":{"docs":{},"k":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.016042780748663103},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":5.030769230769231},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}},",":{"docs":{},"包":{"docs":{},"括":{"docs":{},"运":{"docs":{},"行":{"docs":{},"时":{"docs":{},",":{"docs":{},"基":{"docs":{},"础":{"docs":{},"库":{"docs":{},"以":{"docs":{},"及":{"docs":{},"用":{"docs":{},"于":{"docs":{},"构":{"docs":{},"建":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"手":{"docs":{},"动":{"docs":{},"安":{"docs":{},"装":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}},"。":{"docs":{},"完":{"docs":{},"成":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}},"q":{"docs":{},"u":{"docs":{},"i":{"docs":{},"g":{"docs":{},"g":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"i":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.020618556701030927},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.027972027972027972},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273}},")":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}},"注":{"docs":{},"入":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"m":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"a":{"docs":{},"p":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"l":{"docs":{},"o":{"docs":{},"w":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"a":{"docs":{},"k":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"s":{"docs":{},"k":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.012747875354107648},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.009615384615384616},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.008310249307479225},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.006201550387596899},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"f":{"docs":{},"r":{"docs":{},"o":{"docs":{},"m":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"(":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"[":{"docs":{},"]":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}},"“":{"docs":{},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"?":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"”":{"docs":{},"的":{"docs":{},"意":{"docs":{},"思":{"docs":{},"是":{"docs":{},"说":{"docs":{},",":{"docs":{},"该":{"docs":{},"方":{"docs":{},"法":{"docs":{},"不":{"docs":{},"能":{"docs":{},"立":{"docs":{},"刻":{"docs":{},"给":{"docs":{},"出":{"docs":{},"一":{"docs":{},"个":{"docs":{},"结":{"docs":{},"果":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"使":{"docs":{},"用":{"docs":{},"关":{"docs":{},"键":{"docs":{},"字":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"代":{"docs":{},"替":{"docs":{},"之":{"docs":{},"前":{"docs":{},"的":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"就":{"docs":{},"必":{"docs":{},"须":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}},")":{"docs":{},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"必":{"docs":{},"须":{"docs":{},"执":{"docs":{},"行":{"docs":{},"一":{"docs":{},"次":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}},"b":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.00963855421686747},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.013157894736842105},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.012727272727272728}},"e":{"docs":{},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"l":{"docs":{},"u":{"docs":{},"m":{"docs":{},"n":{"docs":{},"(":{"docs":{},"n":{"docs":{},"u":{"docs":{},"l":{"docs":{},"l":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.014545454545454545}}}}}}}}}}}}}}}}}},"p":{"docs":{},"r":{"docs":{},"i":{"docs":{},"m":{"docs":{},"a":{"docs":{},"r":{"docs":{},"y":{"docs":{},"k":{"docs":{},"e":{"docs":{},"y":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"p":{"docs":{},"k":{"docs":{},"_":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"g":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.046511627906976744},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.006463527239150508}},",":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}},"l":{"docs":{},"k":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"x":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"e":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"e":{"docs":{},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},":":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},")":{"docs":{},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"o":{"docs":{},"r":{"docs":{},"a":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"r":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"a":{"docs":{},"l":{"docs":{},".":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"l":{"docs":{},"l":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}}}},"x":{"docs":{},"t":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.008902077151335312},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},"c":{"docs":{},"h":{"docs":{},"n":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},"o":{"docs":{},"l":{"docs":{},"o":{"docs":{},"g":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"y":{"docs":{},".":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}},"n":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}},"s":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.03626943005181347},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.04139715394566624},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}},"s":{"docs":{},")":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},",":{"docs":{},"并":{"docs":{},"使":{"docs":{},"测":{"docs":{},"试":{"docs":{},"代":{"docs":{},"码":{"docs":{},"干":{"docs":{},"净":{"docs":{},"利":{"docs":{},"索":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"?":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"f":{"docs":{},"i":{"docs":{},"x":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},"e":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"一":{"docs":{},"切":{"docs":{},"工":{"docs":{},"作":{"docs":{},"顺":{"docs":{},"利":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"成":{"docs":{},"功":{"docs":{},"信":{"docs":{},"息":{"docs":{},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}},"t":{"docs":{},"'":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{},"'":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"!":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"m":{"docs":{},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},":":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"s":{"docs":{},"e":{"docs":{},"l":{"docs":{},"v":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}},"n":{"docs":{},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"y":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"v":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},")":{"docs":{},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"s":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},".":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"k":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}},"s":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"r":{"docs":{},"d":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"o":{"docs":{},"u":{"docs":{},"s":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"g":{"docs":{},"h":{"docs":{},"t":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"s":{"docs":{},"e":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}}}},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"g":{"docs":{},"h":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"g":{"docs":{},"h":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},";":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}},"e":{"docs":{},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"y":{"docs":{},"m":{"docs":{},"e":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"f":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}}}},"i":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"m":{"docs":{},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"t":{"docs":{},"a":{"docs":{},"m":{"docs":{},"p":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}},",":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"z":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}},"e":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}},"p":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}}},"t":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.008310249307479225},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0025906735751295338}}}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.007082152974504249}}}},"n":{"docs":{},"i":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"d":{"docs":{},"y":{"docs":{},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"o":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"d":{"docs":{},"o":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.01875},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.006868131868131868},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.022556390977443608},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.004317789291882556}},"l":{"docs":{},"e":{"docs":{},"r":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}},"(":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}},")":{"docs":{},"类":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"实":{"docs":{},"例":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},"被":{"docs":{},"调":{"docs":{},"用":{"docs":{},"。":{"docs":{},"在":{"docs":{},"构":{"docs":{},"造":{"docs":{},"函":{"docs":{},"数":{"docs":{},"中":{"docs":{},"加":{"docs":{},"入":{"docs":{},"的":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"你":{"docs":{},"必":{"docs":{},"须":{"docs":{},"提":{"docs":{},"供":{"docs":{},"一":{"docs":{},"个":{"docs":{},"能":{"docs":{},"匹":{"docs":{},"配":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}},"当":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"需":{"docs":{},"要":{"docs":{},"一":{"docs":{},"个":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"些":{"docs":{},"代":{"docs":{},"码":{"docs":{},"以":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"e":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0113314447592068},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.01569713758079409},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.006965174129353234},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}},"[":{"docs":{},"]":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037}}}},"s":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"\"":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.008635578583765112}},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495}}},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}},"(":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}}}}}}}}}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},".":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"s":{"docs":{},"h":{"docs":{},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"(":{"docs":{},")":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}},",":{"docs":{},"以":{"docs":{},"一":{"docs":{},"个":{"docs":{},"空":{"docs":{},"条":{"docs":{},"目":{"docs":{},"初":{"docs":{},"始":{"docs":{},"化":{"docs":{},"该":{"docs":{},"表":{"docs":{},"单":{"docs":{},"。":{"docs":{},"(":{"docs":{},"请":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"添":{"docs":{},"加":{"docs":{},"{":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.007207207207207207},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384}},"(":{"docs":{},")":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"该":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},"/":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"h":{"docs":{},"o":{"docs":{},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},"(":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"f":{"docs":{},"i":{"docs":{},"x":{"docs":{},"t":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"o":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.023076923076923078},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},",":{"docs":{},"也":{"docs":{},"叫":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"p":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"c":{"docs":{},"s":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"u":{"docs":{},"c":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}},",":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"l":{"docs":{},"d":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"a":{"docs":{},"r":{"docs":{},"r":{"docs":{},"a":{"docs":{},"y":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"r":{"docs":{},"a":{"docs":{},"n":{"docs":{},"s":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"e":{"docs":{},"r":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}},"l":{"docs":{},"a":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"c":{"docs":{},"k":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"v":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"i":{"docs":{},"l":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"y":{"docs":{},".":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}},"i":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.004651162790697674},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"c":{"docs":{},"k":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"y":{"docs":{},".":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"u":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"/":{"docs":{},"f":{"docs":{},"a":{"docs":{},"l":{"docs":{},"s":{"docs":{},"e":{"docs":{},")":{"docs":{},"。":{"docs":{},"默":{"docs":{},"认":{"docs":{},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},",":{"docs":{},"所":{"docs":{},"有":{"docs":{},"新":{"docs":{},"建":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"该":{"docs":{},"值":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},")":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523}}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"l":{"docs":{},"y":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},".":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}},"u":{"docs":{},"r":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"a":{"docs":{},"l":{"docs":{},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"y":{"docs":{},"p":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"?":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"s":{"docs":{},",":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"i":{"docs":{},"c":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195}}}},"o":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.008639308855291577}}}}},"w":{"docs":{},"o":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"发":{"docs":{},"帖":{"docs":{},",":{"docs":{},"包":{"docs":{},"罗":{"docs":{},"万":{"docs":{},"象":{"docs":{},"。":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"(":{"docs":{},"@":{"docs":{},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},")":{"docs":{},"上":{"docs":{},"和":{"docs":{},"我":{"docs":{},"保":{"docs":{},"持":{"docs":{},"联":{"docs":{},"系":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"在":{"docs":{},"我":{"docs":{},"的":{"docs":{},"博":{"docs":{},"客":{"docs":{},"上":{"docs":{},"(":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"w":{"docs":{},"w":{"docs":{},"w":{"docs":{},".":{"docs":{},"r":{"docs":{},"e":{"docs":{},"c":{"docs":{},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"e":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},")":{"docs":{},"。":{"docs":{},"你":{"docs":{},"还":{"docs":{},"可":{"docs":{},"以":{"docs":{},"通":{"docs":{},"过":{"docs":{},"电":{"docs":{},"子":{"docs":{},"邮":{"docs":{},"件":{"docs":{},"(":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"@":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},")":{"docs":{},"联":{"docs":{},"系":{"docs":{},"我":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"v":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"i":{"docs":{},"m":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}},"l":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}},"o":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}},"t":{"docs":{},"i":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"i":{"docs":{},"q":{"docs":{},"u":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"t":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0069084628670120895},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"1":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"s":{"docs":{},"。":{"docs":{},"你":{"docs":{},"已":{"docs":{},"经":{"docs":{},"为":{"docs":{},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"编":{"docs":{},"写":{"docs":{},"准":{"docs":{},"备":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"这":{"docs":{},"样":{"docs":{},"你":{"docs":{},"就":{"docs":{},"为":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"编":{"docs":{},"写":{"docs":{},"准":{"docs":{},"备":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}},"docs":{}}}}}}},"l":{"docs":{},"i":{"docs":{},"k":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}},"a":{"docs":{},"w":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"t":{"docs":{},"u":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"l":{"docs":{},"y":{"docs":{},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}},"p":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.014545454545454545},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0118946474086661}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837}}},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.01090909090909091},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.013930348258706468},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"e":{"docs":{},",":{"docs":{},"重":{"docs":{},"新":{"docs":{},"搭":{"docs":{},"建":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"并":{"docs":{},"应":{"docs":{},"用":{"docs":{},"到":{"docs":{},"到":{"docs":{},"当":{"docs":{},"前":{"docs":{},"的":{"docs":{},"变":{"docs":{},"更":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"\"":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"(":{"docs":{},"m":{"docs":{},"i":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}}}}}}}}}}},"l":{"docs":{},"o":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"d":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}},"s":{"docs":{"./":{"ref":"./","tf":0.006183745583038869},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.017804154302670624},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.011299435028248588},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.021341463414634148},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0375},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.012048192771084338},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.042492917847025496},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.023351648351648352},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.047619047619047616},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.01744186046511628},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.03038674033149171},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.015463917525773196},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.02097902097902098},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.036101083032490974},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.0625},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.009233610341643583},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.007009345794392523},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.045112781954887216},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.013930348258706468},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.03565891472868217},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.025906735751295335},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.031047865459249677},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.015584415584415584},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.012962962962962963},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.010195412064570943},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},",":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.022727272727272728},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.012935323383084577},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.015503875968992248},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.007407407407407408}},"'":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.009146341463414634},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"i":{"docs":{},"d":{"docs":{},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"s":{"docs":{},".":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"\"":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.005970149253731343}}}},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.011940298507462687},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.012403100775193798}},"e":{"docs":{},"r":{"docs":{},")":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}},"。":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.002325581395348837},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"d":{"docs":{},".":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},")":{"docs":{},"地":{"docs":{},"区":{"docs":{},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"资":{"docs":{},"源":{"docs":{},"组":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"距":{"docs":{},"离":{"docs":{},"美":{"docs":{},"国":{"docs":{},"西":{"docs":{},"部":{"docs":{},"很":{"docs":{},"远":{"docs":{},",":{"docs":{},"请":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"r":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.005555555555555556}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"s":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"m":{"docs":{},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},".":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"就":{"docs":{},"像":{"docs":{},"你":{"docs":{},"将":{"docs":{},"其":{"docs":{},"应":{"docs":{},"用":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"i":{"docs":{},"(":{"docs":{},"\"":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},":":{"8":{"8":{"8":{"8":{"docs":{},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"c":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},"i":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"b":{"docs":{},"u":{"docs":{},"n":{"docs":{},"t":{"docs":{},"u":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},")":{"docs":{},"都":{"docs":{},"可":{"docs":{},"以":{"docs":{},"搭":{"docs":{},"建":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}},"v":{"docs":{},"a":{"docs":{},"r":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.01904761904761905},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.014018691588785047},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01791044776119403},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.018604651162790697},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.012089810017271158},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.007761966364812419}},"i":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.002548853016142736}},"e":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"t":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},"l":{"docs":{},"u":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"e":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406}}}},".":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"s":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},")":{"docs":{},"。":{"docs":{},"更":{"docs":{},"多":{"docs":{},"信":{"docs":{},"息":{"docs":{},"请":{"docs":{},"参":{"docs":{},"见":{"docs":{},":":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"/":{"docs":{},"a":{"docs":{},"n":{"docs":{},"n":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"c":{"docs":{},"e":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"s":{"docs":{},"/":{"docs":{},"i":{"docs":{},"s":{"docs":{},"s":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"/":{"2":{"9":{"5":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{},"。":{"docs":{},"核":{"docs":{},"验":{"docs":{},"操":{"docs":{},"作":{"docs":{},"检":{"docs":{},"查":{"docs":{},"从":{"docs":{},"传":{"docs":{},"入":{"docs":{},"请":{"docs":{},"求":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"到":{"docs":{},"模":{"docs":{},"型":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"鉴":{"docs":{},"别":{"docs":{},"其":{"docs":{},"合":{"docs":{},"理":{"docs":{},"性":{"docs":{},"和":{"docs":{},"有":{"docs":{},"效":{"docs":{},"性":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"模":{"docs":{},"型":{"docs":{},"中":{"docs":{},"添":{"docs":{},"加":{"docs":{},"属":{"docs":{},"性":{"docs":{},",":{"docs":{},"告":{"docs":{},"知":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"f":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433}},"i":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"y":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"s":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},")":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.03076923076923077}}}}}}}}},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.01524390243902439},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.009375},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.012612612612612612},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.04096385542168675},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.006463527239150508},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.005841121495327103},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"/":{"docs":{},"s":{"docs":{},"h":{"docs":{},"a":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},"/":{"docs":{},"_":{"docs":{},"l":{"docs":{},"a":{"docs":{},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.023255813953488372},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},".":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"/":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682}}}}}}}}}}}}}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"/":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}}}}}}}}}},".":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},".":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"[":{"docs":{},"\"":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},"\"":{"docs":{},"]":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"(":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},")":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"在":{"docs":{},"布":{"docs":{},"局":{"docs":{},"中":{"docs":{},"的":{"docs":{},"导":{"docs":{},"航":{"docs":{},"条":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}},"?":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"r":{"docs":{},"t":{"docs":{},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.058823529411764705},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.026836158192090395},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.0380952380952381},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}}}},"a":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}},"d":{"docs":{},"e":{"docs":{},"o":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"o":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.008771929824561403},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}},"w":{"docs":{},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.004120879120879121},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"i":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"(":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},".":{"docs":{},".":{"docs":{},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},"s":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"y":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00424929178470255},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},".":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"e":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}},"b":{"docs":{"./":{"ref":"./","tf":0.019434628975265017},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.007062146892655367},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.018292682926829267},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.023376623376623377},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.009259259259259259},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.004248088360237893}},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"e":{"docs":{},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}},"应":{"docs":{},"用":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"框":{"docs":{},"架":{"docs":{},"(":{"docs":{},"r":{"docs":{},"u":{"docs":{},"b":{"docs":{},"i":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}},",":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},"b":{"docs":{},"u":{"docs":{},"i":{"docs":{},"l":{"docs":{},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.011111111111111112}}}}}},"l":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}},"l":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},".":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"k":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}},"n":{"docs":{},"t":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"s":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"e":{"docs":{},"r":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"u":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}},"e":{"docs":{},"k":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"n":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"n":{"docs":{},"d":{"docs":{},"o":{"docs":{},"w":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.01038961038961039},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"s":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"、":{"docs":{},"m":{"docs":{},"a":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"或":{"docs":{},"者":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"u":{"docs":{},"x":{"docs":{},"上":{"docs":{},"安":{"docs":{},"装":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},",":{"docs":{},"和":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"、":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"u":{"docs":{},"x":{"docs":{},"上":{"docs":{},"。":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}},")":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}},".":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},",":{"docs":{},"i":{"docs":{},"i":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"s":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},".":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"i":{"docs":{},"o":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}},",":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"、":{"docs":{},"y":{"docs":{},"u":{"docs":{},"y":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"w":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"t":{"docs":{},"h":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}}}},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}},"r":{"docs":{},"e":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}},"p":{"docs":{},"e":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"o":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"d":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"r":{"docs":{},"k":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}},"!":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"a":{"docs":{},"r":{"docs":{},"o":{"docs":{},"u":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},".":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}},"!":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},"d":{"docs":{},"i":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.008496176720475786}}}}},"e":{"docs":{},"r":{"docs":{},"_":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"n":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}},"l":{"docs":{},"d":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":2.50593471810089},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}},".":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"!":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.011869436201780416},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"\"":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.005934718100890208}}}}}},"\"":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"”":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"清":{"docs":{},"单":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"很":{"docs":{},"棒":{"docs":{},"的":{"docs":{},"练":{"docs":{},"习":{"docs":{},",":{"docs":{},"麻":{"docs":{},"雀":{"docs":{},"小":{"docs":{},",":{"docs":{},"五":{"docs":{},"脏":{"docs":{},"俱":{"docs":{},"全":{"docs":{},",":{"docs":{},"它":{"docs":{},"将":{"docs":{},"涉":{"docs":{},"及":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"i":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"e":{"docs":{},"s":{"docs":{},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"y":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"!":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"d":{"docs":{},"s":{"docs":{},",":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}},"u":{"docs":{},"l":{"docs":{},"d":{"docs":{},"n":{"docs":{},"'":{"docs":{},"t":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},".":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.008287292817679558},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.01015228426395939},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.025},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.009499136442141624},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"t":{"docs":{},"e":{"docs":{},"n":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"o":{"docs":{},"t":{"docs":{},"e":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"n":{"docs":{},"g":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},",":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"a":{"docs":{},"p":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}},"h":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"v":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}},"'":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}},"e":{"docs":{},"t":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"n":{"docs":{},"e":{"docs":{},"v":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"r":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682}}}}}}},"y":{"docs":{},"?":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"w":{"docs":{},"w":{"docs":{},"r":{"docs":{},"o":{"docs":{},"o":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322}},"/":{"docs":{},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"/":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}}}}}}}},"j":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}},"s":{"docs":{},"/":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},".":{"docs":{},"j":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}}}}},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"'":{"docs":{},"l":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.007067137809187279},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0213903743315508},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.008902077151335312},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.007062146892655367},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.01524390243902439},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0113314447592068},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.005454545454545455},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.005415162454873646},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0046168051708217915},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.022556390977443608},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"r":{"docs":{"./":{"ref":"./","tf":0.00441696113074205},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0106951871657754},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.005649717514124294},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.012987012987012988},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"v":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.007792207792207792}}},"d":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},".":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"r":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"s":{"docs":{},"e":{"docs":{},"l":{"docs":{},"f":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},".":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},",":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"!":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}},"u":{"docs":{},"y":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"e":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"t":{"docs":{},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}},".":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"!":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"©":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}}},"—":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}},"—":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"、":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"上":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"。":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"这":{"docs":{},"件":{"docs":{},"事":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}},"构":{"docs":{},"建":{"docs":{},"并":{"docs":{},"运":{"docs":{},"行":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},",":{"docs":{},"但":{"docs":{},"我":{"docs":{},"不":{"docs":{},"会":{"docs":{},"过":{"docs":{},"多":{"docs":{},"涉":{"docs":{},"及":{"docs":{},"这":{"docs":{},"个":{"docs":{},"主":{"docs":{},"题":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}},"你":{"docs":{},"拥":{"docs":{},"有":{"docs":{},"多":{"docs":{},"种":{"docs":{},"部":{"docs":{},"署":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"。":{"docs":{},"这":{"docs":{},"一":{"docs":{},"章":{"docs":{},"里":{"docs":{},",":{"docs":{},"我":{"docs":{},"将":{"docs":{},"教":{"docs":{},"给":{"docs":{},"你":{"docs":{},"最":{"docs":{},"常":{"docs":{},"用":{"docs":{},"(":{"docs":{},"也":{"docs":{},"是":{"docs":{},"最":{"docs":{},"简":{"docs":{},"单":{"docs":{},")":{"docs":{},"的":{"docs":{},"上":{"docs":{},"线":{"docs":{},"方":{"docs":{},"式":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"可":{"docs":{},"能":{"docs":{},"需":{"docs":{},"要":{"docs":{},"把":{"docs":{},"文":{"docs":{},"件":{"docs":{},"名":{"docs":{},"用":{"docs":{},"引":{"docs":{},"号":{"docs":{},"括":{"docs":{},"起":{"docs":{},"来":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}},"移":{"docs":{},"动":{"docs":{},"应":{"docs":{},"用":{"docs":{},"也":{"docs":{},"是":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"其":{"docs":{},"它":{"docs":{},"属":{"docs":{},"性":{"docs":{},"(":{"docs":{},"i":{"docs":{},"s":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"教":{"docs":{},"程":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"等":{"docs":{},"待":{"docs":{},"访":{"docs":{},"问":{"docs":{},"请":{"docs":{},"求":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}},"一":{"docs":{},"章":{"docs":{},"结":{"docs":{},"尾":{"docs":{},"处":{"docs":{},",":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}},"节":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}},"个":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"有":{"docs":{},"着":{"docs":{},"大":{"docs":{},"量":{"docs":{},"的":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},",":{"docs":{},"从":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}},"多":{"docs":{},"个":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}},"也":{"docs":{},"写":{"docs":{},"一":{"docs":{},"些":{"docs":{},"有":{"docs":{},"关":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"传":{"docs":{},"输":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"被":{"docs":{},"窃":{"docs":{},"取":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"必":{"docs":{},"须":{"docs":{},"是":{"docs":{},"全":{"docs":{},"局":{"docs":{},"唯":{"docs":{},"一":{"docs":{},"的":{"docs":{},"。":{"docs":{},"一":{"docs":{},"旦":{"docs":{},"这":{"docs":{},"个":{"docs":{},"应":{"docs":{},"用":{"docs":{},"创":{"docs":{},"建":{"docs":{},"好":{"docs":{},"了":{"docs":{},",":{"docs":{},"会":{"docs":{},"具":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"以":{"docs":{},"下":{"docs":{},"格":{"docs":{},"式":{"docs":{},"的":{"docs":{},"默":{"docs":{},"认":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"发":{"docs":{},"表":{"docs":{},"看":{"docs":{},"法":{"docs":{},":":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"t":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"n":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"就":{"docs":{},"有":{"docs":{},"很":{"docs":{},"多":{"docs":{},"非":{"docs":{},"常":{"docs":{},"精":{"docs":{},"彩":{"docs":{},"(":{"docs":{},"其":{"docs":{},"中":{"docs":{},"某":{"docs":{},"些":{"docs":{},"就":{"docs":{},"是":{"docs":{},"来":{"docs":{},"自":{"docs":{},"于":{"docs":{},"你":{"docs":{},"们":{"docs":{},"读":{"docs":{},"者":{"docs":{},")":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"在":{"docs":{},"上":{"docs":{},"面":{"docs":{},"没":{"docs":{},"有":{"docs":{},"账":{"docs":{},"号":{"docs":{},"或":{"docs":{},"者":{"docs":{},"想":{"docs":{},"要":{"docs":{},"一":{"docs":{},"张":{"docs":{},"优":{"docs":{},"惠":{"docs":{},"券":{"docs":{},",":{"docs":{},"请":{"docs":{},"发":{"docs":{},"信":{"docs":{},"到":{"docs":{},":":{"docs":{},"n":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"@":{"docs":{},"b":{"docs":{},"a":{"docs":{},"r":{"docs":{},"b":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"不":{"docs":{},"再":{"docs":{},"有":{"docs":{},"区":{"docs":{},"别":{"docs":{},":":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"可":{"docs":{},"以":{"docs":{},"方":{"docs":{},"便":{"docs":{},"的":{"docs":{},"返":{"docs":{},"回":{"docs":{},"视":{"docs":{},"图":{"docs":{},"、":{"docs":{},"状":{"docs":{},"态":{"docs":{},"码":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"功":{"docs":{},"能":{"docs":{},"已":{"docs":{},"经":{"docs":{},"内":{"docs":{},"置":{"docs":{},"了":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"不":{"docs":{},"想":{"docs":{},"费":{"docs":{},"劲":{"docs":{},"的":{"docs":{},"话":{"docs":{},",":{"docs":{},"完":{"docs":{},"全":{"docs":{},"可":{"docs":{},"以":{"docs":{},"不":{"docs":{},"用":{"docs":{},"再":{"docs":{},"安":{"docs":{},"装":{"docs":{},"并":{"docs":{},"配":{"docs":{},"置":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"了":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"论":{"docs":{},"你":{"docs":{},"此":{"docs":{},"前":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"用":{"docs":{},"什":{"docs":{},"么":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"或":{"docs":{},"者":{"docs":{},"平":{"docs":{},"台":{"docs":{},",":{"docs":{},"都":{"docs":{},"需":{"docs":{},"要":{"docs":{},"安":{"docs":{},"装":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"还":{"docs":{},"是":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"都":{"docs":{},"遵":{"docs":{},"循":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}},"同":{"docs":{},",":{"docs":{},"那":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"是":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"会":{"docs":{},"察":{"docs":{},"觉":{"docs":{},"有":{"docs":{},"什":{"docs":{},"么":{"docs":{},"异":{"docs":{},"样":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"要":{"docs":{},"漏":{"docs":{},"掉":{"docs":{},"结":{"docs":{},"尾":{"docs":{},"那":{"docs":{},"个":{"docs":{},"句":{"docs":{},"点":{"docs":{},"!":{"docs":{},"它":{"docs":{},"告":{"docs":{},"诉":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}},"专":{"docs":{},"用":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"之":{"docs":{},"前":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},",":{"docs":{},"它":{"docs":{},"是":{"docs":{},"唯":{"docs":{},"一":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"先":{"docs":{},"试":{"docs":{},"着":{"docs":{},"创":{"docs":{},"建":{"docs":{},"并":{"docs":{},"运":{"docs":{},"行":{"docs":{},"一":{"docs":{},"个":{"docs":{},"简":{"docs":{},"单":{"docs":{},"的":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"吧":{"docs":{},"。":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"反":{"docs":{},"向":{"docs":{},"代":{"docs":{},"理":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}},"类":{"docs":{},"的":{"docs":{},"后":{"docs":{},"端":{"docs":{},"语":{"docs":{},"言":{"docs":{},"写":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"注":{"docs":{},"意":{"docs":{},"到":{"docs":{},"很":{"docs":{},"多":{"docs":{},"熟":{"docs":{},"悉":{"docs":{},"的":{"docs":{},"概":{"docs":{},"念":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}},"模":{"docs":{},"板":{"docs":{},"语":{"docs":{},"言":{"docs":{},")":{"docs":{},",":{"docs":{},"它":{"docs":{},"接":{"docs":{},"收":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"并":{"docs":{},"展":{"docs":{},"示":{"docs":{},"给":{"docs":{},"用":{"docs":{},"户":{"docs":{},"。":{"docs":{},"模":{"docs":{},"型":{"docs":{},"则":{"docs":{},"保":{"docs":{},"管":{"docs":{},"着":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"要":{"docs":{},"么":{"docs":{},"是":{"docs":{},"准":{"docs":{},"备":{"docs":{},"发":{"docs":{},"送":{"docs":{},"给":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},",":{"docs":{},"要":{"docs":{},"么":{"docs":{},"是":{"docs":{},"用":{"docs":{},"户":{"docs":{},"输":{"docs":{},"入":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"状":{"docs":{},"态":{"docs":{},"码":{"docs":{},"。":{"docs":{},"返":{"docs":{},"回":{"docs":{},"类":{"docs":{},"型":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}},"身":{"docs":{},"份":{"docs":{},"提":{"docs":{},"供":{"docs":{},"者":{"docs":{},"的":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"反":{"docs":{},"向":{"docs":{},"代":{"docs":{},"理":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},",":{"docs":{},"把":{"docs":{},"请":{"docs":{},"求":{"docs":{},"代":{"docs":{},"理":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}},"也":{"docs":{},"为":{"docs":{},"多":{"docs":{},"线":{"docs":{},"程":{"docs":{},"和":{"docs":{},"异":{"docs":{},"步":{"docs":{},"任":{"docs":{},"务":{"docs":{},"作":{"docs":{},"了":{"docs":{},"专":{"docs":{},"门":{"docs":{},"的":{"docs":{},"优":{"docs":{},"化":{"docs":{},"。":{"docs":{},"与":{"docs":{},"使":{"docs":{},"用":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}},"可":{"docs":{},"以":{"docs":{},"跑":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"能":{"docs":{},"处":{"docs":{},"理":{"docs":{},"这":{"docs":{},"个":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}},"便":{"docs":{},"于":{"docs":{},"把":{"docs":{},"你":{"docs":{},"的":{"docs":{},"应":{"docs":{},"用":{"docs":{},"扩":{"docs":{},"展":{"docs":{},"为":{"docs":{},"多":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"。":{"docs":{},"一":{"docs":{},"旦":{"docs":{},"你":{"docs":{},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"镜":{"docs":{},"像":{"docs":{},",":{"docs":{},"用":{"docs":{},"它":{"docs":{},"来":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"什":{"docs":{},"么":{"docs":{},"是":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"以":{"docs":{},"及":{"docs":{},"它":{"docs":{},"的":{"docs":{},"实":{"docs":{},"用":{"docs":{},"之":{"docs":{},"处":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}},"从":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"构":{"docs":{},"建":{"docs":{},"伊":{"docs":{},"始":{"docs":{},"就":{"docs":{},"注":{"docs":{},"重":{"docs":{},"安":{"docs":{},"全":{"docs":{},"。":{"docs":{},"它":{"docs":{},"已":{"docs":{},"经":{"docs":{},"自":{"docs":{},"动":{"docs":{},"处":{"docs":{},"理":{"docs":{},"了":{"docs":{},"净":{"docs":{},"化":{"docs":{},"输":{"docs":{},"入":{"docs":{},"数":{"docs":{},"据":{"docs":{},"和":{"docs":{},"跨":{"docs":{},"域":{"docs":{},"伪":{"docs":{},"造":{"docs":{},"请":{"docs":{},"求":{"docs":{},"(":{"docs":{},"c":{"docs":{},"s":{"docs":{},"r":{"docs":{},"f":{"docs":{},")":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"不":{"docs":{},"需":{"docs":{},"要":{"docs":{},"操":{"docs":{},"心":{"docs":{},"这":{"docs":{},"些":{"docs":{},"了":{"docs":{},"。":{"docs":{},"你":{"docs":{},"同":{"docs":{},"时":{"docs":{},"还":{"docs":{},"享":{"docs":{},"有":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"获":{"docs":{},"取":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},"中":{"docs":{},"获":{"docs":{},"取":{"docs":{},"真":{"docs":{},"实":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"获":{"docs":{},"取":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"代":{"docs":{},"码":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"的":{"docs":{},"支":{"docs":{},"持":{"docs":{},"库":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"看":{"docs":{},"着":{"docs":{},"这":{"docs":{},"段":{"docs":{},"已":{"docs":{},"经":{"docs":{},"像":{"docs":{},"天":{"docs":{},"书":{"docs":{},"那":{"docs":{},"么":{"docs":{},"晦":{"docs":{},"涩":{"docs":{},",":{"docs":{},"直":{"docs":{},"接":{"docs":{},"跳":{"docs":{},"到":{"docs":{},"下":{"docs":{},"一":{"docs":{},"章":{"docs":{},"吧":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"框":{"docs":{},"架":{"docs":{},",":{"docs":{},"可":{"docs":{},"用":{"docs":{},"于":{"docs":{},"编":{"docs":{},"写":{"docs":{},"单":{"docs":{},"元":{"docs":{},"和":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"。":{"docs":{},"像":{"docs":{},"其":{"docs":{},"它":{"docs":{},"组":{"docs":{},"件":{"docs":{},"一":{"docs":{},"样":{"docs":{},",":{"docs":{},"它":{"docs":{},"也":{"docs":{},"是":{"docs":{},"一":{"docs":{},"组":{"docs":{},"n":{"docs":{},"u":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"补":{"docs":{},"全":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}},"文":{"docs":{},"件":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},",":{"docs":{},"一":{"docs":{},"般":{"docs":{},"与":{"docs":{},"存":{"docs":{},"放":{"docs":{},"该":{"docs":{},"文":{"docs":{},"件":{"docs":{},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"名":{"docs":{},"保":{"docs":{},"持":{"docs":{},"一":{"docs":{},"致":{"docs":{},"(":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{},"是":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},",":{"docs":{},"以":{"docs":{},"此":{"docs":{},"类":{"docs":{},"推":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},"创":{"docs":{},"建":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"查":{"docs":{},"询":{"docs":{},"语":{"docs":{},"句":{"docs":{},",":{"docs":{},"查":{"docs":{},"询":{"docs":{},"结":{"docs":{},"果":{"docs":{},"映":{"docs":{},"射":{"docs":{},"回":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}},"可":{"docs":{},"以":{"docs":{},"于":{"docs":{},"具":{"docs":{},"体":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"实":{"docs":{},"现":{"docs":{},"无":{"docs":{},"关":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"根":{"docs":{},"据":{"docs":{},"底":{"docs":{},"层":{"docs":{},"以":{"docs":{},"来":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"技":{"docs":{},"术":{"docs":{},"更":{"docs":{},"换":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"块":{"docs":{},"下":{"docs":{},"编":{"docs":{},"写":{"docs":{},"新":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"表":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"的":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}},"以":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"前":{"docs":{},"的":{"docs":{},"版":{"docs":{},"本":{"docs":{},",":{"docs":{},"直":{"docs":{},"接":{"docs":{},"看":{"docs":{},"下":{"docs":{},"一":{"docs":{},"章":{"docs":{},"去":{"docs":{},"吧":{"docs":{},"!":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}},"便":{"docs":{},"停":{"docs":{},"止":{"docs":{},"这":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}},"调":{"docs":{},"试":{"docs":{},"模":{"docs":{},"式":{"docs":{},"运":{"docs":{},"行":{"docs":{},"项":{"docs":{},"目":{"docs":{},"。":{"docs":{},"这":{"docs":{},"跟":{"docs":{},"命":{"docs":{},"令":{"docs":{},"行":{"docs":{},"的":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}},"获":{"docs":{},"取":{"docs":{},"其":{"docs":{},"中":{"docs":{},"的":{"docs":{},"值":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"当":{"docs":{},"前":{"docs":{},"用":{"docs":{},"户":{"docs":{},",":{"docs":{},"如":{"docs":{},"同":{"docs":{},"在":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}},"说":{"docs":{},"明":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"怎":{"docs":{},"样":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"进":{"docs":{},"行":{"docs":{},"核":{"docs":{},"验":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"及":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}},"检":{"docs":{},"验":{"docs":{},"你":{"docs":{},"的":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}},"结":{"docs":{},"果":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"交":{"docs":{},"互":{"docs":{},"模":{"docs":{},"式":{"docs":{},"运":{"docs":{},"行":{"docs":{},"这":{"docs":{},"个":{"docs":{},"容":{"docs":{},"器":{"docs":{},"(":{"docs":{},"输":{"docs":{},"出":{"docs":{},"到":{"docs":{},"终":{"docs":{},"端":{"docs":{},",":{"docs":{},"而":{"docs":{},"不":{"docs":{},"是":{"docs":{},"在":{"docs":{},"后":{"docs":{},"台":{"docs":{},"运":{"docs":{},"行":{"docs":{},")":{"docs":{},"。":{"docs":{},"当":{"docs":{},"你":{"docs":{},"想":{"docs":{},"要":{"docs":{},"停":{"docs":{},"止":{"docs":{},"这":{"docs":{},"个":{"docs":{},"容":{"docs":{},"器":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"按":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"下":{"docs":{},"这":{"docs":{},"些":{"docs":{},"很":{"docs":{},"棒":{"docs":{},"的":{"docs":{},"各":{"docs":{},"国":{"docs":{},"程":{"docs":{},"序":{"docs":{},"员":{"docs":{},",":{"docs":{},"翻":{"docs":{},"译":{"docs":{},"了":{"docs":{},"本":{"docs":{},"书":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}},"贡":{"docs":{},"献":{"docs":{},"者":{"docs":{},",":{"docs":{},"提":{"docs":{},"升":{"docs":{},"了":{"docs":{},"这":{"docs":{},"本":{"docs":{},"书":{"docs":{},"的":{"docs":{},"质":{"docs":{},"量":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}},"作":{"docs":{},"为":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"对":{"docs":{},"比":{"docs":{},",":{"docs":{},"这":{"docs":{},"里":{"docs":{},"要":{"docs":{},"指":{"docs":{},"出":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"前":{"docs":{},"缀":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},"幕":{"docs":{},"后":{"docs":{},"的":{"docs":{},"实":{"docs":{},"际":{"docs":{},"服":{"docs":{},"务":{"docs":{},"。":{"docs":{},"可":{"docs":{},"能":{"docs":{},"你":{"docs":{},"觉":{"docs":{},"得":{"docs":{},"这":{"docs":{},"是":{"docs":{},"理":{"docs":{},"所":{"docs":{},"当":{"docs":{},"然":{"docs":{},"的":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"你":{"docs":{},"的":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"仅":{"docs":{},"有":{"docs":{},"这":{"docs":{},"一":{"docs":{},"个":{"docs":{},"实":{"docs":{},"现":{"docs":{},",":{"docs":{},"但":{"docs":{},"你":{"docs":{},"后":{"docs":{},"面":{"docs":{},"会":{"docs":{},"为":{"docs":{},"同":{"docs":{},"一":{"docs":{},"个":{"docs":{},"接":{"docs":{},"口":{"docs":{},"提":{"docs":{},"供":{"docs":{},"多":{"docs":{},"个":{"docs":{},"实":{"docs":{},"现":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},",":{"docs":{},"有":{"docs":{},"必":{"docs":{},"要":{"docs":{},"明":{"docs":{},"确":{"docs":{},"指":{"docs":{},"定":{"docs":{},"实":{"docs":{},"现":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"复":{"docs":{},"用":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"最":{"docs":{},"后":{"docs":{},"一":{"docs":{},"步":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"。":{"docs":{},"首":{"docs":{},"先":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}},"附":{"docs":{},"加":{"docs":{},"练":{"docs":{},"习":{"docs":{},",":{"docs":{},"请":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"练":{"docs":{},"习":{"docs":{},",":{"docs":{},"请":{"docs":{},"在":{"docs":{},"这":{"docs":{},"个":{"docs":{},"页":{"docs":{},"面":{"docs":{},"添":{"docs":{},"加":{"docs":{},"更":{"docs":{},"多":{"docs":{},"管":{"docs":{},"理":{"docs":{},"功":{"docs":{},"能":{"docs":{},"特":{"docs":{},"性":{"docs":{},"。":{"docs":{},"例":{"docs":{},"如":{"docs":{},",":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"按":{"docs":{},"钮":{"docs":{},",":{"docs":{},"为":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"提":{"docs":{},"供":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"主":{"docs":{},"机":{"docs":{},"名":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"你":{"docs":{},"可":{"docs":{},"能":{"docs":{},"还":{"docs":{},"会":{"docs":{},"听":{"docs":{},"说":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"有":{"docs":{},"点":{"docs":{},"疑":{"docs":{},"惑":{"docs":{},",":{"docs":{},"为":{"docs":{},"什":{"docs":{},"么":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}},"会":{"docs":{},"纳":{"docs":{},"闷":{"docs":{},",":{"docs":{},"其":{"docs":{},"余":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}},"以":{"docs":{},"用":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"类":{"docs":{},"似":{"docs":{},"的":{"docs":{},"规":{"docs":{},"则":{"docs":{},"完":{"docs":{},"全":{"docs":{},"自":{"docs":{},"定":{"docs":{},"义":{"docs":{},"页":{"docs":{},"面":{"docs":{},"的":{"docs":{},"外":{"docs":{},"观":{"docs":{},"和":{"docs":{},"体":{"docs":{},"验":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}},"在":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"直":{"docs":{},"接":{"docs":{},"在":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"里":{"docs":{},"编":{"docs":{},"写":{"docs":{},"这":{"docs":{},"段":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"作":{"docs":{},"为":{"docs":{},"更":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"实":{"docs":{},"践":{"docs":{},",":{"docs":{},"应":{"docs":{},"该":{"docs":{},"保":{"docs":{},"持":{"docs":{},"你":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"独":{"docs":{},"立":{"docs":{},"。":{"docs":{},"为":{"docs":{},"什":{"docs":{},"么":{"docs":{},"呢":{"docs":{},"?":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"巨":{"docs":{},"大":{"docs":{},"的":{"docs":{},",":{"docs":{},"现":{"docs":{},"实":{"docs":{},"世":{"docs":{},"界":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"不":{"docs":{},"得":{"docs":{},"不":{"docs":{},"应":{"docs":{},"付":{"docs":{},"一":{"docs":{},"些":{"docs":{},"事":{"docs":{},"情":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"该":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"第":{"docs":{},"一":{"docs":{},"次":{"docs":{},"启":{"docs":{},"动":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"将":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}},"把":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"运":{"docs":{},"行":{"docs":{},"以":{"docs":{},"下":{"docs":{},"指":{"docs":{},"令":{"docs":{},"来":{"docs":{},"启":{"docs":{},"动":{"docs":{},"这":{"docs":{},"个":{"docs":{},"多":{"docs":{},"容":{"docs":{},"器":{"docs":{},"程":{"docs":{},"序":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}},"将":{"docs":{},"要":{"docs":{},"构":{"docs":{},"建":{"docs":{},"的":{"docs":{},"这":{"docs":{},"个":{"docs":{},"应":{"docs":{},"用":{"docs":{},",":{"docs":{},"其":{"docs":{},"完":{"docs":{},"整":{"docs":{},"源":{"docs":{},"码":{"docs":{},"位":{"docs":{},"于":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}},"惯":{"docs":{},"用":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":10.005347593582888}}}}}}},"代":{"docs":{},"码":{"docs":{},"就":{"docs":{},"是":{"docs":{},"通":{"docs":{},"过":{"docs":{},"它":{"docs":{},"与":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},",":{"docs":{},"进":{"docs":{},"行":{"docs":{},"读":{"docs":{},"写":{"docs":{},"的":{"docs":{},"。":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"/":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"d":{"docs":{},"b":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"目":{"docs":{},"录":{"docs":{},"结":{"docs":{},"构":{"docs":{},"看":{"docs":{},"起":{"docs":{},"来":{"docs":{},"应":{"docs":{},"该":{"docs":{},"是":{"docs":{},"这":{"docs":{},"样":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}},"已":{"docs":{},"经":{"docs":{},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"、":{"docs":{},"一":{"docs":{},"个":{"docs":{},"视":{"docs":{},"图":{"docs":{},"、":{"docs":{},"一":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"。":{"docs":{},"在":{"docs":{},"你":{"docs":{},"把":{"docs":{},"模":{"docs":{},"型":{"docs":{},"和":{"docs":{},"视":{"docs":{},"图":{"docs":{},"应":{"docs":{},"用":{"docs":{},"于":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"中":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"先":{"docs":{},"写":{"docs":{},"点":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"用":{"docs":{},"它":{"docs":{},"把":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"从":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"取":{"docs":{},"出":{"docs":{},"来":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"完":{"docs":{},"全":{"docs":{},"可":{"docs":{},"以":{"docs":{},"自":{"docs":{},"己":{"docs":{},"写":{"docs":{},"一":{"docs":{},"段":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"把":{"docs":{},"一":{"docs":{},"个":{"docs":{},"日":{"docs":{},"期":{"docs":{},"转":{"docs":{},"换":{"docs":{},"成":{"docs":{},"更":{"docs":{},"人":{"docs":{},"性":{"docs":{},"化":{"docs":{},"的":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},",":{"docs":{},"不":{"docs":{},"过":{"docs":{},"幸":{"docs":{},"运":{"docs":{},"的":{"docs":{},"是":{"docs":{},",":{"docs":{},"还":{"docs":{},"有":{"docs":{},"个":{"docs":{},"更":{"docs":{},"便":{"docs":{},"捷":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"修":{"docs":{},"改":{"docs":{},"了":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"应":{"docs":{},"该":{"docs":{},"注":{"docs":{},"意":{"docs":{},"到":{"docs":{},"相":{"docs":{},"同":{"docs":{},"的":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"模":{"docs":{},"式":{"docs":{},",":{"docs":{},"如":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}},"搭":{"docs":{},"建":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"应":{"docs":{},"用":{"docs":{},"了":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"有":{"docs":{},"了":{"docs":{},"测":{"docs":{},"试":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"覆":{"docs":{},"盖":{"docs":{},"了":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"结":{"docs":{},"构":{"docs":{},"看":{"docs":{},"起":{"docs":{},"来":{"docs":{},"应":{"docs":{},"该":{"docs":{},"是":{"docs":{},"这":{"docs":{},"样":{"docs":{},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"执":{"docs":{},"行":{"docs":{},"这":{"docs":{},"些":{"docs":{},"步":{"docs":{},"骤":{"docs":{},"一":{"docs":{},"次":{"docs":{},"。":{"docs":{},"现":{"docs":{},"在":{"docs":{},"开":{"docs":{},"始":{"docs":{},",":{"docs":{},"任":{"docs":{},"何":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"推":{"docs":{},"送":{"docs":{},"程":{"docs":{},"序":{"docs":{},"文":{"docs":{},"件":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"构":{"docs":{},"建":{"docs":{},"和":{"docs":{},"运":{"docs":{},"行":{"docs":{},"需":{"docs":{},"要":{"docs":{},"些":{"docs":{},"什":{"docs":{},"么":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"、":{"docs":{},"转":{"docs":{},"换":{"docs":{},"或":{"docs":{},"以":{"docs":{},"本":{"docs":{},"作":{"docs":{},"品":{"docs":{},"为":{"docs":{},"基":{"docs":{},"础":{"docs":{},"进":{"docs":{},"行":{"docs":{},"创":{"docs":{},"作":{"docs":{},",":{"docs":{},"在":{"docs":{},"任":{"docs":{},"何":{"docs":{},"用":{"docs":{},"途":{"docs":{},"下":{"docs":{},",":{"docs":{},"甚":{"docs":{},"至":{"docs":{},"商":{"docs":{},"业":{"docs":{},"目":{"docs":{},"的":{"docs":{},"。":{"docs":{},"您":{"docs":{},"必":{"docs":{},"须":{"docs":{},"给":{"docs":{},"出":{"docs":{},"适":{"docs":{},"当":{"docs":{},"的":{"docs":{},"署":{"docs":{},"名":{"docs":{},",":{"docs":{},"提":{"docs":{},"供":{"docs":{},"指":{"docs":{},"向":{"docs":{},"本":{"docs":{},"许":{"docs":{},"可":{"docs":{},"协":{"docs":{},"议":{"docs":{},"的":{"docs":{},"链":{"docs":{},"接":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"布":{"docs":{},"局":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":10.005813953488373}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":10.00438596491228}}}}}}}},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"类":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"该":{"docs":{},"字":{"docs":{},"段":{"docs":{},"仅":{"docs":{},"仅":{"docs":{},"影":{"docs":{},"响":{"docs":{},"该":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"本":{"docs":{},"地":{"docs":{},"拷":{"docs":{},"贝":{"docs":{},",":{"docs":{},"s":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"过":{"docs":{},"视":{"docs":{},"图":{"docs":{},"和":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},",":{"docs":{},"剩":{"docs":{},"下":{"docs":{},"的":{"docs":{},"就":{"docs":{},"是":{"docs":{},"要":{"docs":{},"添":{"docs":{},"加":{"docs":{},"缺":{"docs":{},"失":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"方":{"docs":{},"法":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}},"了":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"可":{"docs":{},"以":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}},"正":{"docs":{},"了":{"docs":{},"读":{"docs":{},"者":{"docs":{},"们":{"docs":{},"发":{"docs":{},"现":{"docs":{},"的":{"docs":{},"一":{"docs":{},"些":{"docs":{},"笔":{"docs":{},"误":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}},"倍":{"docs":{},"是":{"docs":{},"很":{"docs":{},"正":{"docs":{},"常":{"docs":{},"的":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"写":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"相":{"docs":{},"比":{"docs":{},",":{"docs":{},"执":{"docs":{},"行":{"docs":{},"速":{"docs":{},"度":{"docs":{},"高":{"docs":{},"出":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}},"过":{"docs":{},"页":{"docs":{},"面":{"docs":{},",":{"docs":{},"那":{"docs":{},"你":{"docs":{},"就":{"docs":{},"已":{"docs":{},"经":{"docs":{},"了":{"docs":{},"解":{"docs":{},"其":{"docs":{},"基":{"docs":{},"本":{"docs":{},"概":{"docs":{},"念":{"docs":{},"了":{"docs":{},".":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"测":{"docs":{},"试":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"去":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"出":{"docs":{},"现":{"docs":{},"并":{"docs":{},"把":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"于":{"docs":{},"某":{"docs":{},"种":{"docs":{},"原":{"docs":{},"因":{"docs":{},"无":{"docs":{},"效":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"会":{"docs":{},"被":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{},"路":{"docs":{},"由":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}},"显":{"docs":{},"而":{"docs":{},"易":{"docs":{},"见":{"docs":{},"的":{"docs":{},"安":{"docs":{},"全":{"docs":{},"因":{"docs":{},"素":{"docs":{},",":{"docs":{},"对":{"docs":{},"于":{"docs":{},"任":{"docs":{},"何":{"docs":{},"人":{"docs":{},"来":{"docs":{},"说":{"docs":{},",":{"docs":{},"都":{"docs":{},"不":{"docs":{},"能":{"docs":{},"自":{"docs":{},"主":{"docs":{},"的":{"docs":{},"注":{"docs":{},"册":{"docs":{},"成":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"账":{"docs":{},"号":{"docs":{},"。":{"docs":{},"事":{"docs":{},"实":{"docs":{},"上":{"docs":{},",":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"来":{"docs":{},"的":{"docs":{},"其":{"docs":{},"它":{"docs":{},"类":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"时":{"docs":{},"时":{"docs":{},"刻":{"docs":{},"专":{"docs":{},"注":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"点":{"docs":{},"上":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}},"则":{"docs":{},"不":{"docs":{},"复":{"docs":{},"存":{"docs":{},"在":{"docs":{},"了":{"docs":{},"。":{"docs":{},"整":{"docs":{},"个":{"docs":{},"处":{"docs":{},"理":{"docs":{},"管":{"docs":{},"线":{"docs":{},"由":{"docs":{},"中":{"docs":{},"间":{"docs":{},"件":{"docs":{},"驱":{"docs":{},"动":{"docs":{},",":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}},"创":{"docs":{},"作":{"docs":{},"共":{"docs":{},"用":{"docs":{},"署":{"docs":{},"名":{"4":{"docs":{},".":{"0":{"docs":{},"国":{"docs":{},"际":{"docs":{},"许":{"docs":{},"可":{"docs":{},"证":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"docs":{}}},"docs":{}}}}}},"建":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":2.501412429378531},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"简":{"docs":{},"单":{"docs":{},"但":{"docs":{},"实":{"docs":{},"用":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"新":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"这":{"docs":{},"一":{"docs":{},"次":{"docs":{},"添":{"docs":{},"加":{"docs":{},"几":{"docs":{},"个":{"docs":{},"选":{"docs":{},"项":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}},"的":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"接":{"docs":{},"口":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"名":{"docs":{},"为":{"docs":{},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"s":{"docs":{},"/":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"s":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},"夹":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{},"视":{"docs":{},"图":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"用":{"docs":{},"的":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"账":{"docs":{},"号":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"项":{"docs":{},"目":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"虚":{"docs":{},"拟":{"docs":{},"机":{"docs":{},",":{"docs":{},"在":{"docs":{},"上":{"docs":{},"面":{"docs":{},"安":{"docs":{},"装":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"镜":{"docs":{},"像":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":10.003125}}}}},"模":{"docs":{},"型":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":10.001801801801802}}}},"视":{"docs":{},"图":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":10.002409638554218}}}},"服":{"docs":{},"务":{"docs":{},"类":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":10.001805054151625}}}}},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"条":{"docs":{},"指":{"docs":{},"向":{"docs":{},"m":{"docs":{},"i":{"docs":{},"c":{"docs":{},"r":{"docs":{},"o":{"docs":{},"s":{"docs":{},"o":{"docs":{},"f":{"docs":{},"t":{"docs":{},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},".":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"的":{"docs":{},"引":{"docs":{},"用":{"docs":{},",":{"docs":{},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"便":{"docs":{},"捷":{"docs":{},"的":{"docs":{},"“":{"docs":{},"元":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"(":{"docs":{},"m":{"docs":{},"e":{"docs":{},"t":{"docs":{},"a":{"docs":{},"p":{"docs":{},"a":{"docs":{},"c":{"docs":{},"k":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},")":{"docs":{},"”":{"docs":{},",":{"docs":{},"它":{"docs":{},"引":{"docs":{},"用":{"docs":{},"了":{"docs":{},"你":{"docs":{},"在":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"其":{"docs":{},"它":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"变":{"docs":{},"更":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":10.001818181818182}},"的":{"docs":{},"最":{"docs":{},"后":{"docs":{},"一":{"docs":{},"步":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"要":{"docs":{},"应":{"docs":{},"用":{"docs":{},"它":{"docs":{},"(":{"docs":{},"们":{"docs":{},")":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}},"部":{"docs":{},"署":{"docs":{},"配":{"docs":{},"置":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}},"别":{"docs":{},"担":{"docs":{},"心":{"docs":{},",":{"docs":{},"就":{"docs":{},"算":{"docs":{},"对":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"前":{"docs":{},"端":{"docs":{},"代":{"docs":{},"码":{"docs":{},"(":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{},"、":{"docs":{},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{},"、":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},")":{"docs":{},"怎":{"docs":{},"样":{"docs":{},"与":{"docs":{},"后":{"docs":{},"端":{"docs":{},"代":{"docs":{},"码":{"docs":{},"交":{"docs":{},"互":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"言":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"它":{"docs":{},"尚":{"docs":{},"未":{"docs":{},"被":{"docs":{},"保":{"docs":{},"存":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"保":{"docs":{},"存":{"docs":{},"操":{"docs":{},"作":{"docs":{},"成":{"docs":{},"功":{"docs":{},",":{"docs":{},"s":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"面":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"缀":{"docs":{},",":{"docs":{},"使":{"docs":{},"方":{"docs":{},"法":{"docs":{},"名":{"docs":{},"构":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{},"可":{"docs":{},"读":{"docs":{},"性":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"句":{"docs":{},"子":{"docs":{},",":{"docs":{},"不":{"docs":{},"过":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"按":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{},"意":{"docs":{},"愿":{"docs":{},"选":{"docs":{},"择":{"docs":{},"命":{"docs":{},"名":{"docs":{},"风":{"docs":{},"格":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"却":{"docs":{},"已":{"docs":{},"久":{"docs":{},"经":{"docs":{},"考":{"docs":{},"验":{"docs":{},"。":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"又":{"docs":{},"一":{"docs":{},"个":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"有":{"docs":{},"什":{"docs":{},"么":{"docs":{},"可":{"docs":{},"取":{"docs":{},"之":{"docs":{},"处":{"docs":{},"呢":{"docs":{},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"比":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"反":{"docs":{},"序":{"docs":{},"列":{"docs":{},"化":{"docs":{},"、":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"连":{"docs":{},"接":{"docs":{},"、":{"docs":{},"p":{"docs":{},"d":{"docs":{},"f":{"docs":{},"生":{"docs":{},"成":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"几":{"docs":{},"乎":{"docs":{},"你":{"docs":{},"能":{"docs":{},"想":{"docs":{},"到":{"docs":{},"的":{"docs":{},"任":{"docs":{},"何":{"docs":{},"需":{"docs":{},"求":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"向":{"docs":{},"代":{"docs":{},"理":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"配":{"docs":{},"对":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{},"(":{"docs":{},"下":{"docs":{},"面":{"docs":{},"有":{"docs":{},"更":{"docs":{},"详":{"docs":{},"细":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}},"发":{"docs":{},"布":{"docs":{},"。":{"docs":{},"您":{"docs":{},"可":{"docs":{},"以":{"docs":{},"自":{"docs":{},"由":{"docs":{},"地":{"docs":{},":":{"docs":{},"共":{"docs":{},"享":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"起":{"docs":{},"一":{"docs":{},"个":{"docs":{},"调":{"docs":{},"用":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"行":{"docs":{},"版":{"docs":{},"(":{"docs":{},"例":{"docs":{},"如":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"可":{"docs":{},"能":{"docs":{},"初":{"docs":{},"出":{"docs":{},"茅":{"docs":{},"庐":{"docs":{},",":{"docs":{},"但":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"以":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"连":{"docs":{},"接":{"docs":{},"到":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"优":{"docs":{},"化":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"生":{"docs":{},"成":{"docs":{},"过":{"docs":{},"程":{"docs":{},"并":{"docs":{},"使":{"docs":{},"它":{"docs":{},"容":{"docs":{},"量":{"docs":{},"紧":{"docs":{},"凑":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}},"空":{"docs":{},"(":{"docs":{},"n":{"docs":{},"u":{"docs":{},"l":{"docs":{},"l":{"docs":{},"a":{"docs":{},"b":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"是":{"docs":{},"可":{"docs":{},"选":{"docs":{},"的":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"不":{"docs":{},"加":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}},"读":{"docs":{},"/":{"docs":{},"可":{"docs":{},"写":{"docs":{},"(":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"/":{"docs":{},"w":{"docs":{},"r":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},")":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},",":{"docs":{},"更":{"docs":{},"确":{"docs":{},"切":{"docs":{},"地":{"docs":{},"说":{"docs":{},",":{"docs":{},"它":{"docs":{},"有":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{},"服":{"docs":{},"务":{"docs":{},"集":{"docs":{},"合":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"吧":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"和":{"docs":{"./":{"ref":"./","tf":0.006183745583038869},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.006097560975609756},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0036036036036036037},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.012048192771084338},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.005194805194805195},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.01079913606911447}},"很":{"docs":{},"多":{"docs":{},"其":{"docs":{},"它":{"docs":{},"语":{"docs":{},"言":{"docs":{},"编":{"docs":{},"程":{"docs":{},"的":{"docs":{},"支":{"docs":{},"持":{"docs":{},"非":{"docs":{},"常":{"docs":{},"丰":{"docs":{},"富":{"docs":{},"。":{"docs":{},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"搜":{"docs":{},"索":{"docs":{},"“":{"docs":{},"下":{"docs":{},"载":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}}}}}}}},"模":{"docs":{},"型":{"docs":{},"类":{"docs":{},"。":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}},"密":{"docs":{},"码":{"docs":{},"进":{"docs":{},"行":{"docs":{},"登":{"docs":{},"录":{"docs":{},"的":{"docs":{},"功":{"docs":{},"能":{"docs":{},"。":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}},"其":{"docs":{},"它":{"docs":{},"主":{"docs":{},"题":{"docs":{},"的":{"docs":{},"博":{"docs":{},"文":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"任":{"docs":{},"何":{"docs":{},"媒":{"docs":{},"介":{"docs":{},"以":{"docs":{},"任":{"docs":{},"何":{"docs":{},"形":{"docs":{},"式":{"docs":{},"复":{"docs":{},"制":{"docs":{},"、":{"docs":{},"发":{"docs":{},"行":{"docs":{},"本":{"docs":{},"作":{"docs":{},"品":{"docs":{},",":{"docs":{},"演":{"docs":{},"绎":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},",":{"docs":{},"用":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"类":{"docs":{},",":{"docs":{},"取":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}},"这":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"发":{"docs":{},"现":{"docs":{},"多":{"docs":{},"出":{"docs":{},"来":{"docs":{},"几":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"。":{"docs":{},"在":{"docs":{},"你":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}},"一":{"docs":{},"章":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"探":{"docs":{},"究":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"哪":{"docs":{},"儿":{"docs":{},"?":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"端":{"docs":{},",":{"docs":{},"@":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}},"部":{"docs":{},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"条":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"视":{"docs":{},"图":{"docs":{},"中":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"查":{"docs":{},"看":{"docs":{},"认":{"docs":{},"证":{"docs":{},"状":{"docs":{},"态":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},"构":{"docs":{},"造":{"docs":{},"函":{"docs":{},"数":{"docs":{},"的":{"docs":{},"下":{"docs":{},"方":{"docs":{},",":{"docs":{},"为":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"按":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"添":{"docs":{},"加":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"对":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"进":{"docs":{},"行":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}},"模":{"docs":{},"型":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"流":{"docs":{},"程":{"docs":{},"中":{"docs":{},",":{"docs":{},"模":{"docs":{},"型":{"docs":{},"里":{"docs":{},"的":{"docs":{},"任":{"docs":{},"何":{"docs":{},"属":{"docs":{},"性":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"不":{"docs":{},"能":{"docs":{},"匹":{"docs":{},"配":{"docs":{},"到":{"docs":{},"请":{"docs":{},"求":{"docs":{},"里":{"docs":{},"的":{"docs":{},"字":{"docs":{},"段":{"docs":{},",":{"docs":{},"都":{"docs":{},"会":{"docs":{},"被":{"docs":{},"忽":{"docs":{},"略":{"docs":{},"掉":{"docs":{},"。":{"docs":{},"由":{"docs":{},"于":{"docs":{},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"仅":{"docs":{},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{},"户":{"docs":{},"访":{"docs":{},"问":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"中":{"docs":{},"某":{"docs":{},"些":{"docs":{},"特":{"docs":{},"定":{"docs":{},"内":{"docs":{},"容":{"docs":{},"时":{"docs":{},",":{"docs":{},"你":{"docs":{},"通":{"docs":{},"常":{"docs":{},"都":{"docs":{},"会":{"docs":{},"要":{"docs":{},"求":{"docs":{},"他":{"docs":{},"们":{"docs":{},"登":{"docs":{},"录":{"docs":{},"。":{"docs":{},"比":{"docs":{},"如":{"docs":{},"说":{"docs":{},",":{"docs":{},"把":{"docs":{},"主":{"docs":{},"页":{"docs":{},"向":{"docs":{},"所":{"docs":{},"有":{"docs":{},"人":{"docs":{},"展":{"docs":{},"示":{"docs":{},"是":{"docs":{},"合":{"docs":{},"理":{"docs":{},"的":{"docs":{},"(":{"docs":{},"不":{"docs":{},"管":{"docs":{},"你":{"docs":{},"有":{"docs":{},"没":{"docs":{},"有":{"docs":{},"登":{"docs":{},"录":{"docs":{},")":{"docs":{},",":{"docs":{},"但":{"docs":{},"只":{"docs":{},"在":{"docs":{},"登":{"docs":{},"录":{"docs":{},"之":{"docs":{},"后":{"docs":{},"才":{"docs":{},"向":{"docs":{},"你":{"docs":{},"展":{"docs":{},"示":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"。":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"中":{"docs":{},"使":{"docs":{},"用":{"docs":{},"身":{"docs":{},"份":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":10.000995024875621}}}}}}},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},",":{"docs":{},"也":{"docs":{},"就":{"docs":{},"是":{"docs":{},"最":{"docs":{},"外":{"docs":{},"层":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},"方":{"docs":{},"法":{"docs":{},"下":{"docs":{},"面":{"docs":{},"再":{"docs":{},"添":{"docs":{},"加":{"docs":{},"两":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{},",":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},"方":{"docs":{},"法":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"此":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}},"网":{"docs":{},"络":{"docs":{},"应":{"docs":{},"用":{"docs":{},"里":{"docs":{},",":{"docs":{},"角":{"docs":{},"色":{"docs":{},"是":{"docs":{},"用":{"docs":{},"于":{"docs":{},"处":{"docs":{},"理":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}},"本":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}},"章":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"学":{"docs":{},"习":{"docs":{},"如":{"docs":{},"何":{"docs":{},"编":{"docs":{},"写":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}}}}}}}},"开":{"docs":{},"头":{"docs":{},",":{"docs":{},"我":{"docs":{},"提":{"docs":{},"到":{"docs":{},"过":{"docs":{},",":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},",":{"docs":{},"运":{"docs":{},"行":{"docs":{},"以":{"docs":{},"下":{"docs":{},"命":{"docs":{},"令":{"docs":{},"(":{"docs":{},"请":{"docs":{},"确":{"docs":{},"保":{"docs":{},"你":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}},"运":{"docs":{},"行":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"每":{"docs":{},"次":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"执":{"docs":{},"行":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"进":{"docs":{},"行":{"docs":{},"一":{"docs":{},"些":{"docs":{},"配":{"docs":{},"置":{"docs":{},"。":{"docs":{},"为":{"docs":{},"免":{"docs":{},"配":{"docs":{},"置":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"把":{"docs":{},"测":{"docs":{},"试":{"docs":{},"代":{"docs":{},"码":{"docs":{},"弄":{"docs":{},"的":{"docs":{},"乱":{"docs":{},"七":{"docs":{},"八":{"docs":{},"糟":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"把":{"docs":{},"配":{"docs":{},"置":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"提":{"docs":{},"取":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"类":{"docs":{},"里":{"docs":{},"。":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"当":{"docs":{},"前":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"查":{"docs":{},"找":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}},"增":{"docs":{},"添":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"新":{"docs":{},"工":{"docs":{},"具":{"docs":{},",":{"docs":{},"并":{"docs":{},"复":{"docs":{},"用":{"docs":{},"(":{"docs":{},"及":{"docs":{},"简":{"docs":{},"化":{"docs":{},")":{"docs":{},"了":{"docs":{},"你":{"docs":{},"用":{"docs":{},"过":{"docs":{},"的":{"docs":{},"那":{"docs":{},"些":{"docs":{},"东":{"docs":{},"西":{"docs":{},"。":{"docs":{},"我":{"docs":{},"将":{"docs":{},"在":{"docs":{},"后":{"docs":{},"续":{"docs":{},"章":{"docs":{},"节":{"docs":{},"指":{"docs":{},"出":{"docs":{},"部":{"docs":{},"分":{"docs":{},"差":{"docs":{},"异":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"多":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},",":{"docs":{},"后":{"docs":{},"者":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"数":{"docs":{},"较":{"docs":{},"大":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"种":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}},"级":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"重":{"docs":{},"身":{"docs":{},"份":{"docs":{},"认":{"docs":{},"证":{"docs":{},"流":{"docs":{},"程":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}},"好":{"docs":{},"了":{"docs":{},",":{"docs":{},"前":{"docs":{},"言":{"docs":{},"就":{"docs":{},"到":{"docs":{},"这":{"docs":{},"儿":{"docs":{},"。":{"docs":{},"开":{"docs":{},"始":{"docs":{},"学":{"docs":{},"习":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"模":{"docs":{},"型":{"docs":{},"也":{"docs":{},"有":{"docs":{},"了":{"docs":{},",":{"docs":{},"是":{"docs":{},"时":{"docs":{},"候":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"接":{"docs":{},"收":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}},"当":{"docs":{},"一":{"docs":{},"个":{"docs":{},"请":{"docs":{},"求":{"docs":{},"进":{"docs":{},"来":{"docs":{},",":{"docs":{},"将":{"docs":{},"会":{"docs":{},"被":{"docs":{},"发":{"docs":{},"送":{"docs":{},"到":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}},"如":{"docs":{},"何":{"docs":{},"添":{"docs":{},"加":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"进":{"docs":{},"行":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"读":{"docs":{},"写":{"docs":{},"操":{"docs":{},"作":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}},"部":{"docs":{},"署":{"docs":{},"该":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"到":{"docs":{},"网":{"docs":{},"络":{"docs":{},"上":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}},"果":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"你":{"docs":{},"从":{"docs":{},"没":{"docs":{},"用":{"docs":{},"过":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"刚":{"docs":{},"开":{"docs":{},"始":{"docs":{},"编":{"docs":{},"程":{"docs":{},",":{"docs":{},"本":{"docs":{},"书":{"docs":{},"将":{"docs":{},"在":{"docs":{},"“":{"docs":{},"构":{"docs":{},"建":{"docs":{},"最":{"docs":{},"新":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"应":{"docs":{},"用":{"docs":{},"”":{"docs":{},"方":{"docs":{},"面":{"docs":{},",":{"docs":{},"使":{"docs":{},"你":{"docs":{},"了":{"docs":{},"解":{"docs":{},"其":{"docs":{},"中":{"docs":{},"的":{"docs":{},"模":{"docs":{},"式":{"docs":{},"和":{"docs":{},"概":{"docs":{},"念":{"docs":{},"。":{"docs":{},"你":{"docs":{},"将":{"docs":{},"以":{"docs":{},"从":{"docs":{},"无":{"docs":{},"到":{"docs":{},"有":{"docs":{},"、":{"docs":{},"循":{"docs":{},"序":{"docs":{},"渐":{"docs":{},"进":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},",":{"docs":{},"学":{"docs":{},"习":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"已":{"docs":{},"经":{"docs":{},"在":{"docs":{},"使":{"docs":{},"用":{"docs":{},"诸":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"被":{"docs":{},"这":{"docs":{},"些":{"docs":{},"命":{"docs":{},"名":{"docs":{},"搞":{"docs":{},"糊":{"docs":{},"涂":{"docs":{},"了":{"docs":{},",":{"docs":{},"别":{"docs":{},"发":{"docs":{},"愁":{"docs":{},"!":{"docs":{},"咱":{"docs":{},"们":{"docs":{},"马":{"docs":{},"上":{"docs":{},"就":{"docs":{},"要":{"docs":{},"写":{"docs":{},"代":{"docs":{},"码":{"docs":{},"进":{"docs":{},"行":{"docs":{},"实":{"docs":{},"践":{"docs":{},"了":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"现":{"docs":{},"存":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"请":{"docs":{},"在":{"docs":{},"网":{"docs":{},"络":{"docs":{},"上":{"docs":{},"搜":{"docs":{},"索":{"docs":{},"“":{"docs":{},"s":{"docs":{},"c":{"docs":{},"a":{"docs":{},"f":{"docs":{},"f":{"docs":{},"o":{"docs":{},"l":{"docs":{},"d":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"初":{"docs":{},"次":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"在":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}},"老":{"docs":{},"式":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"顶":{"docs":{},"层":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},"执":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}},"看":{"docs":{},"到":{"docs":{},"类":{"docs":{},"似":{"docs":{},"于":{"docs":{},"上":{"docs":{},"面":{"docs":{},"的":{"docs":{},"输":{"docs":{},"出":{"docs":{},",":{"docs":{},"就":{"docs":{},"大":{"docs":{},"步":{"docs":{},"前":{"docs":{},"进":{"docs":{},"吧":{"docs":{},"。":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}}}}}}}}}},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"报":{"docs":{},"错":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"完":{"docs":{},"善":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"如":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"了":{"docs":{},"解":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"还":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"没":{"docs":{},"在":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}},"用":{"docs":{},"其":{"docs":{},"它":{"docs":{},"开":{"docs":{},"发":{"docs":{},"语":{"docs":{},"言":{"docs":{},"写":{"docs":{},"过":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}},"的":{"docs":{},"是":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"账":{"docs":{},"号":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"将":{"docs":{},"在":{"docs":{},"右":{"docs":{},"上":{"docs":{},"角":{"docs":{},"见":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"导":{"docs":{},"航":{"docs":{},"项":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"网":{"docs":{},"络":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"没":{"docs":{},"自":{"docs":{},"动":{"docs":{},"弹":{"docs":{},"出":{"docs":{},"来":{"docs":{},",":{"docs":{},"打":{"docs":{},"开":{"docs":{},"它":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}},"浏":{"docs":{},"览":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"想":{"docs":{},"回":{"docs":{},"滚":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"提":{"docs":{},"供":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}},"打":{"docs":{},"开":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"更":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"看":{"docs":{},"到":{"docs":{},"两":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"名":{"docs":{},"字":{"docs":{},"分":{"docs":{},"别":{"docs":{},"是":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}},"按":{"docs":{},"原":{"docs":{},"样":{"docs":{},"执":{"docs":{},"行":{"docs":{},"变":{"docs":{},"更":{"docs":{},",":{"docs":{},"会":{"docs":{},"遭":{"docs":{},"遇":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"立":{"docs":{},"刻":{"docs":{},"运":{"docs":{},"行":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"还":{"docs":{},"是":{"docs":{},"没":{"docs":{},"什":{"docs":{},"么":{"docs":{},"作":{"docs":{},"用":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"没":{"docs":{},"有":{"docs":{},"提":{"docs":{},"交":{"docs":{},"按":{"docs":{},"钮":{"docs":{},"通":{"docs":{},"知":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},",":{"docs":{},"让":{"docs":{},"它":{"docs":{},"根":{"docs":{},"据":{"docs":{},"表":{"docs":{},"单":{"docs":{},"数":{"docs":{},"据":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"运":{"docs":{},"行":{"docs":{},"程":{"docs":{},"序":{"docs":{},"并":{"docs":{},"注":{"docs":{},"册":{"docs":{},"或":{"docs":{},"者":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"又":{"docs":{},"一":{"docs":{},"次":{"docs":{},"见":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{},"空":{"docs":{},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}},"愿":{"docs":{},"意":{"docs":{},",":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"修":{"docs":{},"改":{"docs":{},"之":{"docs":{},"前":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}},"可":{"docs":{},"以":{"docs":{},"把":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"和":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"放":{"docs":{},"置":{"docs":{},"在":{"docs":{},"同":{"docs":{},"一":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},"。":{"docs":{},"对":{"docs":{},"大":{"docs":{},"型":{"docs":{},"项":{"docs":{},"目":{"docs":{},"而":{"docs":{},"言":{"docs":{},",":{"docs":{},"通":{"docs":{},"常":{"docs":{},"会":{"docs":{},"把":{"docs":{},"它":{"docs":{},"们":{"docs":{},"分":{"docs":{},"开":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"于":{"docs":{},"它":{"docs":{},"们":{"docs":{},"各":{"docs":{},"自":{"docs":{},"独":{"docs":{},"立":{"docs":{},"运":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"当":{"docs":{},"前":{"docs":{},"在":{"docs":{},"你":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},",":{"docs":{},"向":{"docs":{},"上":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}},"此":{"docs":{},"刻":{"docs":{},"位":{"docs":{},"于":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},",":{"docs":{},"c":{"docs":{},"d":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}},"不":{"docs":{},"在":{"docs":{},"意":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"想":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"把":{"docs":{},"程":{"docs":{},"序":{"docs":{},"托":{"docs":{},"管":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"更":{"docs":{},"喜":{"docs":{},"欢":{"docs":{},"通":{"docs":{},"过":{"docs":{},"视":{"docs":{},"频":{"docs":{},"学":{"docs":{},"习":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"与":{"docs":{},"你":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"做":{"docs":{},"对":{"docs":{},"比":{"docs":{},",":{"docs":{},"可":{"docs":{},"任":{"docs":{},"意":{"docs":{},"下":{"docs":{},"载":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"这":{"docs":{},"种":{"docs":{},"语":{"docs":{},"法":{"docs":{},"让":{"docs":{},"你":{"docs":{},"看":{"docs":{},"上":{"docs":{},"去":{"docs":{},"感":{"docs":{},"到":{"docs":{},"困":{"docs":{},"惑":{"docs":{},",":{"docs":{},"就":{"docs":{},"这":{"docs":{},"么":{"docs":{},"理":{"docs":{},"解":{"docs":{},":":{"docs":{},"“":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}},"想":{"docs":{},"使":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"变":{"docs":{},"简":{"docs":{},"短":{"docs":{},"一":{"docs":{},"点":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"删":{"docs":{},"除":{"docs":{},"中":{"docs":{},"间":{"docs":{},"变":{"docs":{},"量":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}},"当":{"docs":{},"前":{"docs":{},"用":{"docs":{},"户":{"docs":{},"已":{"docs":{},"经":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"不":{"docs":{},"存":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}},"传":{"docs":{},"入":{"docs":{},"一":{"docs":{},"个":{"docs":{},"不":{"docs":{},"存":{"docs":{},"在":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"要":{"docs":{},"深":{"docs":{},"入":{"docs":{},"学":{"docs":{},"习":{"docs":{},",":{"docs":{},"以":{"docs":{},"下":{"docs":{},"这":{"docs":{},"些":{"docs":{},"方":{"docs":{},"式":{"docs":{},"可":{"docs":{},"供":{"docs":{},"参":{"docs":{},"考":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"所":{"docs":{},"见":{"docs":{},",":{"docs":{},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"与":{"docs":{},"身":{"docs":{},"份":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"是":{"docs":{},"任":{"docs":{},"何":{"docs":{},"现":{"docs":{},"代":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"和":{"docs":{},"身":{"docs":{},"份":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":10.002840909090908}}}}}},"装":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}},"已":{"docs":{},"经":{"docs":{},"被":{"docs":{},"翻":{"docs":{},"译":{"docs":{},"成":{"docs":{},"其":{"docs":{},"它":{"docs":{},"语":{"docs":{},"言":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"在":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}},"由":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"从":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},"包":{"docs":{},"括":{"docs":{},"了":{"docs":{},"你":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"一":{"docs":{},"切":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}},"保":{"docs":{},"存":{"docs":{},"好":{"docs":{},"了":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"应":{"docs":{},"用":{"docs":{},"、":{"docs":{},"a":{"docs":{},"p":{"docs":{},"i":{"docs":{},"、":{"docs":{},"微":{"docs":{},"服":{"docs":{},"务":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"你":{"docs":{},"将":{"docs":{},"学":{"docs":{},"习":{"docs":{},"如":{"docs":{},"何":{"docs":{},"通":{"docs":{},"过":{"docs":{},"前":{"docs":{},"后":{"docs":{},"端":{"docs":{},"代":{"docs":{},"码":{"docs":{},"实":{"docs":{},"现":{"docs":{},"设":{"docs":{},"计":{"docs":{},"目":{"docs":{},"标":{"docs":{},",":{"docs":{},"如":{"docs":{},"何":{"docs":{},"与":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},",":{"docs":{},"如":{"docs":{},"何":{"docs":{},"部":{"docs":{},"署":{"docs":{},"应":{"docs":{},"用":{"docs":{},"到":{"docs":{},"真":{"docs":{},"实":{"docs":{},"环":{"docs":{},"境":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"(":{"docs":{},"以":{"docs":{},"及":{"docs":{},"合":{"docs":{},"理":{"docs":{},"组":{"docs":{},"织":{"docs":{},"各":{"docs":{},"模":{"docs":{},"块":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},")":{"docs":{},"。":{"docs":{},"对":{"docs":{},"于":{"docs":{},"你":{"docs":{},"在":{"docs":{},"编":{"docs":{},"程":{"docs":{},"方":{"docs":{},"面":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"本":{"docs":{},"书":{"docs":{},"不":{"docs":{},"能":{"docs":{},"事":{"docs":{},"无":{"docs":{},"巨":{"docs":{},"细":{"docs":{},"的":{"docs":{},"涵":{"docs":{},"盖":{"docs":{},",":{"docs":{},"但":{"docs":{},"它":{"docs":{},"可":{"docs":{},"以":{"docs":{},"作":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"起":{"docs":{},"点":{"docs":{},",":{"docs":{},"引":{"docs":{},"导":{"docs":{},"你":{"docs":{},"了":{"docs":{},"解":{"docs":{},"更":{"docs":{},"高":{"docs":{},"级":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"部":{"docs":{},"分":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"命":{"docs":{},"令":{"docs":{},"行":{"docs":{},"工":{"docs":{},"具":{"docs":{},"。":{"docs":{},"它":{"docs":{},"可":{"docs":{},"以":{"docs":{},"安":{"docs":{},"装":{"docs":{},"在":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}},"。":{"docs":{},"这":{"docs":{},"需":{"docs":{},"要":{"docs":{},"用":{"docs":{},"到":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},"当":{"docs":{},"然":{"docs":{},",":{"docs":{},"只":{"docs":{},"要":{"docs":{},"你":{"docs":{},"愿":{"docs":{},"意":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"使":{"docs":{},"用":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"(":{"docs":{},"有":{"docs":{},"时":{"docs":{},"也":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{},"“":{"docs":{},"后":{"docs":{},"端":{"docs":{},"”":{"docs":{},")":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}},"了":{"docs":{},"么":{"docs":{},"?":{"docs":{},"先":{"docs":{},"做":{"docs":{},"点":{"docs":{},"“":{"docs":{},"利":{"docs":{},"其":{"docs":{},"器":{"docs":{},"”":{"docs":{},"的":{"docs":{},"事":{"docs":{},":":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}},"变":{"docs":{},"更":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"或":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}},"该":{"docs":{},"把":{"docs":{},"服":{"docs":{},"务":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"到":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"网":{"docs":{},"卡":{"docs":{},"和":{"docs":{},"端":{"docs":{},"口":{"docs":{},"上":{"docs":{},"(":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},"时":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}},"开":{"docs":{},"发":{"docs":{},"者":{"docs":{},"注":{"docs":{},"意":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},",":{"docs":{},"将":{"docs":{},"如":{"docs":{},"鱼":{"docs":{},"得":{"docs":{},"水":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"。":{"docs":{},"你":{"docs":{},"每":{"docs":{},"次":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}},"始":{"docs":{},"之":{"docs":{},"前":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"开":{"docs":{},"发":{"docs":{},"机":{"docs":{},"上":{"docs":{},"安":{"docs":{},"装":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}},"启":{"docs":{},"你":{"docs":{},"的":{"docs":{},"网":{"docs":{},"络":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}},"彻":{"docs":{},"底":{"docs":{},"的":{"docs":{},"重":{"docs":{},"写":{"docs":{},",":{"docs":{},"重":{"docs":{},"点":{"docs":{},"关":{"docs":{},"注":{"docs":{},"于":{"docs":{},":":{"docs":{},"让":{"docs":{},"该":{"docs":{},"框":{"docs":{},"架":{"docs":{},"应":{"docs":{},"用":{"docs":{},"新":{"docs":{},"的":{"docs":{},"开":{"docs":{},"发":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"并":{"docs":{},"最":{"docs":{},"终":{"docs":{},"使":{"docs":{},"其":{"docs":{},"与":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"很":{"docs":{},"快":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"微":{"docs":{},"软":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"开":{"docs":{},"发":{"docs":{},"团":{"docs":{},"队":{"docs":{},"很":{"docs":{},"注":{"docs":{},"重":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"感":{"docs":{},"谢":{"docs":{},"你":{"docs":{},"选":{"docs":{},"择":{"docs":{},"这":{"docs":{},"本":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"读":{"docs":{},"完":{"docs":{},"了":{"docs":{},"这":{"docs":{},"本":{"docs":{},"简":{"docs":{},"明":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}},"那":{"docs":{},"些":{"docs":{},"多":{"docs":{},"语":{"docs":{},"言":{"docs":{},"的":{"docs":{},"投":{"docs":{},"稿":{"docs":{},"者":{"docs":{},",":{"docs":{},"简":{"docs":{},"明":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}},"或":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"者":{"docs":{"./":{"ref":"./","tf":0.00265017667844523},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"任":{"docs":{},"何":{"docs":{},"你":{"docs":{},"喜":{"docs":{},"欢":{"docs":{},"的":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"还":{"docs":{},"没":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"惯":{"docs":{},"用":{"docs":{},"的":{"docs":{},",":{"docs":{},"请":{"docs":{},"试":{"docs":{},"试":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}}}}}}}}},"其":{"docs":{},"它":{"docs":{},"语":{"docs":{},"言":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"过":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},"说":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},"以":{"docs":{},"上":{"docs":{},"版":{"docs":{},"本":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}},"整":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"时":{"docs":{},",":{"docs":{},"要":{"docs":{},"事":{"docs":{},"先":{"docs":{},"登":{"docs":{},"录":{"docs":{},"过":{"docs":{},"。":{"docs":{},"要":{"docs":{},"为":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}}}},"所":{"docs":{},"覆":{"docs":{},"盖":{"docs":{},"的":{"docs":{},"广":{"docs":{},"度":{"docs":{},")":{"docs":{},"。":{"docs":{},"比":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"有":{"docs":{},"其":{"docs":{},"它":{"docs":{},"地":{"docs":{},"方":{"docs":{},"你":{"docs":{},"都":{"docs":{},"应":{"docs":{},"该":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}},"手":{"docs":{},"册":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395}},"!":{"docs":{},"我":{"docs":{},"写":{"docs":{},"这":{"docs":{},"本":{"docs":{},"小":{"docs":{},"书":{"docs":{},"的":{"docs":{},"目":{"docs":{},"的":{"docs":{},",":{"docs":{},"是":{"docs":{},"帮":{"docs":{},"助":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}},"如":{"docs":{},"果":{"docs":{},"这":{"docs":{},"本":{"docs":{},"书":{"docs":{},"有":{"docs":{},"点":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"没":{"docs":{},"有":{"docs":{},")":{"docs":{},"用":{"docs":{},"处":{"docs":{},",":{"docs":{},"我":{"docs":{},"很":{"docs":{},"乐":{"docs":{},"于":{"docs":{},"倾":{"docs":{},"听":{"docs":{},"您":{"docs":{},"的":{"docs":{},"想":{"docs":{},"法":{"docs":{},"。":{"docs":{},"请":{"docs":{},"在":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"我":{"docs":{},"热":{"docs":{},"爱":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}},"推":{"docs":{},"向":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"数":{"docs":{},"量":{"docs":{},",":{"docs":{},"比":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"据":{"docs":{},"库":{"docs":{},"引":{"docs":{},"擎":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}},"协":{"docs":{},"作":{"docs":{},"。":{"docs":{},"在":{"docs":{},"本":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"开":{"docs":{},"发":{"docs":{},"过":{"docs":{},"程":{"docs":{},"中":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"以":{"docs":{},"简":{"docs":{},"化":{"docs":{},"安":{"docs":{},"装":{"docs":{},"和":{"docs":{},"配":{"docs":{},"置":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}},"(":{"docs":{},"必":{"docs":{},"须":{"docs":{},"地":{"docs":{},"呀":{"docs":{},")":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}},"(":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}},"、":{"docs":{},"连":{"docs":{},"接":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"类":{"docs":{},"型":{"docs":{},"。":{"docs":{},"感":{"docs":{},"谢":{"docs":{},"项":{"docs":{},"目":{"docs":{},"模":{"docs":{},"板":{"docs":{},":":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}},"这":{"docs":{},"边":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"不":{"docs":{},"多":{"docs":{},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}},"已":{"docs":{},"经":{"docs":{},"配":{"docs":{},"置":{"docs":{},"好":{"docs":{},"待":{"docs":{},"用":{"docs":{},"了":{"docs":{},"。":{"docs":{},"但":{"docs":{},"是":{"docs":{},"还":{"docs":{},"没":{"docs":{},"有":{"docs":{},"表":{"docs":{},"用":{"docs":{},"于":{"docs":{},"保":{"docs":{},"存":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}},"文":{"docs":{},"件":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"的":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"名":{"docs":{},"字":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"局":{"docs":{},"限":{"docs":{},"性":{"docs":{},"带":{"docs":{},"来":{"docs":{},"的":{"docs":{},"问":{"docs":{},"题":{"docs":{},",":{"docs":{},"要":{"docs":{},"修":{"docs":{},"复":{"docs":{},"它":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"这":{"docs":{},"样":{"docs":{},"绕":{"docs":{},"开":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}},"和":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"都":{"docs":{},"已":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"。":{"docs":{},"接":{"docs":{},"下":{"docs":{},"来":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"在":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"使":{"docs":{},"用":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}},"传":{"docs":{},"输":{"docs":{},"对":{"docs":{},"象":{"docs":{},"(":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}},"新":{"docs":{},"功":{"docs":{},"能":{"docs":{},"提":{"docs":{},"交":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"建":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"条":{"docs":{},"目":{"docs":{},"应":{"docs":{},"该":{"docs":{},"总":{"docs":{},"是":{"docs":{},"从":{"docs":{},"现":{"docs":{},"在":{"docs":{},"开":{"docs":{},"始":{"3":{"docs":{},"天":{"docs":{},"后":{"docs":{},"过":{"docs":{},"期":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"docs":{}}}}}},"未":{"docs":{},"完":{"docs":{},"成":{"docs":{},"状":{"docs":{},"态":{"docs":{},"(":{"docs":{},"i":{"docs":{},"s":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}},"的":{"docs":{},"标":{"docs":{},"题":{"docs":{},"应":{"docs":{},"该":{"docs":{},"复":{"docs":{},"制":{"docs":{},"自":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"是":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"一":{"docs":{},"个":{"docs":{},"平":{"docs":{},"台":{"docs":{},"无":{"docs":{},"关":{"docs":{},"的":{"docs":{},"接":{"docs":{},"口":{"docs":{},",":{"docs":{},"它":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"特":{"docs":{},"性":{"docs":{},"和":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}},"由":{"docs":{},"微":{"docs":{},"软":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},",":{"docs":{},"用":{"docs":{},"于":{"docs":{},"构":{"docs":{},"建":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"仅":{"docs":{},"关":{"docs":{},"注":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"操":{"docs":{},"作":{"docs":{},"(":{"docs":{},"不":{"docs":{},"处":{"docs":{},"理":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},")":{"docs":{},"的":{"docs":{},"类":{"docs":{},"。":{"docs":{},"咱":{"docs":{},"们":{"docs":{},"眼":{"docs":{},"下":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},",":{"docs":{},"为":{"docs":{},"简":{"docs":{},"化":{"docs":{},"操":{"docs":{},"作":{"docs":{},",":{"docs":{},"我":{"docs":{},"们":{"docs":{},"将":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"混":{"docs":{},"进":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"里":{"docs":{},",":{"docs":{},"不":{"docs":{},"过":{"docs":{},"你":{"docs":{},"尽":{"docs":{},"可":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"采":{"docs":{},"用":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"去":{"docs":{},"架":{"docs":{},"构":{"docs":{},"你":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"轻":{"docs":{},"量":{"docs":{},"级":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"引":{"docs":{},"擎":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"运":{"docs":{},"行":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"机":{"docs":{},"器":{"docs":{},"上":{"docs":{},"而":{"docs":{},"不":{"docs":{},"必":{"docs":{},"安":{"docs":{},"装":{"docs":{},"任":{"docs":{},"何":{"docs":{},"额":{"docs":{},"外":{"docs":{},"工":{"docs":{},"具":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"在":{"docs":{},"开":{"docs":{},"发":{"docs":{},"环":{"docs":{},"境":{"docs":{},"下":{"docs":{},"使":{"docs":{},"用":{"docs":{},"起":{"docs":{},"来":{"docs":{},"既":{"docs":{},"方":{"docs":{},"便":{"docs":{},"又":{"docs":{},"快":{"docs":{},"捷":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"常":{"docs":{},"用":{"docs":{},"的":{"docs":{},"针":{"docs":{},"对":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"可":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"对":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"最":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"选":{"docs":{},"择":{"docs":{},",":{"docs":{},"我":{"docs":{},"在":{"docs":{},"本":{"docs":{},"书":{"docs":{},"中":{"docs":{},"也":{"docs":{},"会":{"docs":{},"采":{"docs":{},"用":{"docs":{},"它":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}},"编":{"docs":{},"译":{"docs":{},"运":{"docs":{},"行":{"docs":{},"的":{"docs":{},",":{"docs":{},"执":{"docs":{},"行":{"docs":{},"速":{"docs":{},"度":{"docs":{},"远":{"docs":{},"高":{"docs":{},"于":{"docs":{},"解":{"docs":{},"释":{"docs":{},"执":{"docs":{},"行":{"docs":{},"的":{"docs":{},"语":{"docs":{},"言":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}},"随":{"docs":{},"机":{"docs":{},"生":{"docs":{},"产":{"docs":{},"的":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"就":{"docs":{},"你":{"docs":{},"不":{"docs":{},"必":{"docs":{},"再":{"docs":{},"担":{"docs":{},"心":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}},"的":{"docs":{},",":{"docs":{},"并":{"docs":{},"极":{"docs":{},"少":{"docs":{},"会":{"docs":{},"有":{"docs":{},"重":{"docs":{},"复":{"docs":{},"值":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"常":{"docs":{},"被":{"docs":{},"用":{"docs":{},"作":{"docs":{},"唯":{"docs":{},"一":{"docs":{},"标":{"docs":{},"识":{"docs":{},"。":{"docs":{},"你":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"数":{"docs":{},"字":{"docs":{},"(":{"docs":{},"整":{"docs":{},"形":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"的":{"docs":{},"建":{"docs":{},"议":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},",":{"docs":{},"而":{"docs":{},"不":{"docs":{},"是":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}},"异":{"docs":{},"步":{"docs":{},"的":{"docs":{},"(":{"docs":{},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}},"什":{"docs":{},"么":{"docs":{},"?":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"在":{"docs":{},"问":{"docs":{},":":{"docs":{},"“":{"docs":{},"我":{"docs":{},"知":{"docs":{},"道":{"docs":{},"这":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"是":{"docs":{},"谁":{"docs":{},"吗":{"docs":{},"?":{"docs":{},"”":{"docs":{},",":{"docs":{},"而":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}},"免":{"docs":{},"费":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"个":{"docs":{},"帮":{"docs":{},"助":{"docs":{},"你":{"docs":{},"创":{"docs":{},"建":{"docs":{},"并":{"docs":{},"运":{"docs":{},"行":{"docs":{},"多":{"docs":{},"容":{"docs":{},"器":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"工":{"docs":{},"具":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"配":{"docs":{},"置":{"docs":{},"文":{"docs":{},"件":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"两":{"docs":{},"个":{"docs":{},"容":{"docs":{},"器":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"本":{"docs":{},"书":{"docs":{},"的":{"docs":{},"目":{"docs":{},"标":{"docs":{},"读":{"docs":{},"者":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"章":{"docs":{},"总":{"docs":{},"结":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"标":{"docs":{},"准":{"docs":{"./":{"ref":"./","tf":0.0017667844522968198}},"中":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"并":{"docs":{},"不":{"docs":{},"等":{"docs":{},"同":{"docs":{},"于":{"docs":{},"任":{"docs":{},"何":{"docs":{},"实":{"docs":{},"际":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"或":{"docs":{},"者":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"仅":{"docs":{},"仅":{"docs":{},"是":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}},"现":{"docs":{},"存":{"docs":{},"多":{"docs":{},"个":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{},"“":{"docs":{},"版":{"docs":{},"本":{"docs":{},"”":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"级":{"docs":{},"别":{"docs":{},",":{"docs":{},"反":{"docs":{},"映":{"docs":{},"出":{"docs":{},"提":{"docs":{},"供":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}},"识":{"docs":{},"符":{"docs":{},"(":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"f":{"docs":{},"i":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},".":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}},"会":{"docs":{},"将":{"docs":{},"结":{"docs":{},"果":{"docs":{},"输":{"docs":{},"出":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}},"告":{"docs":{},"诉":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"签":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},"上":{"docs":{},",":{"docs":{},"应":{"docs":{},"用":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"记":{"docs":{},",":{"docs":{},"d":{"docs":{},"u":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"框":{"docs":{},"架":{"docs":{},"。":{"docs":{},"它":{"docs":{},"使":{"docs":{},"用":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"模":{"docs":{},"式":{"docs":{},",":{"docs":{},"诸":{"docs":{},"如":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"i":{"docs":{},"o":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}},"选":{"docs":{},"项":{"docs":{},"已":{"docs":{},"经":{"docs":{},"很":{"docs":{},"多":{"docs":{},"了":{"docs":{},":":{"docs":{},"n":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"/":{"docs":{},"e":{"docs":{},"x":{"docs":{},"p":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"s":{"docs":{},"、":{"docs":{},"s":{"docs":{},"p":{"docs":{},"r":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"、":{"docs":{},"r":{"docs":{},"u":{"docs":{},"b":{"docs":{},"i":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},")":{"docs":{},"的":{"docs":{},"知":{"docs":{},"识":{"docs":{},"。":{"docs":{},"我":{"docs":{},"会":{"docs":{},"偶":{"docs":{},"尔":{"docs":{},"提":{"docs":{},"及":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},",":{"docs":{},"需":{"docs":{},"求":{"docs":{},"何":{"docs":{},"在":{"docs":{},"?":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"并":{"docs":{},"移":{"docs":{},"除":{"docs":{},"了":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"模":{"docs":{},"式":{"docs":{},"的":{"docs":{},"基":{"docs":{},"本":{"docs":{},"内":{"docs":{},"容":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"是":{"docs":{},"很":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"网":{"docs":{},"络":{"docs":{},")":{"docs":{},"响":{"docs":{},"应":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"它":{"docs":{},"不":{"docs":{},"可":{"docs":{},"能":{"docs":{},"给":{"docs":{},"出":{"docs":{},"实":{"docs":{},"际":{"docs":{},"的":{"docs":{},"结":{"docs":{},"果":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"移":{"docs":{},"除":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"型":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}},"代":{"docs":{},"表":{"docs":{},"单":{"docs":{},"一":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"而":{"docs":{},"视":{"docs":{},"图":{"docs":{},"则":{"docs":{},"需":{"docs":{},"要":{"docs":{},"展":{"docs":{},"示":{"docs":{},"两":{"docs":{},"个":{"docs":{},"、":{"docs":{},"十":{"docs":{},"个":{"docs":{},",":{"docs":{},"甚":{"docs":{},"至":{"docs":{},"是":{"docs":{},"一":{"docs":{},"百":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"(":{"docs":{},"取":{"docs":{},"决":{"docs":{},"于":{"docs":{},"用":{"docs":{},"户":{"docs":{},"拖":{"docs":{},"延":{"docs":{},"症":{"docs":{},"的":{"docs":{},"病":{"docs":{},"情":{"docs":{},"轻":{"docs":{},"重":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"(":{"docs":{},"p":{"docs":{},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}},"。":{"docs":{},"当":{"docs":{},"它":{"docs":{},"在":{"docs":{},"这":{"docs":{},"里":{"docs":{},"作":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"一":{"docs":{},"起":{"docs":{},"使":{"docs":{},"用":{"docs":{},"。":{"docs":{},"它":{"docs":{},"促":{"docs":{},"成":{"docs":{},"了":{"docs":{},"以":{"docs":{},"下":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}},"核":{"docs":{},"验":{"docs":{},"操":{"docs":{},"作":{"docs":{},"(":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"的":{"docs":{},"替":{"docs":{},"代":{"docs":{},"方":{"docs":{},"案":{"docs":{},",":{"docs":{},"还":{"docs":{},"可":{"docs":{},"以":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"模":{"docs":{},"型":{"docs":{},"(":{"docs":{},"比":{"docs":{},"如":{"docs":{},"叫":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}},"绑":{"docs":{},"定":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"流":{"docs":{},"程":{"docs":{},"会":{"docs":{},"查":{"docs":{},"看":{"docs":{},"请":{"docs":{},"求":{"docs":{},"内":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"并":{"docs":{},"试":{"docs":{},"图":{"docs":{},"智":{"docs":{},"能":{"docs":{},"地":{"docs":{},"把":{"docs":{},"输":{"docs":{},"入":{"docs":{},"的":{"docs":{},"字":{"docs":{},"段":{"docs":{},"和":{"docs":{},"模":{"docs":{},"型":{"docs":{},"里":{"docs":{},"的":{"docs":{},"属":{"docs":{},"性":{"docs":{},"匹":{"docs":{},"配":{"docs":{},"起":{"docs":{},"来":{"docs":{},"。":{"docs":{},"换":{"docs":{},"句":{"docs":{},"话":{"docs":{},"说":{"docs":{},",":{"docs":{},"当":{"docs":{},"用":{"docs":{},"户":{"docs":{},"提":{"docs":{},"交":{"docs":{},"这":{"docs":{},"个":{"docs":{},"表":{"docs":{},"单":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"就":{"docs":{},"没":{"docs":{},"有":{"docs":{},"用":{"docs":{},"于":{"docs":{},"有":{"docs":{},"效":{"docs":{},"性":{"docs":{},"检":{"docs":{},"查":{"docs":{},"的":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}},"/":{"docs":{},"核":{"docs":{},"验":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"板":{"docs":{},"为":{"docs":{},"你":{"docs":{},"生":{"docs":{},"成":{"docs":{},"了":{"docs":{},"多":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"和":{"docs":{},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"在":{"docs":{},"默":{"docs":{},"认":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"基":{"docs":{},"本":{"docs":{},"内":{"docs":{},"容":{"docs":{},"里":{"docs":{},",":{"docs":{},"这":{"docs":{},"几":{"docs":{},"个":{"docs":{},"是":{"docs":{},"最":{"docs":{},"重":{"docs":{},"要":{"docs":{},"的":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"仓":{"docs":{},"库":{"docs":{},"(":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"u":{"docs":{},"b":{"docs":{},"/":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"g":{"docs":{},"n":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},")":{"docs":{},"里":{"docs":{},"的":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"并":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"额":{"docs":{},"外":{"docs":{},"的":{"docs":{},"验":{"docs":{},"证":{"docs":{},"和":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{},"(":{"docs":{},"关":{"docs":{},"于":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"我":{"docs":{},"会":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"就":{"docs":{},"很":{"docs":{},"好":{"docs":{},"用":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"在":{"docs":{},"布":{"docs":{},"局":{"docs":{},"文":{"docs":{},"件":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"了":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}},"语":{"docs":{},"言":{"docs":{},"编":{"docs":{},"写":{"docs":{},",":{"docs":{},"这":{"docs":{},"种":{"docs":{},"模":{"docs":{},"板":{"docs":{},"语":{"docs":{},"言":{"docs":{},"混":{"docs":{},"合":{"docs":{},"了":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}},"现":{"docs":{},"存":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"在":{"docs":{},",":{"docs":{},"暂":{"docs":{},"且":{"docs":{},"不":{"docs":{},"必":{"docs":{},"关":{"docs":{},"心":{"docs":{},"底":{"docs":{},"层":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"采":{"docs":{},"用":{"docs":{},"的":{"docs":{},"是":{"docs":{},"哪":{"docs":{},"种":{"docs":{},"实":{"docs":{},"现":{"docs":{},"。":{"docs":{},"它":{"docs":{},"可":{"docs":{},"以":{"docs":{},"是":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}},"请":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}},"你":{"docs":{},"终":{"docs":{},"于":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"借":{"docs":{},"助":{"docs":{"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125}}}}},"日":{"docs":{},"期":{"docs":{},"的":{"docs":{},"可":{"docs":{},"读":{"docs":{},"性":{"docs":{},"大":{"docs":{},"大":{"docs":{},"提":{"docs":{},"高":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"个":{"docs":{},"单":{"docs":{},"一":{"docs":{},"、":{"docs":{},"共":{"docs":{},"享":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"它":{"docs":{},"为":{"docs":{},"每":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"保":{"docs":{},"存":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"列":{"docs":{},"表":{"docs":{},",":{"docs":{},"将":{"docs":{},"会":{"docs":{},"更":{"docs":{},"有":{"docs":{},"用":{"docs":{},"。":{"docs":{},"下":{"docs":{},"一":{"docs":{},"章":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"在":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"就":{"docs":{},"到":{"docs":{},"了":{"docs":{},"复":{"docs":{},"制":{"docs":{},"其":{"docs":{},"余":{"docs":{},"代":{"docs":{},"码":{"docs":{},"并":{"docs":{},"编":{"docs":{},"译":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}},"接":{"docs":{},"口":{"docs":{},"已":{"docs":{},"经":{"docs":{},"定":{"docs":{},"义":{"docs":{},"好":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"开":{"docs":{},"始":{"docs":{},"创":{"docs":{},"建":{"docs":{},"具":{"docs":{},"体":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"类":{"docs":{},"了":{"docs":{},"。":{"docs":{},"在":{"docs":{},"后":{"docs":{},"续":{"docs":{},"的":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"不":{"docs":{},"同":{"docs":{},"步":{"docs":{},"了":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"实":{"docs":{},"际":{"docs":{},"上":{"docs":{},"并":{"docs":{},"不":{"docs":{},"存":{"docs":{},"在":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"(":{"docs":{},"真":{"docs":{},"的":{"docs":{},")":{"docs":{},"可":{"docs":{},"以":{"docs":{},"开":{"docs":{},"始":{"docs":{},"编":{"docs":{},"写":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"了":{"docs":{},"。":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}},"生":{"docs":{},"态":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"圈":{"docs":{},"中":{"docs":{},"的":{"docs":{},"其":{"docs":{},"它":{"docs":{},"部":{"docs":{},"分":{"docs":{},",":{"docs":{},"它":{"docs":{},"也":{"docs":{},"是":{"docs":{},"一":{"docs":{},"组":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}},"成":{"docs":{},"的":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"从":{"docs":{},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"型":{"docs":{},"(":{"docs":{},"一":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"的":{"docs":{},"数":{"docs":{},"组":{"docs":{},")":{"docs":{},"获":{"docs":{},"取":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"并":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"适":{"docs":{},"当":{"docs":{},"的":{"docs":{},"表":{"docs":{},"格":{"docs":{},"展":{"docs":{},"示":{"docs":{},"给":{"docs":{},"用":{"docs":{},"户":{"docs":{},"。":{"docs":{},"按":{"docs":{},"规":{"docs":{},"定":{"docs":{},",":{"docs":{},"视":{"docs":{},"图":{"docs":{},"要":{"docs":{},"置":{"docs":{},"于":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"命":{"docs":{},"周":{"docs":{},"期":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"登":{"docs":{},"录":{"docs":{},"、":{"docs":{},"注":{"docs":{},"册":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"以":{"docs":{},"及":{"docs":{},"如":{"docs":{},"何":{"docs":{},"提":{"docs":{},"升":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}},"多":{"docs":{},"重":{"docs":{},"身":{"docs":{},"份":{"docs":{},"验":{"docs":{},"证":{"docs":{},"、":{"docs":{},"集":{"docs":{},"成":{"docs":{},"以":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}},"时":{"docs":{},"的":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}},"以":{"docs":{},"简":{"docs":{},"化":{"docs":{},"安":{"docs":{},"全":{"docs":{},"章":{"docs":{},"节":{"docs":{},"、":{"docs":{},"流":{"docs":{},"水":{"docs":{},"线":{"docs":{},"式":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},"和":{"docs":{},"部":{"docs":{},"署":{"docs":{},"。":{"docs":{},"修":{"docs":{},"改":{"docs":{},"了":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693},"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.00625},"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"传":{"docs":{},"承":{"docs":{},",":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"内":{"docs":{},"容":{"docs":{},"组":{"docs":{},"织":{"docs":{},"成":{"docs":{},"了":{"docs":{},"一":{"docs":{},"篇":{"docs":{},"教":{"docs":{},"程":{"docs":{},"。":{"docs":{},"你":{"docs":{},"将":{"docs":{},"从":{"docs":{},"头":{"docs":{},"开":{"docs":{},"始":{"docs":{},",":{"docs":{},"完":{"docs":{},"整":{"docs":{},"地":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"同":{"docs":{},"时":{"docs":{},"了":{"docs":{},"解":{"docs":{},"以":{"docs":{},"下":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"存":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"包":{"docs":{},"管":{"docs":{},"理":{"docs":{},"系":{"docs":{},"统":{"docs":{},",":{"docs":{},"类":{"docs":{},"似":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"定":{"docs":{},"义":{"docs":{},"。":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},"实":{"docs":{},"现":{"docs":{},",":{"docs":{},"它":{"docs":{},"只":{"docs":{},"能":{"docs":{},"运":{"docs":{},"行":{"docs":{},"在":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"数":{"docs":{},"量":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}},"组":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"”":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"它":{"docs":{},"去":{"docs":{},"测":{"docs":{},"试":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"和":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"在":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}},"方":{"docs":{},"式":{"docs":{},"进":{"docs":{},"行":{"docs":{},"贡":{"docs":{},"献":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"法":{"docs":{},"把":{"docs":{},"其":{"docs":{},"他":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"事":{"docs":{},"项":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{},"完":{"docs":{},"成":{"docs":{},"状":{"docs":{},"态":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}},"里":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"框":{"docs":{},"架":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"解":{"docs":{},"释":{"docs":{},"器":{"docs":{},"。":{"docs":{},"有":{"docs":{},"几":{"docs":{},"种":{"docs":{},"语":{"docs":{},"言":{"docs":{},"(":{"docs":{},"c":{"docs":{},"#":{"docs":{},",":{"docs":{},"v":{"docs":{},"i":{"docs":{},"s":{"docs":{},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}},"代":{"docs":{},"码":{"docs":{},"重":{"docs":{},"构":{"docs":{},",":{"docs":{},"且":{"docs":{},"略":{"docs":{},"优":{"docs":{},"于":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}},"。":{"docs":{},"(":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}},":":{"docs":{},"首":{"docs":{},"个":{"docs":{},"代":{"docs":{},"码":{"docs":{},"块":{"docs":{},"检":{"docs":{},"查":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"安":{"docs":{},"装":{"docs":{},"后":{"docs":{},",":{"docs":{},"开":{"docs":{},"启":{"docs":{},"一":{"docs":{},"个":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}}}}}}}}},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"进":{"docs":{},"入":{"docs":{},"到":{"docs":{},"这":{"docs":{},"个":{"docs":{},"新":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}},"里":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"类":{"docs":{},"(":{"docs":{},"一":{"docs":{},"种":{"docs":{},"代":{"docs":{},"码":{"docs":{},"结":{"docs":{},"构":{"docs":{},"或":{"docs":{},"模":{"docs":{},"块":{"docs":{},")":{"docs":{},"里":{"docs":{},"。":{"docs":{},"最":{"docs":{},"上":{"docs":{},"面":{"docs":{},"的":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},",":{"docs":{},"却":{"docs":{},"产":{"docs":{},"生":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"小":{"docs":{},"问":{"docs":{},"题":{"docs":{},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}},"那":{"docs":{},"些":{"docs":{},"类":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"这":{"docs":{},"个":{"docs":{},"类":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"它":{"docs":{},"们":{"docs":{},"。":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}},"处":{"docs":{},"理":{"docs":{},"管":{"docs":{},"线":{"docs":{},"。":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"流":{"docs":{},"程":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"中":{"docs":{},"包":{"docs":{},"括":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"效":{"docs":{},"果":{"docs":{},"一":{"docs":{},"样":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"种":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},"部":{"docs":{},"分":{"docs":{},")":{"docs":{},"之":{"docs":{},"上":{"docs":{},"。":{"docs":{},"安":{"docs":{},"装":{"docs":{},"后":{"docs":{},",":{"docs":{},"默":{"docs":{},"认":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}},"各":{"docs":{},"个":{"docs":{},"组":{"docs":{},"件":{"docs":{},",":{"docs":{},"而":{"docs":{},"且":{"docs":{},"涵":{"docs":{},"盖":{"docs":{},"了":{"docs":{},"很":{"docs":{},"多":{"docs":{},"概":{"docs":{},"念":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"可":{"docs":{},"以":{"docs":{},"直":{"docs":{},"接":{"docs":{},"应":{"docs":{},"用":{"docs":{},"于":{"docs":{},"规":{"docs":{},"模":{"docs":{},"更":{"docs":{},"大":{"docs":{},"的":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"模":{"docs":{},"式":{"docs":{},",":{"docs":{},"其":{"docs":{},"应":{"docs":{},"用":{"docs":{},"几":{"docs":{},"乎":{"docs":{},"遍":{"docs":{},"及":{"docs":{},"所":{"docs":{},"有":{"docs":{},"的":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}},"还":{"docs":{},"有":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"型":{"docs":{},"核":{"docs":{},"验":{"docs":{},"器":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"标":{"docs":{},"题":{"docs":{},"缺":{"docs":{},"失":{"docs":{},"或":{"docs":{},"为":{"docs":{},"空":{"docs":{},",":{"docs":{},"则":{"docs":{},"判":{"docs":{},"定":{"docs":{},"其":{"docs":{},"无":{"docs":{},"效":{"docs":{},"。":{"docs":{},"看":{"docs":{},"一":{"docs":{},"下":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}},"绑":{"docs":{},"定":{"docs":{},"器":{"docs":{},"设":{"docs":{},"置":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"仅":{"docs":{},"需":{"docs":{},"要":{"docs":{},"分":{"docs":{},"配":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}},"系":{"docs":{},"统":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},")":{"docs":{},",":{"docs":{},"编":{"docs":{},"写":{"docs":{},"代":{"docs":{},"码":{"docs":{},"与":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"进":{"docs":{},"行":{"docs":{},"交":{"docs":{},"互":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}},"戳":{"docs":{},"记":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{},"与":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"问":{"docs":{},"题":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}},"名":{"docs":{},"字":{"docs":{},"加":{"docs":{},"上":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"后":{"docs":{},"续":{"docs":{},"操":{"docs":{},"作":{"docs":{},"中":{"docs":{},"把":{"docs":{},"该":{"docs":{},"条":{"docs":{},"目":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{},"已":{"docs":{},"完":{"docs":{},"成":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}},"官":{"docs":{},"方":{"docs":{},"文":{"docs":{},"档":{"docs":{},"(":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"保":{"docs":{},"存":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"去":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}},"引":{"docs":{},"用":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"变":{"docs":{},"量":{"docs":{},"可":{"docs":{},"以":{"docs":{},"让":{"docs":{},"你":{"docs":{},"在":{"docs":{},"后":{"docs":{},"面":{"docs":{},"的":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}},"说":{"docs":{},"法":{"docs":{},"是":{"docs":{},"服":{"docs":{},"务":{"docs":{},"的":{"docs":{},"集":{"docs":{},"合":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}},"列":{"docs":{},"表":{"docs":{},",":{"docs":{},"它":{"docs":{},"应":{"docs":{},"该":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"条":{"docs":{},"目":{"docs":{},"放":{"docs":{},"进":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}},"布":{"docs":{},"局":{"docs":{},"文":{"docs":{},"件":{"docs":{},"里":{"docs":{},"面":{"docs":{},"存":{"docs":{},"放":{"docs":{},"着":{"docs":{},"所":{"docs":{},"有":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},"“":{"docs":{},"基":{"docs":{},"础":{"docs":{},"”":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{},"。":{"docs":{},"其":{"docs":{},"中":{"docs":{},"就":{"docs":{},"包":{"docs":{},"括":{"docs":{},"导":{"docs":{},"航":{"docs":{},"栏":{"docs":{},",":{"docs":{},"它":{"docs":{},"被":{"docs":{},"显":{"docs":{},"示":{"docs":{},"在":{"docs":{},"每":{"docs":{},"个":{"docs":{},"页":{"docs":{},"面":{"docs":{},"的":{"docs":{},"顶":{"docs":{},"端":{"docs":{},"。":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"文":{"docs":{},"档":{"docs":{},"。":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}},"非":{"docs":{},"常":{"docs":{},"适":{"docs":{},"合":{"docs":{},"用":{"docs":{},"来":{"docs":{},"学":{"docs":{},"习":{"docs":{},"这":{"docs":{},"些":{"docs":{},"特":{"docs":{},"性":{"docs":{},"。":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}},"件":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"路":{"docs":{},"由":{"docs":{},"。":{"docs":{},"而":{"docs":{},"是":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}},"表":{"docs":{},"里":{"docs":{},"保":{"docs":{},"存":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}},"局":{"docs":{},"限":{"docs":{},"性":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}},"时":{"docs":{},"候":{"docs":{},"创":{"docs":{},"建":{"docs":{},"并":{"docs":{},"应":{"docs":{},"用":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}},",":{"docs":{},"会":{"docs":{},"验":{"docs":{},"证":{"docs":{},"这":{"docs":{},"个":{"docs":{},"标":{"docs":{},"记":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"重":{"docs":{},"要":{"docs":{},"的":{"docs":{},"安":{"docs":{},"全":{"docs":{},"措":{"docs":{},"施":{"docs":{},",":{"docs":{},"你":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},"可":{"docs":{},"能":{"docs":{},"被":{"docs":{},"欺":{"docs":{},"骗":{"docs":{},",":{"docs":{},"以":{"docs":{},"至":{"docs":{},"于":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"恶":{"docs":{},"意":{"docs":{},"的":{"docs":{},"网":{"docs":{},"站":{"docs":{},"上":{"docs":{},"提":{"docs":{},"交":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{},"这":{"docs":{},"里":{"docs":{},"的":{"docs":{},"验":{"docs":{},"证":{"docs":{},"标":{"docs":{},"记":{"docs":{},"被":{"docs":{},"用":{"docs":{},"于":{"docs":{},"确":{"docs":{},"保":{"docs":{},"呈":{"docs":{},"现":{"docs":{},"和":{"docs":{},"提":{"docs":{},"交":{"docs":{},"表":{"docs":{},"单":{"docs":{},"的":{"docs":{},",":{"docs":{},"是":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"设":{"docs":{},"置":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"用":{"docs":{},"的":{"docs":{},"就":{"docs":{},"是":{"docs":{},"这":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"。":{"docs":{},"当":{"docs":{},"你":{"docs":{},"把":{"docs":{},"程":{"docs":{},"序":{"docs":{},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{},"生":{"docs":{},"产":{"docs":{},"环":{"docs":{},"境":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"它":{"docs":{},"仍":{"docs":{},"会":{"docs":{},"在":{"docs":{},"幕":{"docs":{},"后":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"一":{"docs":{},"系":{"docs":{},"列":{"docs":{},"的":{"docs":{},"日":{"docs":{},"志":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}},"属":{"docs":{},"性":{"docs":{},"获":{"docs":{},"取":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"特":{"docs":{},"性":{"docs":{},",":{"docs":{},"它":{"docs":{},"受":{"docs":{},"到":{"docs":{},"函":{"docs":{},"数":{"docs":{},"式":{"docs":{},"编":{"docs":{},"程":{"docs":{},"的":{"docs":{},"启":{"docs":{},"发":{"docs":{},",":{"docs":{},"简":{"docs":{},"化":{"docs":{},"了":{"docs":{},"在":{"docs":{},"程":{"docs":{},"序":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"查":{"docs":{},"询":{"docs":{},"的":{"docs":{},"写":{"docs":{},"法":{"docs":{},"。":{"docs":{},"在":{"docs":{},"底":{"docs":{},"层":{"docs":{},",":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"生":{"docs":{},"命":{"docs":{},"周":{"docs":{},"期":{"docs":{},"把":{"docs":{},"你":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"容":{"docs":{},"器":{"docs":{},"里":{"docs":{},"。":{"docs":{},"这":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},"每":{"docs":{},"次":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}},"能":{"docs":{},"力":{"docs":{},"”":{"docs":{},"开":{"docs":{},"始":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}},"同":{"docs":{},"时":{"docs":{},"会":{"docs":{},"在":{"docs":{},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"隐":{"docs":{},"藏":{"docs":{},"字":{"docs":{},"段":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"个":{"docs":{},"验":{"docs":{},"证":{"docs":{},"标":{"docs":{},"记":{"docs":{},"。":{"docs":{},"该":{"docs":{},"验":{"docs":{},"证":{"docs":{},"标":{"docs":{},"记":{"docs":{},"可":{"docs":{},"用":{"docs":{},"于":{"docs":{},"防":{"docs":{},"止":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"形":{"docs":{},"式":{"docs":{},"创":{"docs":{},"建":{"docs":{},"这":{"docs":{},"个":{"docs":{},"表":{"docs":{},"单":{"docs":{},"。":{"docs":{},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"是":{"docs":{},"较":{"docs":{},"大":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"小":{"docs":{},"片":{"docs":{},"段":{"docs":{},",":{"docs":{},"存":{"docs":{},"放":{"docs":{},"于":{"docs":{},"一":{"docs":{},"个":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"新":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"真":{"docs":{},"实":{"docs":{},"地":{"docs":{},"址":{"docs":{},"取":{"docs":{},"代":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"语":{"docs":{},"法":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"值":{"docs":{},"将":{"docs":{},"是":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},",":{"docs":{},"以":{"docs":{},"判":{"docs":{},"断":{"docs":{},"它":{"docs":{},"的":{"docs":{},"有":{"docs":{},"效":{"docs":{},"性":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"出":{"docs":{},"于":{"docs":{},"某":{"docs":{},"些":{"docs":{},"原":{"docs":{},"因":{"docs":{},",":{"docs":{},"请":{"docs":{},"求":{"docs":{},"中":{"docs":{},"的":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}},"绝":{"docs":{},"不":{"docs":{},"应":{"docs":{},"该":{"docs":{},"是":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"距":{"docs":{},"离":{"docs":{},"期":{"docs":{},"望":{"docs":{},"值":{"docs":{},"小":{"docs":{},"于":{"docs":{},"一":{"docs":{},"秒":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"参":{"docs":{},"数":{"docs":{},",":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"隐":{"docs":{},"藏":{"docs":{},"元":{"docs":{},"素":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"人":{"docs":{},"一":{"docs":{},"定":{"docs":{},"登":{"docs":{},"录":{"docs":{},"过":{"docs":{},",":{"docs":{},"在":{"docs":{},"查":{"docs":{},"询":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"可":{"docs":{},"以":{"docs":{},"按":{"docs":{},"照":{"docs":{},"登":{"docs":{},"录":{"docs":{},"者":{"docs":{},"的":{"docs":{},"身":{"docs":{},"份":{"docs":{},"进":{"docs":{},"行":{"docs":{},"过":{"docs":{},"滤":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"变":{"docs":{},"更":{"docs":{},",":{"docs":{},"它":{"docs":{},"将":{"docs":{},"给":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"操":{"docs":{},"作":{"docs":{},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"用":{"docs":{},"户":{"docs":{},"信":{"docs":{},"息":{"docs":{},"存":{"docs":{},"储":{"docs":{},"到":{"docs":{},"条":{"docs":{},"目":{"docs":{},"里":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}},"功":{"docs":{},"能":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"小":{"docs":{},"类":{"docs":{},"以":{"docs":{},"保":{"docs":{},"存":{"docs":{},"它":{"docs":{},"的":{"docs":{},"值":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},"常":{"docs":{},"见":{"docs":{},"方":{"docs":{},"法":{"docs":{},"。":{"docs":{},"例":{"docs":{},"如":{"docs":{},",":{"docs":{},"通":{"docs":{},"常":{"docs":{},"会":{"docs":{},"为":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{},"户":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"将":{"docs":{},"创":{"docs":{},"建":{"docs":{},"它":{"docs":{},"并":{"docs":{},"给":{"docs":{},"它":{"docs":{},"一":{"docs":{},"个":{"docs":{},"临":{"docs":{},"时":{"docs":{},"的":{"docs":{},"密":{"docs":{},"码":{"docs":{},"。":{"docs":{},"在":{"docs":{},"你":{"docs":{},"初":{"docs":{},"次":{"docs":{},"登":{"docs":{},"录":{"docs":{},"之":{"docs":{},"后":{"docs":{},",":{"docs":{},"就":{"docs":{},"应":{"docs":{},"该":{"docs":{},"改":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"更":{"docs":{},"安":{"docs":{},"全":{"docs":{},"的":{"docs":{},"密":{"docs":{},"码":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"页":{"docs":{},"面":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"看":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{},"列":{"docs":{},"表":{"docs":{},",":{"docs":{},"列":{"docs":{},"出":{"docs":{},"了":{"docs":{},"本":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"注":{"docs":{},"册":{"docs":{},"用":{"docs":{},"户":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}},"替":{"docs":{},"代":{"docs":{},"品":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},",":{"docs":{},"并":{"docs":{},"通":{"docs":{},"知":{"docs":{},"服":{"docs":{},"务":{"docs":{},"将":{"docs":{},"其":{"docs":{},"存":{"docs":{},"储":{"docs":{},"到":{"docs":{},"(":{"docs":{},"内":{"docs":{},"存":{"docs":{},")":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"和":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"系":{"docs":{},"统":{"docs":{},"在":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"范":{"docs":{},"围":{"docs":{},"。":{"docs":{},"作":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"补":{"docs":{},"充":{"docs":{},"练":{"docs":{},"习":{"docs":{},",":{"docs":{},"请":{"docs":{},"写":{"docs":{},"出":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"以":{"docs":{},"确":{"docs":{},"保":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}},"快":{"docs":{},"速":{"docs":{},"轻":{"docs":{},"量":{"docs":{},"级":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},"。":{"docs":{},"(":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"还":{"docs":{},"不":{"docs":{},"熟":{"docs":{},"悉":{"docs":{},",":{"docs":{},"别":{"docs":{},"担":{"docs":{},"心":{"docs":{},"!":{"docs":{},"我":{"docs":{},"会":{"docs":{},"在":{"docs":{},"后":{"docs":{},"面":{"docs":{},"逐":{"docs":{},"步":{"docs":{},"介":{"docs":{},"绍":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"指":{"docs":{},"示":{"docs":{},"进":{"docs":{},"行":{"docs":{},"安":{"docs":{},"装":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},"网":{"docs":{},"上":{"docs":{},"门":{"docs":{},"户":{"docs":{},"实":{"docs":{},"施":{"docs":{},",":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"深":{"docs":{},"度":{"docs":{},"教":{"docs":{},"程":{"docs":{},"(":{"docs":{},"请":{"docs":{},"搜":{"docs":{},"索":{"docs":{},"“":{"docs":{},"d":{"docs":{},"i":{"docs":{},"g":{"docs":{},"i":{"docs":{},"t":{"docs":{},"a":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}},"默":{"docs":{},"认":{"docs":{},")":{"docs":{},"端":{"docs":{},"口":{"docs":{},"上":{"docs":{},"进":{"docs":{},"行":{"docs":{},"监":{"docs":{},"听":{"docs":{},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"请":{"docs":{},"求":{"docs":{},"转":{"docs":{},"发":{"docs":{},"到":{"docs":{},"由":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"c":{"docs":{},"#":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"较":{"docs":{},"小":{"docs":{},",":{"docs":{},"用":{"docs":{},"来":{"docs":{},"确":{"docs":{},"保":{"docs":{},"单":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"或":{"docs":{},"者":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"块":{"docs":{},"工":{"docs":{},"作":{"docs":{},"良":{"docs":{},"好":{"docs":{},"。":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"(":{"docs":{},"有":{"docs":{},"时":{"docs":{},"候":{"docs":{},"也":{"docs":{},"叫":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"一":{"docs":{},"般":{"docs":{},"来":{"docs":{},"说":{"docs":{},",":{"docs":{},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}},"创":{"docs":{},"建":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}},"上":{"docs":{},"。":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"全":{"docs":{},"部":{"docs":{},"!":{"docs":{},"下":{"docs":{},"一":{"docs":{},"节":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"把":{"docs":{},"同":{"docs":{},"样":{"docs":{},"的":{"docs":{},"流":{"docs":{},"程":{"docs":{},"应":{"docs":{},"用":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"入":{"docs":{},"口":{"docs":{},"点":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"按":{"docs":{},"照":{"docs":{},"惯":{"docs":{},"例":{"docs":{},",":{"docs":{},"会":{"docs":{},"被":{"docs":{},"置":{"docs":{},"于":{"docs":{},"一":{"docs":{},"个":{"docs":{},"叫":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}},"默":{"docs":{},"认":{"docs":{},"欢":{"docs":{},"迎":{"docs":{},"页":{"docs":{},"面":{"docs":{},",":{"docs":{},"说":{"docs":{},"明":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"工":{"docs":{},"作":{"docs":{},"正":{"docs":{},"常":{"docs":{},"!":{"docs":{},"看":{"docs":{},"够":{"docs":{},"了":{"docs":{},"这":{"docs":{},"个":{"docs":{},"页":{"docs":{},"面":{"docs":{},"之":{"docs":{},"后":{"docs":{},",":{"docs":{},"在":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"内":{"docs":{},"按":{"docs":{},"下":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},",":{"docs":{},"它":{"docs":{},"输":{"docs":{},"出":{"docs":{},"文":{"docs":{},"本":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}},"里":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"模":{"docs":{},"式":{"docs":{},"是":{"docs":{},":":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}},"展":{"docs":{},"示":{"docs":{},"的":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"托":{"docs":{},"管":{"docs":{},"工":{"docs":{},"作":{"docs":{},"的":{"docs":{},"细":{"docs":{},"节":{"docs":{},",":{"docs":{},"而":{"docs":{},"只":{"docs":{},"希":{"docs":{},"望":{"docs":{},"参":{"docs":{},"考":{"docs":{},"分":{"docs":{},"步":{"docs":{},"的":{"docs":{},"指":{"docs":{},"导":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"跳":{"docs":{},"转":{"docs":{},"到":{"docs":{},"后":{"docs":{},"续":{"docs":{},"两":{"docs":{},"小":{"docs":{},"节":{"docs":{},"的":{"docs":{},"任":{"docs":{},"一":{"docs":{},"个":{"docs":{},"继":{"docs":{},"续":{"docs":{},"阅":{"docs":{},"读":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"提":{"docs":{},"供":{"docs":{},"原":{"docs":{},"生":{"docs":{},"的":{"docs":{},"支":{"docs":{},"持":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}},"能":{"docs":{},"够":{"docs":{},"运":{"docs":{},"行":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},"你":{"docs":{},"自":{"docs":{},"己":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"上":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{},"不":{"docs":{},"再":{"docs":{},"需":{"docs":{},"要":{"docs":{},"浪":{"docs":{},"费":{"docs":{},"时":{"docs":{},"间":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"上":{"docs":{},"配":{"docs":{},"置":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"、":{"docs":{},"复":{"docs":{},"制":{"docs":{},"文":{"docs":{},"件":{"docs":{},"、":{"docs":{},"重":{"docs":{},"启":{"docs":{},"进":{"docs":{},"程":{"docs":{},",":{"docs":{},"你":{"docs":{},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"新":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"目":{"docs":{},"录":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"等":{"docs":{},"等":{"docs":{},",":{"docs":{},"数":{"docs":{},"不":{"docs":{},"胜":{"docs":{},"数":{"docs":{},"。":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}},"。":{"docs":{},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},"点":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"它":{"docs":{},"确":{"docs":{},"保":{"docs":{},"你":{"docs":{},"不":{"docs":{},"会":{"docs":{},"意":{"docs":{},"外":{"docs":{},"地":{"docs":{},"弄":{"docs":{},"丢":{"docs":{},"了":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}},"协":{"docs":{},"议":{"docs":{},"连":{"docs":{},"接":{"docs":{},"到":{"docs":{},"其":{"docs":{},"它":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"。":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}},"简":{"docs":{},"明":{"docs":{"./":{"ref":"./","tf":0.0035335689045936395},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"类":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"成":{"docs":{},"了":{"docs":{},"起":{"docs":{},"始":{"docs":{},"和":{"docs":{},"中":{"docs":{},"心":{"docs":{},",":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"_":{"docs":{},"s":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"添":{"docs":{},"加":{"docs":{},"中":{"docs":{},"间":{"docs":{},"件":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"用":{"docs":{},"于":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}},"的":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"型":{"docs":{},"后":{"docs":{},"面":{"docs":{},"那":{"docs":{},"个":{"docs":{},"问":{"docs":{},"号":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"类":{"docs":{},"似":{"docs":{},"于":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}},"参":{"docs":{},"数":{"docs":{},"。":{"docs":{},"参":{"docs":{},"数":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"(":{"docs":{},"在":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}},"的":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"新":{"docs":{},"实":{"docs":{},"例":{"docs":{},"就":{"docs":{},"会":{"docs":{},"被":{"docs":{},"创":{"docs":{},"建":{"docs":{},"出":{"docs":{},"来":{"docs":{},"。":{"docs":{},"这":{"docs":{},"对":{"docs":{},"于":{"docs":{},"那":{"docs":{},"些":{"docs":{},"跟":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"打":{"docs":{},"交":{"docs":{},"道":{"docs":{},"的":{"docs":{},"类":{"docs":{},"来":{"docs":{},"说":{"docs":{},",":{"docs":{},"是":{"docs":{},"必":{"docs":{},"要":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"它":{"docs":{},"就":{"docs":{},"不":{"docs":{},"知":{"docs":{},"道":{"docs":{},"也":{"docs":{},"不":{"docs":{},"必":{"docs":{},"关":{"docs":{},"心":{"docs":{},"实":{"docs":{},"际":{"docs":{},"使":{"docs":{},"用":{"docs":{},"的":{"docs":{},"是":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"具":{"docs":{},"体":{"docs":{},"的":{"docs":{},"类":{"docs":{},"。":{"docs":{},"它":{"docs":{},"可":{"docs":{},"以":{"docs":{},"是":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"就":{"docs":{},"需":{"docs":{},"要":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"这":{"docs":{},"个":{"docs":{},"类":{"docs":{},"会":{"docs":{},"基":{"docs":{},"于":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}},"提":{"docs":{},"供":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"入":{"docs":{},"口":{"docs":{},"点":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"类":{"docs":{},"能":{"docs":{},"够":{"docs":{},"在":{"docs":{},"测":{"docs":{},"试":{"docs":{},"期":{"docs":{},"间":{"docs":{},"托":{"docs":{},"管":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"并":{"docs":{},"在":{"docs":{},"测":{"docs":{},"试":{"docs":{},"完":{"docs":{},"成":{"docs":{},"之":{"docs":{},"后":{"docs":{},"自":{"docs":{},"动":{"docs":{},"关":{"docs":{},"闭":{"docs":{},"它":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"编":{"docs":{},"程":{"docs":{},"开":{"docs":{},"发":{"docs":{},"者":{"docs":{},"以":{"docs":{},"及":{"docs":{},"爱":{"docs":{},"好":{"docs":{},"者":{"docs":{},"了":{"docs":{},"解":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}},"方":{"docs":{},"面":{"docs":{},"经":{"docs":{},"验":{"docs":{},"如":{"docs":{},"何":{"docs":{},",":{"docs":{},"本":{"docs":{},"书":{"docs":{},"都":{"docs":{},"会":{"docs":{},"倾":{"docs":{},"囊":{"docs":{},"相":{"docs":{},"授":{"docs":{},",":{"docs":{},"足":{"docs":{},"够":{"docs":{},"你":{"docs":{},"借":{"docs":{},"助":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}},"语":{"docs":{},"言":{"docs":{},"里":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"概":{"docs":{},"念":{"docs":{},"叫":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}},"译":{"docs":{},"器":{"docs":{},"的":{"docs":{},"静":{"docs":{},"态":{"docs":{},"类":{"docs":{},"型":{"docs":{},"检":{"docs":{},"测":{"docs":{},"的":{"docs":{},"优":{"docs":{},"势":{"docs":{},",":{"docs":{},"它":{"docs":{},"像":{"docs":{},"个":{"docs":{},"时":{"docs":{},"刻":{"docs":{},"警":{"docs":{},"惕":{"docs":{},"着":{"docs":{},",":{"docs":{},"还":{"docs":{},"有":{"docs":{},"些":{"docs":{},"强":{"docs":{},"迫":{"docs":{},"症":{"docs":{},"的":{"docs":{},"审":{"docs":{},"校":{"docs":{},"者":{"docs":{},"。":{"docs":{},"这":{"docs":{},"样":{"docs":{},",":{"docs":{},"在":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"量":{"docs":{},"或":{"docs":{},"者":{"docs":{},"某":{"docs":{},"些":{"docs":{},"数":{"docs":{},"据":{"docs":{},"时":{"docs":{},",":{"docs":{},"那":{"docs":{},"些":{"docs":{},"无":{"docs":{},"意":{"docs":{},"识":{"docs":{},"的":{"docs":{},"错":{"docs":{},"误":{"docs":{},"就":{"docs":{},"插":{"docs":{},"翅":{"docs":{},"难":{"docs":{},"逃":{"docs":{},"了":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"出":{"docs":{},"来":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},"启":{"docs":{},"动":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{},"(":{"docs":{},"当":{"docs":{},"你":{"docs":{},"在":{"docs":{},"开":{"docs":{},"发":{"docs":{},"时":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"工":{"docs":{},"具":{"docs":{},"和":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"。":{"docs":{},"以":{"docs":{},"这":{"docs":{},"个":{"docs":{},"预":{"docs":{},"编":{"docs":{},"译":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"为":{"docs":{},"基":{"docs":{},"础":{"docs":{},",":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"写":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}},"缺":{"docs":{},"陷":{"docs":{},"修":{"docs":{},"复":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"著":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}},"虚":{"docs":{},"拟":{"docs":{},"机":{"docs":{},"(":{"docs":{},"j":{"docs":{},"v":{"docs":{},"m":{"docs":{},")":{"docs":{},"或":{"docs":{},"者":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}},")":{"docs":{},"上":{"docs":{},"托":{"docs":{},"管":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{},"通":{"docs":{},"常":{"docs":{},"把":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}},",":{"docs":{},"也":{"docs":{},"有":{"docs":{},"关":{"docs":{},"于":{"docs":{},"搭":{"docs":{},"建":{"docs":{},"和":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"构":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"(":{"docs":{},"m":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},")":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"解":{"docs":{},"耦":{"docs":{},"。":{"docs":{},"你":{"docs":{},"要":{"docs":{},"是":{"docs":{},"还":{"docs":{},"记":{"docs":{},"得":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"决":{"docs":{},"方":{"docs":{},"案":{"docs":{},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"后":{"docs":{},"面":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"会":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}},"了":{"docs":{},"这":{"docs":{},"种":{"docs":{},"问":{"docs":{},"题":{"docs":{},",":{"docs":{},"它":{"docs":{},"提":{"docs":{},"供":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"可":{"docs":{},"以":{"docs":{},"“":{"docs":{},"人":{"docs":{},"性":{"docs":{},"化":{"docs":{},"(":{"docs":{},"h":{"docs":{},"u":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},")":{"docs":{},"”":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"许":{"docs":{},"可":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}},"证":{"docs":{},"开":{"docs":{},"放":{"docs":{},"源":{"docs":{},"码":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"说":{"docs":{},",":{"docs":{},"源":{"docs":{},"代":{"docs":{},"码":{"docs":{},"可":{"docs":{},"以":{"docs":{},"自":{"docs":{},"由":{"docs":{},"获":{"docs":{},"取":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"欢":{"docs":{},"迎":{"docs":{},"社":{"docs":{},"区":{"docs":{},"成":{"docs":{},"员":{"docs":{},"以":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"发":{"docs":{},"布":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"译":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"者":{"docs":{},"注":{"docs":{},":":{"docs":{},"二":{"docs":{},"者":{"docs":{},"都":{"docs":{},"是":{"docs":{},"其":{"docs":{},"它":{"docs":{},"语":{"docs":{},"言":{"docs":{},"中":{"docs":{},",":{"docs":{},"与":{"docs":{},"异":{"docs":{},"步":{"docs":{},"编":{"docs":{},"程":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"概":{"docs":{},"念":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"是":{"docs":{},"用":{"docs":{},"于":{"docs":{},"指":{"docs":{},"代":{"docs":{},"某":{"docs":{},"个":{"docs":{},"尚":{"docs":{},"未":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"的":{"docs":{},"值":{"docs":{},"的":{"docs":{},"对":{"docs":{},"象":{"docs":{},"。":{"docs":{},"而":{"docs":{},"这":{"docs":{},"个":{"docs":{},"值":{"docs":{},",":{"docs":{},"往":{"docs":{},"往":{"docs":{},"是":{"docs":{},"某":{"docs":{},"个":{"docs":{},"计":{"docs":{},"算":{"docs":{},"过":{"docs":{},"程":{"docs":{},"的":{"docs":{},"结":{"docs":{},"果":{"docs":{},"。":{"docs":{},"要":{"docs":{},"了":{"docs":{},"解":{"docs":{},"详":{"docs":{},"细":{"docs":{},",":{"docs":{},"请":{"docs":{},"参":{"docs":{},"考":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}},"详":{"docs":{},"情":{"docs":{},"请":{"docs":{},"访":{"docs":{},"问":{"docs":{},":":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"m":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},".":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},"/":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"n":{"docs":{},"s":{"docs":{},"e":{"docs":{},"s":{"docs":{},"/":{"docs":{},"b":{"docs":{},"y":{"docs":{},"/":{"4":{"docs":{},".":{"0":{"docs":{},"/":{"docs":{},"d":{"docs":{},"e":{"docs":{},"e":{"docs":{},"d":{"docs":{},".":{"docs":{},"z":{"docs":{},"h":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}},"docs":{}}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"尽":{"docs":{},"的":{"docs":{},"设":{"docs":{},"置":{"docs":{},"指":{"docs":{},"令":{"docs":{},"超":{"docs":{},"出":{"docs":{},"了":{"docs":{},"这":{"docs":{},"本":{"docs":{},"书":{"docs":{},"的":{"docs":{},"范":{"docs":{},"畴":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"任":{"docs":{},"何":{"docs":{},"较":{"docs":{},"新":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}},"贯":{"docs":{},"穿":{"docs":{},"本":{"docs":{},"书":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"学":{"docs":{},"习":{"docs":{},"有":{"docs":{},"关":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}},"运":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"在":{"docs":{},"微":{"docs":{},"软":{"docs":{},"的":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}},"时":{"docs":{},"库":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"它":{"docs":{},"在":{"docs":{},"各":{"docs":{},"个":{"docs":{},"操":{"docs":{},"作":{"docs":{},"系":{"docs":{},"统":{"docs":{},"上":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{},"对":{"docs":{},"应":{"docs":{},"的":{"docs":{},"平":{"docs":{},"台":{"docs":{},"相":{"docs":{},"关":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"实":{"docs":{},"现":{"docs":{},"了":{"docs":{},"定":{"docs":{},"义":{"docs":{},"于":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"上":{"docs":{},",":{"docs":{},"类":{"docs":{},"似":{"docs":{},"于":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"用":{"docs":{},"于":{"docs":{},"运":{"docs":{},"行":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}},"编":{"docs":{},"译":{"docs":{},"任":{"docs":{},"务":{"docs":{},",":{"docs":{},"这":{"docs":{},"跟":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}},"(":{"docs":{},"并":{"docs":{},"调":{"docs":{},"试":{"docs":{},"断":{"docs":{},"点":{"docs":{},")":{"docs":{},":":{"docs":{},"使":{"docs":{},"你":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"处":{"docs":{},"于":{"docs":{},"打":{"docs":{},"开":{"docs":{},"状":{"docs":{},"态":{"docs":{},",":{"docs":{},"按":{"docs":{},"下":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{},"页":{"docs":{},"面":{"docs":{},"上":{"docs":{},"的":{"docs":{},"表":{"docs":{},"单":{"docs":{},"添":{"docs":{},"加":{"docs":{},"几":{"docs":{},"个":{"docs":{},"条":{"docs":{},"目":{"docs":{},"到":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}},"并":{"docs":{},"勾":{"docs":{},"选":{"docs":{},"列":{"docs":{},"表":{"docs":{},"中":{"docs":{},"的":{"docs":{},"某":{"docs":{},"些":{"docs":{},"条":{"docs":{},"目":{"docs":{},"完":{"docs":{},"成":{"docs":{},"掉":{"docs":{},"。":{"docs":{},"刷":{"docs":{},"新":{"docs":{},"页":{"docs":{},"面":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"将":{"docs":{},"自":{"docs":{},"动":{"docs":{},"消":{"docs":{},"失":{"docs":{},"掉":{"docs":{},",":{"docs":{},"这":{"docs":{},"归":{"docs":{},"功":{"docs":{},"于":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"用":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":10.001373626373626}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":10.005154639175258}}}}}}},"这":{"docs":{},"本":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}},"书":{"docs":{},"本":{"docs":{},"身":{"docs":{},"也":{"docs":{},"会":{"docs":{},"由":{"docs":{},"于":{"docs":{},"修":{"docs":{},"订":{"docs":{},"和":{"docs":{},"内":{"docs":{},"容":{"docs":{},"的":{"docs":{},"增":{"docs":{},"加":{"docs":{},"而":{"docs":{},"频":{"docs":{},"繁":{"docs":{},"更":{"docs":{},"新":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"阅":{"docs":{},"读":{"docs":{},"的":{"docs":{},"是":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"命":{"docs":{},"令":{"docs":{},"行":{"docs":{},"下":{"docs":{},"执":{"docs":{},"行":{"docs":{},"。":{"docs":{},"首":{"docs":{},"先":{"docs":{},"开":{"docs":{},"启":{"docs":{},"一":{"docs":{},"个":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}},"命":{"docs":{},"令":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"新":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"在":{"docs":{},"美":{"docs":{},"国":{"docs":{},"西":{"docs":{},"部":{"docs":{},"(":{"docs":{},"w":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"不":{"docs":{},"再":{"docs":{},"打":{"docs":{},"印":{"docs":{},"到":{"docs":{},"控":{"docs":{},"制":{"docs":{},"台":{"docs":{},"后":{"docs":{},"直":{"docs":{},"接":{"docs":{},"退":{"docs":{},"出":{"docs":{},",":{"docs":{},"而":{"docs":{},"是":{"docs":{},"启":{"docs":{},"动":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}},"类":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"每":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"都":{"docs":{},"要":{"docs":{},"保":{"docs":{},"存":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"第":{"docs":{},"一":{"docs":{},"行":{"docs":{},"声":{"docs":{},"明":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"私":{"docs":{},"有":{"docs":{},"变":{"docs":{},"量":{"docs":{},",":{"docs":{},"保":{"docs":{},"存":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}},"配":{"docs":{},"置":{"docs":{},"好":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}},"表":{"docs":{},"。":{"docs":{},"(":{"docs":{},"对":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"代":{"docs":{},"码":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},",":{"docs":{},"并":{"docs":{},"不":{"docs":{},"会":{"docs":{},"改":{"docs":{},"变":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"本":{"docs":{},"身":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"路":{"docs":{},"由":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"现":{"docs":{},"在":{"docs":{},"去":{"docs":{},"尝":{"docs":{},"试":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"首":{"docs":{},"先":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}},"角":{"docs":{},"色":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},",":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},"尚":{"docs":{},"不":{"docs":{},"存":{"docs":{},"在":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}},"账":{"docs":{},"号":{"docs":{},"会":{"docs":{},"被":{"docs":{},"创":{"docs":{},"建":{"docs":{},"并":{"docs":{},"被":{"docs":{},"赋":{"docs":{},"予":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"发":{"docs":{},"起":{"docs":{},"一":{"docs":{},"个":{"docs":{},"匿":{"docs":{},"名":{"docs":{},"(":{"docs":{},"未":{"docs":{},"登":{"docs":{},"录":{"docs":{},")":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"到":{"docs":{},"路":{"docs":{},"径":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}},"应":{"docs":{},"用":{"docs":{},"的":{"docs":{},"名":{"docs":{},"称":{"docs":{},"(":{"docs":{},"上":{"docs":{},"面":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}},"配":{"docs":{},"置":{"docs":{},"文":{"docs":{},"件":{"docs":{},"告":{"docs":{},"诉":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"就":{"docs":{},"是":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}},"些":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"静":{"docs":{},"态":{"docs":{},"资":{"docs":{},"源":{"docs":{},"。":{"docs":{},"w":{"docs":{},"w":{"docs":{},"w":{"docs":{},"r":{"docs":{},"o":{"docs":{},"o":{"docs":{},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}},"都":{"docs":{},"默":{"docs":{},"认":{"docs":{},"包":{"docs":{},"括":{"docs":{},"在":{"docs":{},"了":{"docs":{},"所":{"docs":{},"有":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}},"命":{"docs":{},"令":{"docs":{},"必":{"docs":{},"须":{"docs":{},"在":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"执":{"docs":{},"行":{"docs":{},"(":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"m":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"所":{"docs":{},"在":{"docs":{},"目":{"docs":{},"录":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"安":{"docs":{},"全":{"docs":{},"及":{"docs":{},"身":{"docs":{},"份":{"docs":{},"鉴":{"docs":{},"别":{"docs":{},"的":{"docs":{},"特":{"docs":{},"性":{"docs":{},"到":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},"。":{"docs":{},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}},"编":{"docs":{},"译":{"docs":{},"好":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"将":{"docs":{},"会":{"docs":{},"通":{"docs":{},"过":{"docs":{},"这":{"docs":{},"最":{"docs":{},"终":{"docs":{},"的":{"docs":{},"几":{"docs":{},"条":{"docs":{},"命":{"docs":{},"令":{"docs":{},",":{"docs":{},"运":{"docs":{},"行":{"docs":{},"起":{"docs":{},"这":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"样":{"docs":{},"的":{"docs":{},"前":{"docs":{},"端":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"容":{"docs":{},"器":{"docs":{},"化":{"docs":{},"技":{"docs":{},"术":{"docs":{},"能":{"docs":{},"极":{"docs":{},"大":{"docs":{},"地":{"docs":{},"简":{"docs":{},"化":{"docs":{},"把":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"平":{"docs":{},"台":{"docs":{},",":{"docs":{},"像":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"一":{"docs":{},"行":{"docs":{},"告":{"docs":{},"知":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"给":{"docs":{},"类":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}},"的":{"docs":{},"存":{"docs":{},"在":{"docs":{},",":{"docs":{},"此":{"docs":{},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"在":{"docs":{},"被":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"期":{"docs":{},"望":{"docs":{},"被":{"docs":{},"传":{"docs":{},"入":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}},"项":{"docs":{},"已":{"docs":{},"经":{"docs":{},"在":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}},"行":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"服":{"docs":{},"务":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"是":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}},"代":{"docs":{},"码":{"docs":{},"通":{"docs":{},"过":{"docs":{},"检":{"docs":{},"查":{"docs":{},"你":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"里":{"docs":{},"所":{"docs":{},"做":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"变":{"docs":{},"更":{"docs":{},",":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"种":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},"成":{"docs":{},"熟":{"docs":{},"的":{"docs":{},"生":{"docs":{},"态":{"docs":{},"系":{"docs":{},"统":{"docs":{},",":{"docs":{},"其":{"docs":{},"最":{"docs":{},"大":{"docs":{},"的":{"docs":{},"优":{"docs":{},"势":{"docs":{},"之":{"docs":{},"一":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"第":{"docs":{},"三":{"docs":{},"方":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"和":{"docs":{},"插":{"docs":{},"件":{"docs":{},"的":{"docs":{},"量":{"docs":{},"非":{"docs":{},"常":{"docs":{},"庞":{"docs":{},"大":{"docs":{},"。":{"docs":{},"正":{"docs":{},"如":{"docs":{},"其":{"docs":{},"它":{"docs":{},"的":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"系":{"docs":{},"统":{"docs":{},"一":{"docs":{},"样":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"下":{"docs":{},"载":{"docs":{},"并":{"docs":{},"安":{"docs":{},"装":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"关":{"docs":{},"系":{"docs":{},"型":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"与":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}},"云":{"docs":{},"端":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"为":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"处":{"docs":{},"理":{"docs":{},"身":{"docs":{},"份":{"docs":{},"验":{"docs":{},"证":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"选":{"docs":{},"项":{"docs":{},"看":{"docs":{},"作":{"docs":{},"发":{"docs":{},"展":{"docs":{},"的":{"docs":{},"各":{"docs":{},"个":{"docs":{},"环":{"docs":{},"节":{"docs":{},":":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"情":{"docs":{},"形":{"docs":{},"—":{"docs":{},"—":{"docs":{},"你":{"docs":{},"意":{"docs":{},"识":{"docs":{},"不":{"docs":{},"到":{"docs":{},"自":{"docs":{},"己":{"docs":{},"改":{"docs":{},"变":{"docs":{},"了":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},",":{"docs":{},"虽":{"docs":{},"然":{"docs":{},"现":{"docs":{},"在":{"docs":{},"看":{"docs":{},"起":{"docs":{},"来":{"docs":{},"好":{"docs":{},"像":{"docs":{},"不":{"docs":{},"会":{"docs":{},"发":{"docs":{},"生":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"更":{"docs":{},"大":{"docs":{},"更":{"docs":{},"复":{"docs":{},"杂":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},",":{"docs":{},"这":{"docs":{},"会":{"docs":{},"因":{"docs":{},"为":{"docs":{},"各":{"docs":{},"种":{"docs":{},"决":{"docs":{},"策":{"docs":{},"和":{"docs":{},"假":{"docs":{},"设":{"docs":{},"而":{"docs":{},"变":{"docs":{},"得":{"docs":{},"难":{"docs":{},"以":{"docs":{},"追":{"docs":{},"踪":{"docs":{},"。":{"docs":{},"在":{"docs":{},"越":{"docs":{},"大":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},",":{"docs":{},"确":{"docs":{},"保":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"稳":{"docs":{},"定":{"docs":{},"的":{"docs":{},"自":{"docs":{},"动":{"docs":{},"化":{"docs":{},"检":{"docs":{},"查":{"docs":{},"就":{"docs":{},"越":{"docs":{},"重":{"docs":{},"要":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"段":{"docs":{},"代":{"docs":{},"码":{"docs":{},"把":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"先":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"将":{"docs":{},"运":{"docs":{},"行":{"docs":{},"所":{"docs":{},"有":{"docs":{},"迟":{"docs":{},"于":{"docs":{},"你":{"docs":{},"指":{"docs":{},"定":{"docs":{},"变":{"docs":{},"更":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}},"条":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"命":{"docs":{},"令":{"docs":{},"会":{"docs":{},"导":{"docs":{},"致":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}},"两":{"docs":{},"个":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"服":{"docs":{},"务":{"docs":{},"方":{"docs":{},"法":{"docs":{},"现":{"docs":{},"在":{"docs":{},"也":{"docs":{},"必":{"docs":{},"须":{"docs":{},"接":{"docs":{},"受":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}},"是":{"docs":{},"因":{"docs":{},"为":{"docs":{},"注":{"docs":{},"册":{"docs":{},"用":{"docs":{},"户":{"docs":{},"不":{"docs":{},"会":{"docs":{},"自":{"docs":{},"动":{"docs":{},"获":{"docs":{},"得":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}},"个":{"docs":{},"很":{"docs":{},"适":{"docs":{},"合":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"使":{"docs":{},"用":{"docs":{},"场":{"docs":{},"景":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"它":{"docs":{},"涵":{"docs":{},"盖":{"docs":{},"了":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"多":{"docs":{},"个":{"docs":{},"组":{"docs":{},"件":{"docs":{},":":{"docs":{},"路":{"docs":{},"由":{"docs":{},"系":{"docs":{},"统":{"docs":{},"、":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"、":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"被":{"docs":{},"标":{"docs":{},"记":{"docs":{},"了":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"指":{"docs":{},"示":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"进":{"docs":{},"行":{"docs":{},"编":{"docs":{},"程":{"docs":{},",":{"docs":{},"但":{"docs":{},"跟":{"docs":{},"你":{"docs":{},"熟":{"docs":{},"知":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"相":{"docs":{},"去":{"docs":{},"不":{"docs":{},"远":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}},"认":{"docs":{},"证":{"docs":{},"检":{"docs":{},"查":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"所":{"docs":{},"有":{"docs":{},"检":{"docs":{},"查":{"docs":{},"都":{"docs":{},"通":{"docs":{},"过":{"docs":{},"了":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"该":{"docs":{},"用":{"docs":{},"户":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},",":{"docs":{},"导":{"docs":{},"航":{"docs":{},"条":{"docs":{},"上":{"docs":{},"就":{"docs":{},"会":{"docs":{},"加":{"docs":{},"入":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"反":{"docs":{},"向":{"docs":{},"代":{"docs":{},"理":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"部":{"docs":{},"署":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":3.3341829510053804}}}}}},"选":{"docs":{},"择":{"docs":{},"你":{"docs":{},"的":{"docs":{},"语":{"docs":{},"言":{"docs":{},"阅":{"docs":{},"读":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"命":{"docs":{},"令":{"docs":{},"行":{"docs":{},"应":{"docs":{},"用":{"docs":{},"(":{"docs":{},"一":{"docs":{},"种":{"docs":{},"向":{"docs":{},"屏":{"docs":{},"幕":{"docs":{},"输":{"docs":{},"出":{"docs":{},"文":{"docs":{},"本":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},")":{"docs":{},"的":{"docs":{},"模":{"docs":{},"板":{"docs":{},"。":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}}}}},"诸":{"docs":{},"如":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"定":{"docs":{},"了":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},",":{"docs":{},"就":{"docs":{},"该":{"docs":{},"去":{"docs":{},"获":{"docs":{},"取":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}},"项":{"docs":{},",":{"docs":{},"获":{"docs":{},"取":{"docs":{},"你":{"docs":{},"所":{"docs":{},"在":{"docs":{},"平":{"docs":{},"台":{"docs":{},"更":{"docs":{},"详":{"docs":{},"细":{"docs":{},"的":{"docs":{},"信":{"docs":{},"息":{"docs":{},":":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}}}}}}}},"移":{"docs":{},"除":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"指":{"docs":{},"示":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"速":{"docs":{},"度":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"那":{"docs":{},"些":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"已":{"docs":{},"经":{"docs":{},"学":{"docs":{},"会":{"docs":{},"一":{"docs":{},"半":{"docs":{},"了":{"docs":{},":":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}},"行":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}},"章":{"docs":{},"添":{"docs":{},"加":{"docs":{},"真":{"docs":{},"正":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"去":{"docs":{},"访":{"docs":{},"问":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}},",":{"docs":{},"我":{"docs":{},"会":{"docs":{},"深":{"docs":{},"入":{"docs":{},"讲":{"docs":{},"解":{"docs":{},"有":{"docs":{},"关":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"但":{"docs":{},"目":{"docs":{},"前":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"造":{"docs":{},"个":{"docs":{},"假":{"docs":{},",":{"docs":{},"直":{"docs":{},"接":{"docs":{},"返":{"docs":{},"回":{"docs":{},"硬":{"docs":{},"编":{"docs":{},"码":{"docs":{},"的":{"docs":{},"值":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"行":{"docs":{},"告":{"docs":{},"知":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"一":{"docs":{},"节":{"docs":{},",":{"docs":{},"我":{"docs":{},"会":{"docs":{},"讲":{"docs":{},"述":{"docs":{},"如":{"docs":{},"何":{"docs":{},"配":{"docs":{},"置":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}},"个":{"docs":{},"方":{"docs":{},"式":{"docs":{},",":{"docs":{},"依":{"docs":{},"然":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"任":{"docs":{},"意":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}},"项":{"docs":{},"目":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":2.501412429378531}},"成":{"docs":{},"了":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}},"参":{"docs":{},"数":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},"那":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"现":{"docs":{},"在":{"docs":{},"就":{"docs":{},"创":{"docs":{},"建":{"docs":{},"并":{"docs":{},"运":{"docs":{},"行":{"docs":{},"那":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"直":{"docs":{},"到":{"docs":{},"看":{"docs":{},"见":{"docs":{},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{},"欢":{"docs":{},"迎":{"docs":{},"页":{"docs":{},"面":{"docs":{},"为":{"docs":{},"止":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"文":{"docs":{},"件":{"docs":{},"基":{"docs":{},"于":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},"所":{"docs":{},"在":{"docs":{},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}},"到":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"里":{"docs":{},"的":{"docs":{},"路":{"docs":{},"径":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"的":{"docs":{},"各":{"docs":{},"部":{"docs":{},"分":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},"要":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"部":{"docs":{},"署":{"docs":{},"配":{"docs":{},"置":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}},"目":{"docs":{},"录":{"docs":{},"边":{"docs":{},"上":{"docs":{},"添":{"docs":{},"加":{"docs":{},"多":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"全":{"docs":{},"都":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"单":{"docs":{},"一":{"docs":{},"的":{"docs":{},"根":{"docs":{},"解":{"docs":{},"决":{"docs":{},"方":{"docs":{},"案":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"操":{"docs":{},"作":{"docs":{},"是":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"中":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"模":{"docs":{},"板":{"docs":{},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"准":{"docs":{},"备":{"docs":{},"已":{"docs":{},"经":{"docs":{},"就":{"docs":{},"绪":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}},"该":{"docs":{},"模":{"docs":{},"板":{"docs":{},"中":{"docs":{},"带":{"docs":{},"有":{"docs":{},"几":{"docs":{},"个":{"docs":{},"类":{"docs":{},",":{"docs":{},"构":{"docs":{},"建":{"docs":{},"在":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}},"中":{"docs":{},"的":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"(":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}},"及":{"docs":{},"以":{"docs":{},"上":{"docs":{},"列":{"docs":{},"表":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},")":{"docs":{},"一":{"docs":{},"无":{"docs":{},"所":{"docs":{},"知":{"docs":{},",":{"docs":{},"也":{"docs":{},"不":{"docs":{},"妨":{"docs":{},"碍":{"docs":{},"你":{"docs":{},"学":{"docs":{},"下":{"docs":{},"去":{"docs":{},"。":{"docs":{"./":{"ref":"./","tf":0.0008833922261484099}}}}}}}}}}}}}}}}}}}}}}}}},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{},")":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"之":{"docs":{},"间":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"抽":{"docs":{},"象":{"docs":{},"层":{"docs":{},",":{"docs":{},"并":{"docs":{},"以":{"docs":{},"此":{"docs":{},"简":{"docs":{},"化":{"docs":{},"了":{"docs":{},"与":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},"代":{"docs":{},"码":{"docs":{},"的":{"docs":{},"编":{"docs":{},"写":{"docs":{},"。":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"下":{"docs":{},",":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},"用":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603}}},"一":{"docs":{},"章":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"使":{"docs":{},"用":{"docs":{},"另":{"docs":{},"一":{"docs":{},"套":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"在":{"docs":{},"程":{"docs":{},"序":{"docs":{},"中":{"docs":{},"添":{"docs":{},"加":{"docs":{},"更":{"docs":{},"多":{"docs":{},"的":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"从":{"docs":{},"“":{"docs":{},"创":{"docs":{},"建":{"docs":{},"新":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}},"步":{"docs":{},"是":{"docs":{},"修":{"docs":{},"改":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"查":{"docs":{},"询":{"docs":{},",":{"docs":{},"并":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"层":{"docs":{},"过":{"docs":{},"滤":{"docs":{},",":{"docs":{},"仅":{"docs":{},"显":{"docs":{},"示":{"docs":{},"当":{"docs":{},"前":{"docs":{},"用":{"docs":{},"户":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},"。":{"docs":{},"但":{"docs":{},"在":{"docs":{},"做":{"docs":{},"这":{"docs":{},"些":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"字":{"docs":{},"段":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"面":{"docs":{},"看":{"docs":{},"到":{"docs":{},"红":{"docs":{},"色":{"docs":{},"的":{"docs":{},"波":{"docs":{},"浪":{"docs":{},"线":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"该":{"docs":{},"方":{"docs":{},"法":{"docs":{},"尚":{"docs":{},"未":{"docs":{},"定":{"docs":{},"义":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"划":{"docs":{},"线":{"docs":{},"开":{"docs":{},"始":{"docs":{},",":{"docs":{},"但":{"docs":{},"这":{"docs":{},"不":{"docs":{},"是":{"docs":{},"强":{"docs":{},"制":{"docs":{},"性":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}},"。":{"docs":{},"注":{"docs":{},"意":{"docs":{},"实":{"docs":{},"际":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"(":{"docs":{},".":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"了":{"docs":{},"。":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}},"吗":{"docs":{},"?":{"docs":{},"它":{"docs":{},"表":{"docs":{},"示":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"!":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"准":{"docs":{},"备":{"docs":{},"好":{"docs":{},"创":{"docs":{},"建":{"docs":{},"你":{"docs":{},"的":{"docs":{},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}},"材":{"docs":{},"料":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"及":{"docs":{},"以":{"docs":{},"上":{"docs":{},"的":{"docs":{},"版":{"docs":{},"本":{"docs":{},"(":{"docs":{},"免":{"docs":{},"费":{"docs":{},"的":{"docs":{},"社":{"docs":{},"区":{"docs":{},"版":{"docs":{},"就":{"docs":{},"够":{"docs":{},"用":{"docs":{},"了":{"docs":{},")":{"docs":{},"。":{"docs":{},"v":{"docs":{},"i":{"docs":{},"s":{"docs":{},"u":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"着":{"docs":{},"优":{"docs":{},"秀":{"docs":{},"的":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}},"三":{"docs":{},"个":{"docs":{},"组":{"docs":{},"件":{"docs":{},":":{"docs":{},"模":{"docs":{},"型":{"docs":{},"、":{"docs":{},"视":{"docs":{},"图":{"docs":{},"、":{"docs":{},"和":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"。":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"处":{"docs":{},"理":{"docs":{},"从":{"docs":{},"客":{"docs":{},"户":{"docs":{},"端":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},",":{"docs":{},"并":{"docs":{},"选":{"docs":{},"定":{"docs":{},"相":{"docs":{},"应":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"进":{"docs":{},"行":{"docs":{},"处":{"docs":{},"理":{"docs":{},"。":{"docs":{},"视":{"docs":{},"图":{"docs":{},"就":{"docs":{},"是":{"docs":{},"模":{"docs":{},"板":{"docs":{},"(":{"docs":{},"一":{"docs":{},"般":{"docs":{},"是":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"助":{"docs":{},"于":{"docs":{},"实":{"docs":{},"现":{"docs":{},"这":{"docs":{},"些":{"docs":{},"功":{"docs":{},"能":{"docs":{},"。":{"docs":{},"前":{"docs":{},"两":{"docs":{},"个":{"docs":{},"(":{"docs":{},"防":{"docs":{},"止":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{},"注":{"docs":{},"入":{"docs":{},"和":{"docs":{},"跨":{"docs":{},"域":{"docs":{},"攻":{"docs":{},"击":{"docs":{},")":{"docs":{},"功":{"docs":{},"能":{"docs":{},"已":{"docs":{},"经":{"docs":{},"内":{"docs":{},"置":{"docs":{},"了":{"docs":{},",":{"docs":{},"要":{"docs":{},"开":{"docs":{},"启":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"两":{"docs":{},"个":{"docs":{},"依":{"docs":{},"赖":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"很":{"docs":{},"多":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"可":{"docs":{},"以":{"docs":{},"命":{"docs":{},"名":{"docs":{},"和":{"docs":{},"组":{"docs":{},"织":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"它":{"docs":{},"们":{"docs":{},"都":{"docs":{},"有":{"docs":{},"着":{"docs":{},"各":{"docs":{},"自":{"docs":{},"的":{"docs":{},"优":{"docs":{},"缺":{"docs":{},"点":{"docs":{},"。":{"docs":{},"我":{"docs":{},"喜":{"docs":{},"欢":{"docs":{},"给":{"docs":{},"测":{"docs":{},"试":{"docs":{},"类":{"docs":{},"加":{"docs":{},"上":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"构":{"docs":{},"建":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}},"造":{"docs":{},"函":{"docs":{},"数":{"docs":{},"(":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"s":{"docs":{},"t":{"docs":{},"r":{"docs":{},"u":{"docs":{},"c":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},")":{"docs":{},"。":{"docs":{},"构":{"docs":{},"造":{"docs":{},"函":{"docs":{},"数":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"特":{"docs":{},"殊":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"它":{"docs":{},"会":{"docs":{},"在":{"docs":{},"为":{"docs":{},"(":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},"是":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"百":{"docs":{},"度":{"docs":{},",":{"docs":{},"试":{"docs":{},"试":{"docs":{"chapters/your-first-application/":{"ref":"chapters/your-first-application/","tf":0.0053475935828877}}}}}}},"x":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.015384615384615385},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}},"m":{"docs":{},"l":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"定":{"docs":{},"义":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"关":{"docs":{},"于":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"元":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{},"到":{"docs":{},"后":{"docs":{},"面":{"docs":{},",":{"docs":{},"你":{"docs":{},"引":{"docs":{},"用":{"docs":{},"其":{"docs":{},"它":{"docs":{},"包":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"那":{"docs":{},"些":{"docs":{},"包":{"docs":{},"将":{"docs":{},"被":{"docs":{},"记":{"docs":{},"录":{"docs":{},"在":{"docs":{},"这":{"docs":{},"里":{"docs":{},"(":{"docs":{},"类":{"docs":{},"似":{"docs":{},"于":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"解":{"docs":{},"析":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},".":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}},")":{"docs":{},";":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}},"s":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}},"n":{"docs":{},"a":{"docs":{},"m":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},"?":{"docs":{},"\"":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"u":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}}}}},";":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}},"命":{"docs":{},"令":{"docs":{},"行":{"docs":{},"工":{"docs":{},"具":{"docs":{},"(":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}}}}},"里":{"docs":{},"实":{"docs":{},"施":{"docs":{},"。":{"docs":{},"我":{"docs":{},"会":{"docs":{},"讲":{"docs":{},"解":{"docs":{},"后":{"docs":{},"者":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}},"镜":{"docs":{},"像":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"基":{"docs":{},"本":{"docs":{},"的":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}},"的":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"查":{"docs":{},"看":{"docs":{},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"更":{"docs":{},"的":{"docs":{},"列":{"docs":{},"表":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}},"在":{"docs":{},"当":{"docs":{},"前":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},"查":{"docs":{},"找":{"docs":{},"测":{"docs":{},"试":{"docs":{},"方":{"docs":{},"法":{"docs":{},"(":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},",":{"docs":{},"由":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}},"确":{"docs":{},"认":{"docs":{},"它":{"docs":{},"已":{"docs":{},"经":{"docs":{},"安":{"docs":{},"装":{"docs":{},"了":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}},"获":{"docs":{},"取":{"docs":{},"一":{"docs":{},"个":{"docs":{},"地":{"docs":{},"点":{"docs":{},"列":{"docs":{},"表":{"docs":{},",":{"docs":{},"并":{"docs":{},"找":{"docs":{},"出":{"docs":{},"距":{"docs":{},"离":{"docs":{},"你":{"docs":{},"比":{"docs":{},"较":{"docs":{},"近":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"应":{"docs":{},"该":{"docs":{},"看":{"docs":{},"到":{"docs":{},"如":{"docs":{},"下":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"再":{"docs":{},"次":{"docs":{},"被":{"docs":{},"用":{"docs":{},"到":{"docs":{},",":{"docs":{},"以":{"docs":{},"选":{"docs":{},"择":{"docs":{},"一":{"docs":{},"个":{"docs":{},"较":{"docs":{},"小":{"docs":{},"的":{"docs":{},"镜":{"docs":{},"像":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"仅":{"docs":{},"含":{"docs":{},"有":{"docs":{},"运":{"docs":{},"行":{"docs":{},"程":{"docs":{},"序":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"。":{"docs":{},"e":{"docs":{},"n":{"docs":{},"v":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"列":{"docs":{},"出":{"docs":{},"你":{"docs":{},"本":{"docs":{},"地":{"docs":{},"电":{"docs":{},"脑":{"docs":{},"上":{"docs":{},"的":{"docs":{},"全":{"docs":{},"部":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"。":{"docs":{},"要":{"docs":{},"通":{"docs":{},"过":{"docs":{},"容":{"docs":{},"器":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"一":{"docs":{},"下":{"docs":{},",":{"docs":{},"请":{"docs":{},"执":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{},"于":{"docs":{},"容":{"docs":{},"器":{"docs":{},"中":{"docs":{},"的":{"docs":{},"设":{"docs":{},"置":{"docs":{},"环":{"docs":{},"境":{"docs":{},"变":{"docs":{},"量":{"docs":{},",":{"docs":{},"环":{"docs":{},"境":{"docs":{},"变":{"docs":{},"量":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}},"给":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"编":{"docs":{},"译":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"而":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"重":{"docs":{},"建":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"搜":{"docs":{},"索":{"docs":{},"“":{"docs":{},"下":{"docs":{},"载":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}}},"获":{"docs":{},"取":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":5.007692307692308}},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}},"还":{"docs":{},"可":{"docs":{},"以":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/your-first-application/get-the-sdk.html":{"ref":"chapters/your-first-application/get-the-sdk.html","tf":0.007692307692307693}}}}}},"有":{"docs":{},"很":{"docs":{},"多":{"docs":{},"值":{"docs":{},"得":{"docs":{},"研":{"docs":{},"究":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"让":{"docs":{},"我":{"docs":{},"们":{"docs":{},"着":{"docs":{},"手":{"docs":{},"构":{"docs":{},"建":{"docs":{},"这":{"docs":{},"个":{"docs":{},"应":{"docs":{},"用":{"docs":{},"吧":{"docs":{},"!":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}},"其":{"docs":{},"它":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"例":{"docs":{},"如":{"docs":{},"密":{"docs":{},"码":{"docs":{},"重":{"docs":{},"置":{"docs":{},"以":{"docs":{},"及":{"docs":{},"社":{"docs":{},"交":{"docs":{},"账":{"docs":{},"户":{"docs":{},"登":{"docs":{},"录":{"docs":{},"。":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"无":{"docs":{},"法":{"docs":{},"纳":{"docs":{},"入":{"docs":{},"到":{"docs":{},"这":{"docs":{},"本":{"docs":{},"小":{"docs":{},"册":{"docs":{},"子":{"docs":{},"里":{"docs":{},",":{"docs":{},"包":{"docs":{},"括":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}},"更":{"docs":{},"多":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{},"部":{"docs":{},"分":{"docs":{},"视":{"docs":{},"图":{"docs":{},"和":{"docs":{},"后":{"docs":{},"端":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"的":{"docs":{},"视":{"docs":{},"图":{"docs":{},"组":{"docs":{},"件":{"docs":{},",":{"docs":{},"但":{"docs":{},"你":{"docs":{},"现":{"docs":{},"在":{"docs":{},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"一":{"docs":{},"个":{"docs":{},"简":{"docs":{},"单":{"docs":{},"的":{"docs":{},"布":{"docs":{},"局":{"docs":{},"和":{"docs":{},"视":{"docs":{},"图":{"docs":{},"。":{"docs":{},"想":{"docs":{},"要":{"docs":{},"了":{"docs":{},"解":{"docs":{},"更":{"docs":{},"多":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"那":{"docs":{},"句":{"docs":{},"话":{"docs":{},",":{"docs":{},"把":{"docs":{},"所":{"docs":{},"有":{"docs":{},"这":{"docs":{},"些":{"docs":{},"东":{"docs":{},"西":{"docs":{},"写":{"docs":{},"进":{"docs":{},"一":{"docs":{},"个":{"docs":{},"单":{"docs":{},"独":{"docs":{},"的":{"docs":{},"巨":{"docs":{},"大":{"docs":{},"的":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"是":{"docs":{},"可":{"docs":{},"行":{"docs":{},"的":{"docs":{},",":{"docs":{},"但":{"docs":{},"这":{"docs":{},"很":{"docs":{},"快":{"docs":{},"就":{"docs":{},"会":{"docs":{},"变":{"docs":{},"得":{"docs":{},"难":{"docs":{},"以":{"docs":{},"管":{"docs":{},"理":{"docs":{},"和":{"docs":{},"测":{"docs":{},"试":{"docs":{},"。":{"docs":{},"相":{"docs":{},"反":{"docs":{},",":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"都":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"分":{"docs":{},"割":{"docs":{},"成":{"docs":{},"两":{"docs":{},"个":{"docs":{},"、":{"docs":{},"三":{"docs":{},"个":{"docs":{},"或":{"docs":{},"更":{"docs":{},"多":{"docs":{},"的":{"docs":{},"“":{"docs":{},"层":{"docs":{},"”":{"docs":{},"或":{"docs":{},"级":{"docs":{},",":{"docs":{},"每":{"docs":{},"个":{"docs":{},"层":{"docs":{},"级":{"docs":{},"处":{"docs":{},"理":{"docs":{},"(":{"docs":{},"且":{"docs":{},"仅":{"docs":{},"处":{"docs":{},"理":{"docs":{},")":{"docs":{},"一":{"docs":{},"件":{"docs":{},"事":{"docs":{},"情":{"docs":{},"。":{"docs":{},"这":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"保":{"docs":{},"持":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"尽":{"docs":{},"量":{"docs":{},"简":{"docs":{},"单":{"docs":{},",":{"docs":{},"并":{"docs":{},"简":{"docs":{},"化":{"docs":{},"测":{"docs":{},"试":{"docs":{},"工":{"docs":{},"作":{"docs":{},",":{"docs":{},"以":{"docs":{},"及":{"docs":{},"后":{"docs":{},"续":{"docs":{},"的":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"代":{"docs":{},"码":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"记":{"docs":{},"得":{"docs":{},"吗":{"docs":{},"?":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"创":{"docs":{},"建":{"docs":{},"服":{"docs":{},"务":{"docs":{},"接":{"docs":{},"口":{"docs":{},"以":{"docs":{},"解":{"docs":{},"耦":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"和":{"docs":{},"服":{"docs":{},"务":{"docs":{},"的":{"docs":{},"实":{"docs":{},"现":{"docs":{},"类":{"docs":{},"吗":{"docs":{},"?":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"环":{"docs":{},"境":{"docs":{},"变":{"docs":{},"量":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"进":{"docs":{},"行":{"docs":{},"了":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"要":{"docs":{},"在":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"回":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"{":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.017804154302670624},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.025},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.032432432432432434},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.014457831325301205},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0226628895184136},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.016483516483516484},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.01904761904761905},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.014545454545454545},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.018050541516245487},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.01569713758079409},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.018691588785046728},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.029850746268656716},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.040310077519379844},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.013816925734024179},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0258732212160414},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}}},"}":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.017804154302670624},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.025},"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.032432432432432434},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.01927710843373494},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.014164305949008499},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.016483516483516484},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.043859649122807015},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.007272727272727273},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.018050541516245487},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.013850415512465374},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.014018691588785047},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.027860696517412936},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.037209302325581395},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.008635578583765112},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.02328589909443726},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.006796941376380629}},")":{"docs":{},";":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}},";":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0056657223796034},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},",":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}},",":{"docs":{},"看":{"docs":{},"看":{"docs":{},"会":{"docs":{},"发":{"docs":{},"生":{"docs":{},"什":{"docs":{},"么":{"docs":{},"!":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}},"为":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"文":{"docs":{},"件":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}},"了":{"docs":{},"向":{"docs":{},"导":{"docs":{},"航":{"docs":{},"栏":{"docs":{},"添":{"docs":{},"加":{"docs":{},"新":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"请":{"docs":{},"先":{"docs":{},"找":{"docs":{},"到":{"docs":{},"原":{"docs":{},"有":{"docs":{},"导":{"docs":{},"航":{"docs":{},"栏":{"docs":{},"的":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}}}}},"把":{"docs":{},"“":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"中":{"docs":{},"的":{"docs":{},"改":{"docs":{},"动":{"docs":{},"”":{"docs":{},"反":{"docs":{},"映":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"整":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},"栈":{"docs":{},"(":{"docs":{},"包":{"docs":{},"括":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"路":{"docs":{},"由":{"docs":{},")":{"docs":{},",":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"往":{"docs":{},"往":{"docs":{},"像":{"docs":{},"网":{"docs":{},"络":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"那":{"docs":{},"样":{"docs":{},"向":{"docs":{},"程":{"docs":{},"序":{"docs":{},"发":{"docs":{},"起":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"完":{"docs":{},"成":{"docs":{},"了":{"docs":{},"很":{"docs":{},"多":{"docs":{},"工":{"docs":{},"作":{"docs":{},"!":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}},"保":{"docs":{},"持":{"docs":{},"各":{"docs":{},"部":{"docs":{},"分":{"docs":{},"独":{"docs":{},"立":{"docs":{},"且":{"docs":{},"组":{"docs":{},"织":{"docs":{},"良":{"docs":{},"好":{"docs":{},",":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"以":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}},"包":{"docs":{},"含":{"docs":{},"该":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"的":{"docs":{},"行":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"创":{"docs":{},"建":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"实":{"docs":{},"践":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"把":{"docs":{},"它":{"docs":{},"们":{"docs":{},"和":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"代":{"docs":{},"码":{"docs":{},"分":{"docs":{},"离":{"docs":{},"开":{"docs":{},"。":{"docs":{},"新":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},"应":{"docs":{},"该":{"docs":{},"被":{"docs":{},"置":{"docs":{},"于":{"docs":{},"你":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"同":{"docs":{},"级":{"docs":{},"目":{"docs":{},"录":{"docs":{},"(":{"docs":{},"而":{"docs":{},"非":{"docs":{},"在":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"内":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"验":{"docs":{},"证":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"执":{"docs":{},"行":{"docs":{},"的":{"docs":{},"正":{"docs":{},"确":{"docs":{},"性":{"docs":{},",":{"docs":{},"请":{"docs":{},"在":{"docs":{},"原":{"docs":{},"有":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}},"基":{"docs":{},"础":{"docs":{},"创":{"docs":{},"建":{"docs":{},"你":{"docs":{},"的":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"是":{"docs":{},"微":{"docs":{},"软":{"docs":{},"发":{"docs":{},"布":{"docs":{},"的":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"了":{"docs":{},"执":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"(":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":3.3341829510053804}},"一":{"docs":{},"个":{"docs":{},"布":{"docs":{},"局":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"用":{"docs":{},"以":{"docs":{},"定":{"docs":{},"义":{"docs":{},"容":{"docs":{},"纳":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},"基":{"docs":{},"础":{"docs":{},"结":{"docs":{},"构":{"docs":{},"的":{"docs":{},"其":{"docs":{},"余":{"docs":{},"部":{"docs":{},"分":{"docs":{},"。":{"docs":{},"布":{"docs":{},"局":{"docs":{},"视":{"docs":{},"图":{"docs":{},"被":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}},"列":{"docs":{},"表":{"docs":{},"下":{"docs":{},"面":{"docs":{},"那":{"docs":{},"个":{"docs":{},"简":{"docs":{},"易":{"docs":{},"的":{"docs":{},"表":{"docs":{},"单":{"docs":{},",":{"docs":{},"用":{"docs":{},"户":{"docs":{},"可":{"docs":{},"以":{"docs":{},"添":{"docs":{},"加":{"docs":{},"新":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"标":{"docs":{},"记":{"docs":{},"条":{"docs":{},"目":{"docs":{},"完":{"docs":{},"成":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":10.001168224299066}}}}}}}}}}},"它":{"docs":{},",":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"这":{"docs":{},"个":{"docs":{},"常":{"docs":{},"量":{"docs":{},"值":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"尽":{"docs":{},"可":{"docs":{},"能":{"docs":{},"保":{"docs":{},"持":{"docs":{},"轻":{"docs":{},"量":{"docs":{},"化":{"docs":{},",":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"习":{"docs":{},"惯":{"docs":{},"。":{"docs":{},"在":{"docs":{},"当":{"docs":{},"前":{"docs":{},"的":{"docs":{},"情":{"docs":{},"形":{"docs":{},"里":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"应":{"docs":{},"该":{"docs":{},"仅":{"docs":{},"仅":{"docs":{},"完":{"docs":{},"成":{"docs":{},"这":{"docs":{},"些":{"docs":{},"事":{"docs":{},"情":{"docs":{},":":{"docs":{},"从":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"取":{"docs":{},"出":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"的":{"docs":{},"记":{"docs":{},"录":{"docs":{},",":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"事":{"docs":{},"项":{"docs":{},"包":{"docs":{},"装":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"可":{"docs":{},"用":{"docs":{},"于":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},"模":{"docs":{},"型":{"docs":{},"中":{"docs":{},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"这":{"docs":{},"个":{"docs":{},"视":{"docs":{},"图":{"docs":{},"发":{"docs":{},"送":{"docs":{},"到":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"内":{"docs":{},"置":{"docs":{},"于":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}},"到":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"屏":{"docs":{},"幕":{"docs":{},"上":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},"由":{"docs":{},"两":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"构":{"docs":{},"成":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"(":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}}}},"要":{"docs":{},"放":{"docs":{},"置":{"docs":{},"你":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"路":{"docs":{},"径":{"docs":{},"下":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{},"你":{"docs":{},"的":{"docs":{},"“":{"docs":{},"我":{"docs":{},"的":{"docs":{},"文":{"docs":{},"档":{"docs":{},"”":{"docs":{},"目":{"docs":{},"录":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}}},"新":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},"之":{"docs":{},"后":{"docs":{},",":{"docs":{},"就":{"docs":{},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"运":{"docs":{},"行":{"docs":{},"这":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}},"了":{"docs":{},"此":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"上":{"docs":{},"一":{"docs":{},"层":{"docs":{},"的":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}},"剪":{"docs":{},"切":{"docs":{},"板":{"docs":{},",":{"docs":{},"并":{"docs":{},"把":{"docs":{},"它":{"docs":{},"在":{"docs":{},"本":{"docs":{},"地":{"docs":{},"仓":{"docs":{},"库":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}},"参":{"docs":{},"数":{"docs":{},"指":{"docs":{},"示":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}},",":{"docs":{},"表":{"docs":{},"示":{"docs":{},"你":{"docs":{},"做":{"docs":{},"出":{"docs":{},"如":{"docs":{},"下":{"docs":{},"声":{"docs":{},"明":{"docs":{},":":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}},"使":{"docs":{},"用":{"docs":{},",":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"了":{"docs":{},"吗":{"docs":{},"?":{"docs":{},"这":{"docs":{},"是":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"缺":{"docs":{},"失":{"docs":{},"了":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"无":{"docs":{},"法":{"docs":{},"解":{"docs":{},"析":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}},"了":{"docs":{},",":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"传":{"docs":{},"给":{"docs":{},"了":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"扩":{"docs":{},"展":{"docs":{},"名":{"docs":{},")":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}},",":{"docs":{},"打":{"docs":{},"开":{"docs":{},"前":{"docs":{},"面":{"docs":{},"那":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"的":{"docs":{},"话":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"看":{"docs":{},"到":{"docs":{},"以":{"docs":{},"下":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"指":{"docs":{},"令":{"docs":{},"运":{"docs":{},"行":{"docs":{},"这":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"在":{"docs":{},"代":{"docs":{},"码":{"docs":{},"编":{"docs":{},"译":{"docs":{},"完":{"docs":{},"成":{"docs":{},"之":{"docs":{},"后":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"看":{"docs":{},"到":{"docs":{},"输":{"docs":{},"出":{"docs":{},"在":{"docs":{},"控":{"docs":{},"制":{"docs":{},"台":{"docs":{},"里":{"docs":{},"面":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},":":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"默":{"docs":{},"认":{"docs":{},"会":{"docs":{},"用":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}},"告":{"docs":{},"诉":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}},",":{"docs":{},"在":{"docs":{},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"生":{"docs":{},"成":{"docs":{},"了":{"docs":{},"小":{"docs":{},"型":{"docs":{},"的":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}},"并":{"docs":{},"验":{"docs":{},"证":{"docs":{},"及":{"docs":{},"限":{"docs":{},"定":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"变":{"docs":{},"更":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"应":{"docs":{},"用":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"复":{"docs":{},"制":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"以":{"docs":{},"反":{"docs":{},"映":{"docs":{},"最":{"docs":{},"新":{"docs":{},"的":{"docs":{},"优":{"docs":{},"秀":{"docs":{},"实":{"docs":{},"践":{"docs":{},"。":{"docs":{},"修":{"docs":{},"正":{"docs":{},"了":{"docs":{},"笔":{"docs":{},"误":{"docs":{},",":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"来":{"docs":{},"自":{"docs":{},"读":{"docs":{},"者":{"docs":{},"的":{"docs":{},"建":{"docs":{},"议":{"docs":{},"。":{"docs":{},"还":{"docs":{},"弄":{"docs":{},"了":{"docs":{},"个":{"docs":{},"新":{"docs":{},"改":{"docs":{},"良":{"docs":{},"的":{"docs":{},"封":{"docs":{},"面":{"docs":{},"得":{"docs":{},"瑟":{"docs":{},"了":{"docs":{},"一":{"docs":{},"下":{"docs":{},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"后":{"docs":{},"的":{"docs":{},"分":{"docs":{},"号":{"docs":{},"。":{"docs":{},"修":{"docs":{},"正":{"docs":{},"中":{"docs":{},"文":{"docs":{},"版":{"docs":{},"译":{"docs":{},"者":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{},"修":{"docs":{},"正":{"docs":{},"其":{"docs":{},"它":{"docs":{},"笔":{"docs":{},"误":{"docs":{},"和":{"docs":{},"读":{"docs":{},"者":{"docs":{},"反":{"docs":{},"馈":{"docs":{},"的":{"docs":{},"问":{"docs":{},"题":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"定":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"所":{"docs":{},"用":{"docs":{},"的":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}},"的":{"docs":{},"模":{"docs":{},"板":{"docs":{},"带":{"docs":{},"给":{"docs":{},"你":{"docs":{},"预":{"docs":{},"先":{"docs":{},"构":{"docs":{},"建":{"docs":{},"好":{"docs":{},"的":{"docs":{},"视":{"docs":{},"图":{"docs":{},"和":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},",":{"docs":{},"用":{"docs":{},"以":{"docs":{},"处":{"docs":{},"理":{"docs":{},"这":{"docs":{},"些":{"docs":{},"常":{"docs":{},"见":{"docs":{},"情":{"docs":{},"景":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"你":{"docs":{},"快":{"docs":{},"速":{"docs":{},"上":{"docs":{},"手":{"docs":{},"和":{"docs":{},"运":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"出":{"docs":{},"了":{"docs":{},"在":{"docs":{},"被":{"docs":{},"运":{"docs":{},"行":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},"去":{"docs":{},"执":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"示":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"深":{"docs":{},"入":{"docs":{},"钻":{"docs":{},"研":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}},"源":{"docs":{},"文":{"docs":{},"件":{"docs":{},"(":{"docs":{},"带":{"docs":{},"有":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}}}}},"版":{"docs":{},"的":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":2.5029673590504453},"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"本":{"docs":{},"。":{"docs":{},"这":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"把":{"docs":{},"正":{"docs":{},"在":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"类":{"docs":{},"或":{"docs":{},"者":{"docs":{},"方":{"docs":{},"法":{"docs":{},"的":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"隔":{"docs":{},"离":{"docs":{},"出":{"docs":{},"来":{"docs":{},"。":{"docs":{},"(":{"docs":{},"这":{"docs":{},"很":{"docs":{},"重":{"docs":{},"要":{"docs":{},"!":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"在":{"docs":{},"测":{"docs":{},"试":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},",":{"docs":{},"显":{"docs":{},"然":{"docs":{},"不":{"docs":{},"应":{"docs":{},"该":{"docs":{},"一":{"docs":{},"失":{"docs":{},"手":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"语":{"docs":{},"句":{"docs":{},"引":{"docs":{},"入":{"docs":{},"了":{"docs":{"chapters/your-first-application/hello-world-in-csharp.html":{"ref":"chapters/your-first-application/hello-world-in-csharp.html","tf":0.002967359050445104}}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}},"以":{"docs":{},"符":{"docs":{},"号":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}},"将":{"docs":{},"遍":{"docs":{},"历":{"docs":{},"到":{"docs":{},"每":{"docs":{},"个":{"docs":{},"代":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},",":{"docs":{},"并":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{},"表":{"docs":{},"格":{"docs":{},"的":{"docs":{},"行":{"docs":{},"(":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"用":{"docs":{},"以":{"docs":{},"从":{"docs":{},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"型":{"docs":{},"里":{"docs":{},"抽":{"docs":{},"取":{"docs":{},"数":{"docs":{},"据":{"docs":{},"并":{"docs":{},"转":{"docs":{},"换":{"docs":{},"为":{"docs":{},"文":{"docs":{},"本":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"报":{"docs":{},"错":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}},"引":{"docs":{},"入":{"docs":{},"那":{"docs":{},"个":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"不":{"docs":{},"写":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"加":{"docs":{},"上":{"docs":{},":":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}},"以":{"docs":{},"导":{"docs":{},"入":{"docs":{},"该":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}},"。":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}},">":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.00423728813559322},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.01875},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0034542314335060447}}},"q":{"docs":{},"u":{"docs":{},"i":{"docs":{},"c":{"docs":{},"k":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"l":{"docs":{},"y":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},".":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}},"i":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"t":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},",":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"r":{"docs":{},"i":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.007220216606498195},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}},"y":{"docs":{},")":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"o":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"用":{"docs":{},"于":{"docs":{},"存":{"docs":{},"储":{"docs":{},"用":{"docs":{},"户":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}},"登":{"docs":{},"录":{"docs":{},"及":{"docs":{},"安":{"docs":{},"全":{"docs":{},"检":{"docs":{},"查":{"docs":{},"表":{"docs":{},"单":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"每":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"都":{"docs":{},"保":{"docs":{},"持":{"docs":{},"私":{"docs":{},"密":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"章":{"docs":{},"讲":{"docs":{},"解":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"测":{"docs":{},"试":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}},"里":{"docs":{},"说":{"docs":{},"明":{"docs":{},"原":{"docs":{},"因":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},",":{"docs":{},"深":{"docs":{},"入":{"docs":{},"地":{"docs":{},"使":{"docs":{},"用":{"docs":{},"了":{"docs":{},"整":{"docs":{},"个":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}},"旦":{"docs":{},"你":{"docs":{},"确":{"docs":{},"定":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"镜":{"docs":{},"像":{"docs":{},"创":{"docs":{},"建":{"docs":{},"完":{"docs":{},"成":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}},"层":{"docs":{},"。":{"docs":{},"(":{"docs":{},"这":{"docs":{},"个":{"docs":{},"目":{"docs":{},"录":{"docs":{},"也":{"docs":{},"叫":{"docs":{},"做":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}},"部":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"仓":{"docs":{},"库":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"管":{"docs":{},"理":{"docs":{},",":{"docs":{},"执":{"docs":{},"行":{"docs":{},"下":{"docs":{},"列":{"docs":{},"命":{"docs":{},"令":{"docs":{},"进":{"docs":{},"行":{"docs":{},"设":{"docs":{},"置":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}},"功":{"docs":{},"能":{"docs":{},"相":{"docs":{},"同":{"docs":{},",":{"docs":{},"但":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"额":{"docs":{},"外":{"docs":{},"好":{"docs":{},"处":{"docs":{},"—":{"docs":{},"—":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"代":{"docs":{},"码":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"器":{"docs":{},"的":{"docs":{},"左":{"docs":{},"边":{"docs":{},"栏":{"docs":{},"上":{"docs":{},"点":{"docs":{},"击":{"docs":{},",":{"docs":{},"以":{"docs":{},"设":{"docs":{},"置":{"docs":{},"一":{"docs":{},"个":{"docs":{},"断":{"docs":{},"点":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"性":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}},"后":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"面":{"docs":{},"会":{"docs":{},"提":{"docs":{},"示":{"docs":{},"你":{"docs":{},"保":{"docs":{},"存":{"docs":{},"解":{"docs":{},"决":{"docs":{},"方":{"docs":{},"案":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"把":{"docs":{},"它":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"(":{"docs":{},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"启":{"docs":{},"动":{"docs":{},"时":{"docs":{},"读":{"docs":{},"取":{"docs":{},"的":{"docs":{},"配":{"docs":{},"置":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"它":{"docs":{},"来":{"docs":{},"保":{"docs":{},"存":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"连":{"docs":{},"接":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"其":{"docs":{},"它":{"docs":{},"你":{"docs":{},"不":{"docs":{},"想":{"docs":{},"硬":{"docs":{},"编":{"docs":{},"码":{"docs":{},"的":{"docs":{},"任":{"docs":{},"何":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"(":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"用":{"docs":{},"的":{"docs":{},"是":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}},"并":{"docs":{},"导":{"docs":{},"航":{"docs":{},"至":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},",":{"docs":{},"并":{"docs":{},"以":{"docs":{},"普":{"docs":{},"通":{"docs":{},"用":{"docs":{},"户":{"docs":{},"身":{"docs":{},"份":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"去":{"docs":{},"访":{"docs":{},"问":{"docs":{},"一":{"docs":{},"下":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}},"处":{"docs":{},"理":{"docs":{},"和":{"docs":{},"调":{"docs":{},"整":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"、":{"docs":{},"提":{"docs":{},"供":{"docs":{},"静":{"docs":{},"态":{"docs":{},"内":{"docs":{},"容":{"docs":{},"和":{"docs":{},"错":{"docs":{},"误":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{},"在":{"docs":{},"这":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"还":{"docs":{},"可":{"docs":{},"以":{"docs":{},"向":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"注":{"docs":{},"入":{"docs":{},"容":{"docs":{},"器":{"docs":{},"中":{"docs":{},"添":{"docs":{},"加":{"docs":{},"你":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"(":{"docs":{},"后":{"docs":{},"面":{"docs":{},"细":{"docs":{},"说":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"这":{"docs":{},"个":{"docs":{},"表":{"docs":{},"单":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"用":{"docs":{},"户":{"docs":{},"账":{"docs":{},"号":{"docs":{},"的":{"docs":{},"存":{"docs":{},"储":{"docs":{},"、":{"docs":{},"散":{"docs":{},"列":{"docs":{},"并":{"docs":{},"保":{"docs":{},"存":{"docs":{},"密":{"docs":{},"码":{"docs":{},"、":{"docs":{},"还":{"docs":{},"负":{"docs":{},"责":{"docs":{},"管":{"docs":{},"理":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"角":{"docs":{},"色":{"docs":{},"。":{"docs":{},"它":{"docs":{},"支":{"docs":{},"持":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"小":{"docs":{},"贴":{"docs":{},"士":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"快":{"docs":{},"捷":{"docs":{},"编":{"docs":{},"译":{"docs":{},":":{"docs":{},"使":{"docs":{},"用":{"docs":{},"快":{"docs":{},"捷":{"docs":{},"键":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}},"我":{"docs":{},"的":{"docs":{},"文":{"docs":{},"档":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}},"们":{"docs":{},"需":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"两":{"docs":{},"个":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"模":{"docs":{},"型":{"docs":{},"类":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"表":{"docs":{},"示":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},"(":{"docs":{},"有":{"docs":{},"时":{"docs":{},"候":{"docs":{},"也":{"docs":{},"称":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"更":{"docs":{},"喜":{"docs":{},"欢":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"在":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{},"博":{"docs":{},"客":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}},"打":{"docs":{},"开":{"docs":{},"文":{"docs":{},"件":{"docs":{},"夹":{"docs":{},"。":{"docs":{},"打":{"docs":{},"开":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}},"项":{"docs":{},"目":{"docs":{},"的":{"docs":{},"根":{"docs":{},"文":{"docs":{},"件":{"docs":{},"夹":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}},"一":{"docs":{},"个":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"并":{"docs":{},"导":{"docs":{},"航":{"docs":{},"至":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"交":{"docs":{},"道":{"docs":{},",":{"docs":{},"这":{"docs":{},"一":{"docs":{},"章":{"docs":{},"将":{"docs":{},"教":{"docs":{},"你":{"docs":{},"基":{"docs":{},"础":{"docs":{},"知":{"docs":{},"识":{"docs":{},",":{"docs":{},"带":{"docs":{},"你":{"docs":{},"上":{"docs":{},"道":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"上":{"docs":{},",":{"docs":{},"始":{"docs":{},"终":{"docs":{},"采":{"docs":{},"用":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}},"包":{"docs":{},"和":{"docs":{},"压":{"docs":{},"缩":{"docs":{},"静":{"docs":{},"态":{"docs":{},"资":{"docs":{},"源":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}},"技":{"docs":{},"巧":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"接":{"docs":{},"下":{"docs":{},"来":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"新":{"docs":{},"目":{"docs":{},"录":{"docs":{},"以":{"docs":{},"保":{"docs":{},"存":{"docs":{},"你":{"docs":{},"的":{"docs":{},"整":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"进":{"docs":{},"到":{"docs":{},"该":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"型":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"调":{"docs":{},"用":{"docs":{},"到":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},",":{"docs":{},"进":{"docs":{},"行":{"docs":{},"实":{"docs":{},"际":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"操":{"docs":{},"作":{"docs":{},",":{"docs":{},"保":{"docs":{},"存":{"docs":{},"这":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"调":{"docs":{},"用":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},"去":{"docs":{},"修":{"docs":{},"改":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"将":{"docs":{},"要":{"docs":{},"由":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"提":{"docs":{},"醒":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"在":{"docs":{},"它":{"docs":{},"启":{"docs":{},"动":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"执":{"docs":{},"行":{"docs":{},"这":{"docs":{},"个":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"。":{"docs":{},"修":{"docs":{},"改":{"docs":{},"p":{"docs":{},"r":{"docs":{},"o":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"m":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},",":{"docs":{},"并":{"docs":{},"更":{"docs":{},"新":{"docs":{},"m":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{},"(":{"docs":{},")":{"docs":{},"去":{"docs":{},"调":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"b":{"docs":{},"a":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"为":{"docs":{},"部":{"docs":{},"署":{"docs":{},"工":{"docs":{},"作":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}},"在":{"docs":{},"你":{"docs":{},"刚":{"docs":{},"刚":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"组":{"docs":{},"里":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"一":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"是":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"又":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"于":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}},"口":{"docs":{},"(":{"docs":{},"i":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"r":{"docs":{},"f":{"docs":{},"a":{"docs":{},"c":{"docs":{},"e":{"docs":{},")":{"docs":{},",":{"docs":{},"在":{"docs":{},"接":{"docs":{},"口":{"docs":{},"中":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"对":{"docs":{},"象":{"docs":{},"中":{"docs":{},"方":{"docs":{},"法":{"docs":{},"和":{"docs":{},"属":{"docs":{},"性":{"docs":{},"的":{"docs":{},"定":{"docs":{},"义":{"docs":{},"与":{"docs":{},"实":{"docs":{},"际":{"docs":{},"包":{"docs":{},"含":{"docs":{},"这":{"docs":{},"些":{"docs":{},"方":{"docs":{},"法":{"docs":{},"和":{"docs":{},"属":{"docs":{},"性":{"docs":{},"的":{"docs":{},"类":{"docs":{},"分":{"docs":{},"离":{"docs":{},"开":{"docs":{},"来":{"docs":{},"。":{"docs":{},"接":{"docs":{},"口":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"解":{"docs":{},"耦":{"docs":{},"你":{"docs":{},"的":{"docs":{},"那":{"docs":{},"些":{"docs":{},"类":{"docs":{},",":{"docs":{},"也":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"如":{"docs":{},"你":{"docs":{},"接":{"docs":{},"下":{"docs":{},"来":{"docs":{},"(":{"docs":{},"以":{"docs":{},"及":{"docs":{},"在":{"docs":{},"后":{"docs":{},"续":{"docs":{},"的":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"但":{"docs":{},"总":{"docs":{},"是":{"docs":{},"返":{"docs":{},"回":{"docs":{},"这":{"docs":{},"个":{"docs":{},"包":{"docs":{},"含":{"docs":{},"两":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}},"你":{"docs":{},"还":{"docs":{},"没":{"docs":{},"告":{"docs":{},"诉":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"而":{"docs":{},"不":{"docs":{},"是":{"docs":{},"任":{"docs":{},"何":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"也":{"docs":{},"就":{"docs":{},"同":{"docs":{},"样":{"docs":{},"需":{"docs":{},"要":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"如":{"docs":{},"此":{"docs":{},"有":{"docs":{},"用":{"docs":{},"的":{"docs":{},"原":{"docs":{},"因":{"docs":{},"就":{"docs":{},"在":{"docs":{},"于":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"它":{"docs":{},"们":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"解":{"docs":{},"耦":{"docs":{},"(":{"docs":{},"分":{"docs":{},"离":{"docs":{},")":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},"的":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"。":{"docs":{},"既":{"docs":{},"然":{"docs":{},"这":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"于":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"对":{"docs":{},"象":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"那":{"docs":{},"一":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"它":{"docs":{},"的":{"docs":{},"定":{"docs":{},"义":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"中":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"方":{"docs":{},"法":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}},"了":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"受":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"(":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{},",":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}},"使":{"docs":{},"用":{"docs":{},"查":{"docs":{},"找":{"docs":{},"到":{"docs":{},"的":{"docs":{},"信":{"docs":{},"息":{"docs":{},"创":{"docs":{},"建":{"docs":{},"模":{"docs":{},"型":{"docs":{},",":{"docs":{},"并":{"docs":{},"使":{"docs":{},"之":{"docs":{},"与":{"docs":{},"一":{"docs":{},"个":{"docs":{},"视":{"docs":{},"图":{"docs":{},"绑":{"docs":{},"定":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}},"接":{"docs":{},"收":{"docs":{},"请":{"docs":{},"求":{"docs":{},",":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"查":{"docs":{},"找":{"docs":{},"所":{"docs":{},"需":{"docs":{},"资":{"docs":{},"料":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}},",":{"docs":{},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}},"而":{"docs":{},"要":{"docs":{},"改":{"docs":{},"为":{"docs":{},"指":{"docs":{},"向":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}},"里":{"docs":{},"对":{"docs":{},"这":{"docs":{},"两":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}},"提":{"docs":{},"示":{"docs":{},"你":{"docs":{},"安":{"docs":{},"装":{"docs":{},"缺":{"docs":{},"失":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},",":{"docs":{},"点":{"docs":{},"击":{"docs":{},"“":{"docs":{},"是":{"docs":{},"”":{"docs":{},"以":{"docs":{},"添":{"docs":{},"加":{"docs":{},"它":{"docs":{},"们":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}},"认":{"docs":{},"证":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":10.007518796992482}}}},":":{"docs":{},"f":{"1":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}},"docs":{}}}},"交":{"docs":{},"该":{"docs":{},"表":{"docs":{},"单":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"供":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"上":{"docs":{},"佳":{"docs":{},"的":{"docs":{},"替":{"docs":{},"代":{"docs":{},"品":{"docs":{},":":{"docs":{},"t":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}},"文":{"docs":{},"件":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.002824858757062147}},"夹":{"docs":{},"(":{"docs":{},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},")":{"docs":{},",":{"docs":{},"不":{"docs":{},"是":{"docs":{},"内":{"docs":{},"层":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}},")":{"docs":{},"。":{"docs":{},"你":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}},"内":{"docs":{},"执":{"docs":{},"行":{"docs":{},",":{"docs":{},"该":{"docs":{},"文":{"docs":{},"件":{"docs":{},"夹":{"docs":{},"是":{"docs":{},"上":{"docs":{},"一":{"docs":{},"步":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}},"里":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"用":{"docs":{},"以":{"docs":{},"忽":{"docs":{},"略":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"里":{"docs":{},"包":{"docs":{},"含":{"docs":{},"着":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"为":{"docs":{},"你":{"docs":{},"设":{"docs":{},"置":{"docs":{},"好":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}},",":{"docs":{},"就":{"docs":{},"保":{"docs":{},"存":{"docs":{},"着":{"docs":{},"一":{"docs":{},"个":{"docs":{},"很":{"docs":{},"基":{"docs":{},"本":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"设":{"docs":{},"置":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}},"的":{"docs":{},"底":{"docs":{},"部":{"docs":{},"添":{"docs":{},"加":{"docs":{},"以":{"docs":{},"下":{"docs":{},"这":{"docs":{},"些":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}},")":{"docs":{},"并":{"docs":{},"未":{"docs":{},"复":{"docs":{},"制":{"docs":{},"到":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"里":{"docs":{},"。":{"docs":{},"你":{"docs":{},"稍":{"docs":{},"后":{"docs":{},"即":{"docs":{},"可":{"docs":{},"弄":{"docs":{},"清":{"docs":{},"个":{"docs":{},"中":{"docs":{},"缘":{"docs":{},"由":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"档":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"(":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"s":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},")":{"docs":{},"和":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}},"位":{"docs":{},"于":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"和":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},",":{"docs":{},"并":{"docs":{},"在":{"docs":{},"端":{"docs":{},"口":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"这":{"docs":{},"也":{"docs":{},"是":{"docs":{},"个":{"docs":{},"可":{"docs":{},"行":{"docs":{},"的":{"docs":{},"方":{"docs":{},"案":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}},"所":{"docs":{},"具":{"docs":{},"有":{"docs":{},"的":{"docs":{},"其":{"docs":{},"它":{"docs":{},"特":{"docs":{},"性":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}},"接":{"docs":{},"收":{"docs":{},"从":{"docs":{},"互":{"docs":{},"联":{"docs":{},"网":{"docs":{},"上":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},",":{"docs":{},"并":{"docs":{},"派":{"docs":{},"发":{"docs":{},"到":{"docs":{},"你":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}},"(":{"docs":{},"这":{"docs":{},"包":{"docs":{},"括":{"docs":{},"亚":{"docs":{},"马":{"docs":{},"逊":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}},"层":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}},"。":{"docs":{},"表":{"docs":{},"示":{"docs":{},"层":{"docs":{},"已":{"docs":{},"经":{"docs":{},"有":{"docs":{},"了":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},",":{"docs":{},"接":{"docs":{},"下":{"docs":{},"来":{"docs":{},"就":{"docs":{},"应":{"docs":{},"该":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},",":{"docs":{},"用":{"docs":{},"来":{"docs":{},"处":{"docs":{},"理":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"容":{"docs":{},"器":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},",":{"docs":{},"为":{"docs":{},"此":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"搜":{"docs":{},"索":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"来":{"docs":{},"初":{"docs":{},"始":{"docs":{},"化":{"docs":{},"你":{"docs":{},"的":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}},"实":{"docs":{},"现":{"docs":{},",":{"docs":{},"它":{"docs":{},"会":{"docs":{},"根":{"docs":{},"据":{"docs":{},"操":{"docs":{},"作":{"docs":{},"成":{"docs":{},"功":{"docs":{},"与":{"docs":{},"否":{"docs":{},",":{"docs":{},"返":{"docs":{},"回":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}},"配":{"docs":{},"置":{"docs":{},"内":{"docs":{},"存":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"做":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"潜":{"docs":{},"在":{"docs":{},"问":{"docs":{},"题":{"docs":{},"的":{"docs":{},"小":{"docs":{},"灯":{"docs":{},"泡":{"docs":{},"提":{"docs":{},"示":{"docs":{},":":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"有":{"docs":{},"红":{"docs":{},"色":{"docs":{},"波":{"docs":{},"浪":{"docs":{},"线":{"docs":{},"(":{"docs":{},"编":{"docs":{},"译":{"docs":{},"错":{"docs":{},"误":{"docs":{},")":{"docs":{},",":{"docs":{},"把":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"的":{"docs":{},"光":{"docs":{},"标":{"docs":{},"放":{"docs":{},"在":{"docs":{},"红":{"docs":{},"线":{"docs":{},"里":{"docs":{},",":{"docs":{},"到":{"docs":{},"左":{"docs":{},"边":{"docs":{},"栏":{"docs":{},"里":{"docs":{},"找":{"docs":{},"那":{"docs":{},"个":{"docs":{},"小":{"docs":{},"灯":{"docs":{},"泡":{"docs":{},"的":{"docs":{},"图":{"docs":{},"标":{"docs":{},",":{"docs":{},"小":{"docs":{},"灯":{"docs":{},"泡":{"docs":{},"的":{"docs":{},"提":{"docs":{},"示":{"docs":{},"信":{"docs":{},"息":{"docs":{},"会":{"docs":{},"给":{"docs":{},"出":{"docs":{},"常":{"docs":{},"见":{"docs":{},"问":{"docs":{},"题":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},"建":{"docs":{},"议":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{},"在":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"户":{"docs":{},"点":{"docs":{},"击":{"docs":{},"一":{"docs":{},"个":{"docs":{},"按":{"docs":{},"钮":{"docs":{},"或":{"docs":{},"者":{"docs":{},"提":{"docs":{},"交":{"docs":{},"一":{"docs":{},"个":{"docs":{},"表":{"docs":{},"单":{"docs":{},",":{"docs":{},"从":{"docs":{},"而":{"docs":{},"发":{"docs":{},"送":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"给":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},",":{"docs":{},"重":{"docs":{},"复":{"docs":{},"整":{"docs":{},"个":{"docs":{},"处":{"docs":{},"理":{"docs":{},"流":{"docs":{},"程":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"管":{"docs":{},"理":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"名":{"docs":{},"和":{"docs":{},"密":{"docs":{},"码":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}},"于":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"这":{"docs":{},"种":{"docs":{},"类":{"docs":{},"型":{"docs":{},"保":{"docs":{},"存":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}},"过":{"docs":{},"滤":{"docs":{},"出":{"docs":{},"所":{"docs":{},"有":{"docs":{},"“":{"docs":{},"未":{"docs":{},"完":{"docs":{},"成":{"docs":{},"”":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}},"来":{"docs":{},"连":{"docs":{},"接":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"地":{"docs":{},"址":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"作":{"docs":{},"为":{"docs":{},"参":{"docs":{},"数":{"docs":{},",":{"docs":{},"还":{"docs":{},"进":{"docs":{},"行":{"docs":{},"了":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}},"一":{"docs":{},"个":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"顶":{"docs":{},"层":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"“":{"docs":{},"根":{"docs":{},"”":{"docs":{},"目":{"docs":{},"录":{"docs":{},"可":{"docs":{},"以":{"docs":{},"容":{"docs":{},"纳":{"docs":{},"一":{"docs":{},"个":{"docs":{},"或":{"docs":{},"多":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"。":{"docs":{},"根":{"docs":{},"目":{"docs":{},"录":{"docs":{},"有":{"docs":{},"时":{"docs":{},"候":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},"弄":{"docs":{},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}},"放":{"docs":{},"着":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},",":{"docs":{},"已":{"docs":{},"经":{"docs":{},"预":{"docs":{},"置":{"docs":{},"了":{"docs":{},"几":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"有":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"默":{"docs":{},"认":{"docs":{},"欢":{"docs":{},"迎":{"docs":{},"页":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}}}},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"与":{"docs":{},"所":{"docs":{},"属":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"同":{"docs":{},"名":{"docs":{},"的":{"docs":{},"子":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"。":{"docs":{},"视":{"docs":{},"图":{"docs":{},"文":{"docs":{},"件":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{},"名":{"docs":{},"就":{"docs":{},"是":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"下":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},"新":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},":":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}},"使":{"docs":{},"用":{"docs":{},"以":{"docs":{},"下":{"docs":{},"命":{"docs":{},"令":{"docs":{},"搭":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}},"找":{"docs":{},"到":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},")":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"前":{"docs":{},"的":{"docs":{},"重":{"docs":{},"点":{"docs":{},"就":{"docs":{},"是":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}},"示":{"docs":{},"例":{"docs":{},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},"目":{"docs":{},"录":{"docs":{},"里":{"docs":{},",":{"docs":{},"请":{"docs":{},"退":{"docs":{},"回":{"docs":{},"到":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}},"管":{"docs":{},"理":{"docs":{},"你":{"docs":{},"的":{"docs":{},"源":{"docs":{},"码":{"docs":{},",":{"docs":{},"眼":{"docs":{},"下":{"docs":{},"就":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"适":{"docs":{},"合":{"docs":{},"的":{"docs":{},"时":{"docs":{},"机":{"docs":{},",":{"docs":{},"在":{"docs":{},"项":{"docs":{},"目":{"docs":{},"目":{"docs":{},"录":{"docs":{},"下":{"docs":{},"用":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734},"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}},"在":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"里":{"docs":{},"渲":{"docs":{},"染":{"docs":{},"并":{"docs":{},"呈":{"docs":{},"现":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}},"。":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"模":{"docs":{},"型":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"(":{"docs":{},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"和":{"docs":{},"前":{"docs":{},"端":{"docs":{},"代":{"docs":{},"码":{"docs":{},"就":{"docs":{},"这":{"docs":{},"样":{"docs":{},"搞":{"docs":{},"定":{"docs":{},"了":{"docs":{},"。":{"docs":{},"是":{"docs":{},"时":{"docs":{},"候":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},",":{"docs":{},"为":{"docs":{},"每":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"显":{"docs":{},"示":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}},"请":{"docs":{},"确":{"docs":{},"保":{"docs":{},"你":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}},"求":{"docs":{},"中":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"到":{"docs":{},"你":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"数":{"docs":{},"据":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"到":{"docs":{},"模":{"docs":{},"型":{"docs":{},"后":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"在":{"docs":{},"每":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"下":{"docs":{},"面":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"提":{"docs":{},"交":{"docs":{},"按":{"docs":{},"钮":{"docs":{},",":{"docs":{},"但":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},"体":{"docs":{},"验":{"docs":{},"太":{"docs":{},"蠢":{"docs":{},"了":{"docs":{},"。":{"docs":{},"理":{"docs":{},"想":{"docs":{},"的":{"docs":{},"方":{"docs":{},"法":{"docs":{},"是":{"docs":{},",":{"docs":{},"点":{"docs":{},"击":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"能":{"docs":{},"够":{"docs":{},"自":{"docs":{},"动":{"docs":{},"地":{"docs":{},"提":{"docs":{},"交":{"docs":{},"该":{"docs":{},"表":{"docs":{},"单":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"些":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"模":{"docs":{},"板":{"docs":{},"直":{"docs":{},"接":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}},"的":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"文":{"docs":{},"件":{"docs":{},"将":{"docs":{},"作":{"docs":{},"为":{"docs":{},"静":{"docs":{},"态":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"自":{"docs":{},"动":{"docs":{},"被":{"docs":{},"打":{"docs":{},"包":{"docs":{},"和":{"docs":{},"压":{"docs":{},"缩":{"docs":{},"。":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}}}}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"图":{"docs":{},"形":{"docs":{},"界":{"docs":{},"面":{"docs":{},")":{"docs":{},"安":{"docs":{},"装":{"docs":{},"它":{"docs":{},"们":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"等":{"docs":{},"效":{"docs":{},"查":{"docs":{},"询":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}},"所":{"docs":{},"有":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}},",":{"docs":{},"选":{"docs":{},"择":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}}},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}},"你":{"docs":{},"同":{"docs":{},"样":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"部":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}},"可":{"docs":{},"以":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}},"或":{"docs":{},"者":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"将":{"docs":{},"如":{"docs":{},"鱼":{"docs":{},"得":{"docs":{},"水":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"是":{"docs":{},"初":{"docs":{},"次":{"docs":{},"跟":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}},"省":{"docs":{},"略":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"有":{"docs":{},"需":{"docs":{},"要":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"自":{"docs":{},"定":{"docs":{},"义":{"docs":{},"这":{"docs":{},"些":{"docs":{},"行":{"docs":{},"为":{"docs":{},",":{"docs":{},"不":{"docs":{},"过":{"docs":{},"就":{"docs":{},"目":{"docs":{},"前":{"docs":{},"的":{"docs":{},"情":{"docs":{},"况":{"docs":{},",":{"docs":{},"让":{"docs":{},"我":{"docs":{},"们":{"docs":{},"暂":{"docs":{},"且":{"docs":{},"遵":{"docs":{},"循":{"docs":{},"这":{"docs":{},"些":{"docs":{},"惯":{"docs":{},"例":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"用":{"docs":{},"的":{"docs":{},"模":{"docs":{},"型":{"docs":{},"(":{"docs":{},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"型":{"docs":{},")":{"docs":{},"非":{"docs":{},"常":{"docs":{},"相":{"docs":{},"似":{"docs":{},",":{"docs":{},"但":{"docs":{},"又":{"docs":{},"不":{"docs":{},"尽":{"docs":{},"相":{"docs":{},"同":{"docs":{},"。":{"docs":{},"在":{"docs":{},"现":{"docs":{},"在":{"docs":{},"的":{"docs":{},"情":{"docs":{},"形":{"docs":{},"下":{"docs":{},",":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"看":{"docs":{},"起":{"docs":{},"来":{"docs":{},"是":{"docs":{},"什":{"docs":{},"么":{"docs":{},"样":{"docs":{},"的":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"你":{"docs":{},"无":{"docs":{},"须":{"docs":{},"在":{"docs":{},"代":{"docs":{},"码":{"docs":{},"层":{"docs":{},"面":{"docs":{},"担":{"docs":{},"心":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"层":{"docs":{},"面":{"docs":{},"的":{"docs":{},"东":{"docs":{},"西":{"docs":{},"。":{"docs":{},"这":{"docs":{},"种":{"docs":{},"模":{"docs":{},"型":{"docs":{},"简":{"docs":{},"单":{"docs":{},"的":{"docs":{},"风":{"docs":{},"格":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{},"“":{"docs":{},"朴":{"docs":{},"实":{"docs":{},"可":{"docs":{},"爱":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"一":{"docs":{},"些":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"则":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}},"个":{"docs":{},"占":{"docs":{},"位":{"docs":{},"符":{"docs":{},",":{"docs":{},"代":{"docs":{},"表":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"面":{"docs":{},"装":{"docs":{},"着":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"添":{"docs":{},"加":{"docs":{},"实":{"docs":{},"现":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"实":{"docs":{},"现":{"docs":{},"方":{"docs":{},"法":{"docs":{},"。":{"docs":{},"在":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}},"应":{"docs":{},"付":{"docs":{},"过":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}},"查":{"docs":{},"找":{"docs":{},"并":{"docs":{},"自":{"docs":{},"动":{"docs":{},"给":{"docs":{},"出":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"当":{"docs":{},"前":{"docs":{},"用":{"docs":{},"户":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"它":{"docs":{},"在":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"定":{"docs":{},"义":{"docs":{},"的":{"docs":{},"接":{"docs":{},"口":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"那":{"docs":{},"样":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"包":{"docs":{},"含":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"提":{"docs":{},"交":{"docs":{},"它":{"docs":{},"们":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"运":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},":":{"docs":{"chapters/your-first-application/create-aspnetcore-project.html":{"ref":"chapters/your-first-application/create-aspnetcore-project.html","tf":0.0014124293785310734}}},"“":{"docs":{},"h":{"docs":{},"e":{"docs":{},"l":{"docs":{},"l":{"docs":{},"o":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}},"回":{"docs":{},"调":{"docs":{},"地":{"docs":{},"狱":{"docs":{},"”":{"docs":{},",":{"docs":{},"那":{"docs":{},"你":{"docs":{},"现":{"docs":{},"在":{"docs":{},"走":{"docs":{},"运":{"docs":{},"了":{"docs":{},"。":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}},"截":{"docs":{},"止":{"docs":{},"日":{"docs":{},"期":{"docs":{},"”":{"docs":{},"一":{"docs":{},"栏":{"docs":{},"所":{"docs":{},"展":{"docs":{},"示":{"docs":{},"的":{"docs":{},"日":{"docs":{},"期":{"docs":{},",":{"docs":{},"这":{"docs":{},"种":{"docs":{},"格":{"docs":{},"式":{"docs":{},"(":{"docs":{},"叫":{"docs":{},"做":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"m":{"docs":{},"a":{"docs":{},"z":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"中":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"的":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878},"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677},"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.010309278350515464},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"逻":{"docs":{},"辑":{"docs":{},",":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"类":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"几":{"docs":{},"个":{"docs":{},"惯":{"docs":{},"例":{"docs":{},"(":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"模":{"docs":{},"式":{"docs":{},")":{"docs":{},",":{"docs":{},"比":{"docs":{},"如":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}},"效":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"用":{"docs":{},"过":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},",":{"docs":{},"这":{"docs":{},"就":{"docs":{},"是":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}},"并":{"docs":{},"仅":{"docs":{},"具":{"docs":{},"有":{"docs":{},"特":{"docs":{},"定":{"docs":{},"的":{"docs":{},"字":{"docs":{},"段":{"docs":{},"(":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},")":{"docs":{},",":{"docs":{},"用":{"docs":{},"于":{"docs":{},"添":{"docs":{},"加":{"docs":{},"新":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"。":{"docs":{},"模":{"docs":{},"型":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"流":{"docs":{},"程":{"docs":{},"依":{"docs":{},"然":{"docs":{},"要":{"docs":{},"用":{"docs":{},"到":{"docs":{},",":{"docs":{},"但":{"docs":{},"现":{"docs":{},"在":{"docs":{},",":{"docs":{},"你":{"docs":{},"分":{"docs":{},"离":{"docs":{},"了":{"docs":{},"两":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"用":{"docs":{},"于":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},"存":{"docs":{},"储":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{},"用":{"docs":{},"于":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"传":{"docs":{},"入":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"案":{"docs":{},",":{"docs":{},"也":{"docs":{},"被":{"docs":{},"称":{"docs":{},"作":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"所":{"docs":{},"有":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"具":{"docs":{},"体":{"docs":{},"的":{"docs":{},"实":{"docs":{},"现":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"受":{"docs":{},"益":{"docs":{},",":{"docs":{},"而":{"docs":{},"且":{"docs":{},"已":{"docs":{},"经":{"docs":{},"正":{"docs":{},"常":{"docs":{},"工":{"docs":{},"作":{"docs":{},"了":{"docs":{},",":{"docs":{},"请":{"docs":{},"试":{"docs":{},"着":{"docs":{},"注":{"docs":{},"册":{"docs":{},"一":{"docs":{},"个":{"docs":{},"账":{"docs":{},"号":{"docs":{},"并":{"docs":{},"用":{"docs":{},"它":{"docs":{},"登":{"docs":{},"录":{"docs":{},"。":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"注":{"docs":{},"入":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"获":{"docs":{},"取":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},"和":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}},"之":{"docs":{},"后":{"docs":{},"的":{"docs":{},"命":{"docs":{},"令":{"docs":{},"都":{"docs":{},"会":{"docs":{},"在":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}},"定":{"docs":{},"义":{"docs":{},"的":{"docs":{},"那":{"docs":{},"些":{"docs":{},"程":{"docs":{},"序":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}},"听":{"docs":{},"起":{"docs":{},"来":{"docs":{},"心":{"docs":{},"动":{"docs":{},"吗":{"docs":{},"?":{"docs":{},"那":{"docs":{},"就":{"docs":{},"整":{"docs":{},"起":{"docs":{},"来":{"docs":{},"吧":{"docs":{},"!":{"docs":{},"你":{"docs":{},"要":{"docs":{},"是":{"docs":{},"还":{"docs":{},"没":{"docs":{},"按":{"docs":{},"上":{"docs":{},"一":{"docs":{},"章":{"docs":{},"所":{"docs":{},"讲":{"docs":{},",":{"docs":{},"用":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"基":{"docs":{},"础":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":5.003048780487805}}},"于":{"docs":{},"云":{"docs":{},"的":{"docs":{},"身":{"docs":{},"份":{"docs":{},"鉴":{"docs":{},"别":{"docs":{},"服":{"docs":{},"务":{"docs":{},":":{"docs":{},"这":{"docs":{},"种":{"docs":{},"服":{"docs":{},"务":{"docs":{},"既":{"docs":{},"处":{"docs":{},"理":{"docs":{},"简":{"docs":{},"单":{"docs":{},"情":{"docs":{},"况":{"docs":{},"也":{"docs":{},"处":{"docs":{},"理":{"docs":{},"复":{"docs":{},"杂":{"docs":{},"情":{"docs":{},"况":{"docs":{},"(":{"docs":{},"多":{"docs":{},"步":{"docs":{},"验":{"docs":{},"证":{"docs":{},"、":{"docs":{},"账":{"docs":{},"号":{"docs":{},"找":{"docs":{},"回":{"docs":{},",":{"docs":{},")":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"能":{"docs":{},"极":{"docs":{},"大":{"docs":{},"地":{"docs":{},"缩":{"docs":{},"减":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"编":{"docs":{},"写":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"量":{"docs":{},",":{"docs":{},"和":{"docs":{},"维":{"docs":{},"护":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"量":{"docs":{},"。":{"docs":{},"另":{"docs":{},"外":{"docs":{},",":{"docs":{},"用":{"docs":{},"户":{"docs":{},"数":{"docs":{},"据":{"docs":{},"的":{"docs":{},"敏":{"docs":{},"感":{"docs":{},"部":{"docs":{},"分":{"docs":{},"并":{"docs":{},"不":{"docs":{},"会":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"外":{"docs":{},"加":{"docs":{},"某":{"docs":{},"种":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},"就":{"docs":{},"是":{"docs":{},"常":{"docs":{},"见":{"docs":{},"的":{"docs":{},"范":{"docs":{},"例":{"docs":{},")":{"docs":{},"以":{"docs":{},"及":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}},"广":{"docs":{},"为":{"docs":{},"人":{"docs":{},"知":{"docs":{},"的":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}},"像":{"docs":{},"一":{"docs":{},"个":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"的":{"docs":{},"大":{"docs":{},"型":{"docs":{},"接":{"docs":{},"口":{"docs":{},"。":{"docs":{},"你":{"docs":{},"的":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}},"让":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"被":{"docs":{},"用":{"docs":{},"于":{"docs":{},"查":{"docs":{},"找":{"docs":{},"用":{"docs":{},"户":{"docs":{},"详":{"docs":{},"细":{"docs":{},"信":{"docs":{},"息":{"docs":{},",":{"docs":{},"并":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}},"正":{"docs":{},"如":{"docs":{},"其":{"docs":{},"名":{"docs":{},"字":{"docs":{},"所":{"docs":{},"示":{"docs":{},",":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}},"你":{"docs":{},"可":{"docs":{},"能":{"docs":{},"已":{"docs":{},"经":{"docs":{},"猜":{"docs":{},"到":{"docs":{},"的":{"docs":{},"那":{"docs":{},"样":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"系":{"docs":{},"统":{"docs":{},"。":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}},"内":{"docs":{},"部":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"的":{"docs":{},"(":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"试":{"docs":{},"试":{"docs":{},",":{"docs":{},"把":{"docs":{},"这":{"docs":{},"行":{"docs":{},"代":{"docs":{},"码":{"docs":{},"注":{"docs":{},"释":{"docs":{},"掉":{"docs":{},")":{"docs":{},"。":{"docs":{},"你":{"docs":{},"在":{"docs":{},"应":{"docs":{},"用":{"docs":{},"里":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"任":{"docs":{},"何":{"docs":{},"其":{"docs":{},"它":{"docs":{},"服":{"docs":{},"务":{"docs":{},",":{"docs":{},"也":{"docs":{},"都":{"docs":{},"要":{"docs":{},"在":{"docs":{},"这":{"docs":{},"个":{"docs":{},"地":{"docs":{},"方":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"练":{"docs":{},"习":{"docs":{},"内":{"docs":{},"容":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}},"里":{"docs":{},"的":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}},"让":{"docs":{},"用":{"docs":{},"户":{"docs":{},"通":{"docs":{},"过":{"docs":{},"她":{"docs":{},"们":{"docs":{},"的":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"进":{"docs":{},"行":{"docs":{},"交":{"docs":{},"互":{"docs":{},"的":{"docs":{},"网":{"docs":{},"页":{"docs":{},"和":{"docs":{},"界":{"docs":{},"面":{"docs":{},"(":{"docs":{},"也":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{},"“":{"docs":{},"前":{"docs":{},"端":{"docs":{},"”":{"docs":{},")":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{},"、":{"docs":{},"c":{"docs":{},"s":{"docs":{},"s":{"docs":{},"、":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"项":{"docs":{},"目":{"docs":{},"使":{"docs":{},"用":{"docs":{},"了":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}},"我":{"docs":{},"们":{"docs":{},"仔":{"docs":{},"细":{"docs":{},"探":{"docs":{},"究":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}},"逐":{"docs":{},"行":{"docs":{},"分":{"docs":{},"析":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}},"通":{"docs":{},"读":{"docs":{},"本":{"docs":{},"书":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"构":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"清":{"docs":{},"单":{"docs":{},"应":{"docs":{},"用":{"docs":{},",":{"docs":{},"允":{"docs":{},"许":{"docs":{},"用":{"docs":{},"户":{"docs":{},"添":{"docs":{},"加":{"docs":{},"待":{"docs":{},"办":{"docs":{},"项":{"docs":{},",":{"docs":{},"并":{"docs":{},"在":{"docs":{},"事":{"docs":{},"项":{"docs":{},"完":{"docs":{},"成":{"docs":{},"之":{"docs":{},"后":{"docs":{},"勾":{"docs":{},"掉":{"docs":{},"它":{"docs":{},"。":{"docs":{},"具":{"docs":{},"体":{"docs":{},"来":{"docs":{},"说":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"是":{"docs":{},":":{"docs":{"chapters/mvc-basics/":{"ref":"chapters/mvc-basics/","tf":0.003048780487804878}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"常":{"docs":{},",":{"docs":{},"你":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"的":{"docs":{},"模":{"docs":{},"型":{"docs":{},"(":{"docs":{},"实":{"docs":{},"体":{"docs":{},")":{"docs":{},",":{"docs":{},"跟":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}},"会":{"docs":{},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{},"下":{"docs":{},"列":{"docs":{},"环":{"docs":{},"境":{"docs":{},"之":{"docs":{},"一":{"docs":{},":":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}},"过":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}},"社":{"docs":{},"交":{"docs":{},"媒":{"docs":{},"体":{"docs":{},"授":{"docs":{},"权":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}},"/":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}},"/":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.03125},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.019230769230769232},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.017543859649122806},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.014545454545454545},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0069084628670120895},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.007761966364812419}}},"f":{"docs":{},"o":{"docs":{},"o":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}},",":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},"/":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.011627906976744186},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0035046728971962616}},",":{"docs":{},"后":{"docs":{},"者":{"docs":{},"会":{"docs":{},"刷":{"docs":{},"新":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"并":{"docs":{},"向":{"docs":{},"用":{"docs":{},"户":{"docs":{},"显":{"docs":{},"示":{"docs":{},"新":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}},"并":{"docs":{},"刷":{"docs":{},"新":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.002770083102493075}},"。":{"docs":{},"眼":{"docs":{},"下":{"docs":{},"这":{"docs":{},"不":{"docs":{},"会":{"docs":{},"有":{"docs":{},"效":{"docs":{},"果":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"还":{"docs":{},"没":{"docs":{},"有":{"docs":{},"任":{"docs":{},"何":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"你":{"docs":{},"会":{"docs":{},"被":{"docs":{},"自":{"docs":{},"动":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{},"登":{"docs":{},"录":{"docs":{},"页":{"docs":{},"面":{"docs":{},":":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}},",":{"docs":{},"并":{"docs":{},"验":{"docs":{},"证":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"被":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{},"了":{"docs":{},"登":{"docs":{},"录":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{},"e":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}},"/":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.005097706032285472}},"/":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},".":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}}}}}}}}}}}}}}},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"/":{"docs":{},"n":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{},"/":{"docs":{},"n":{"docs":{},"g":{"docs":{},"i":{"docs":{},"n":{"docs":{},"x":{"docs":{},".":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}}}}}}}}}}}}}}}}},"p":{"docs":{},":":{"docs":{},"p":{"docs":{},"u":{"docs":{},"b":{"docs":{},"l":{"docs":{},"i":{"docs":{},"s":{"docs":{},"h":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"h":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"a":{"docs":{},"r":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"f":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},"=":{"docs":{},"\"":{"docs":{},"f":{"docs":{},"a":{"docs":{},"l":{"docs":{},"s":{"docs":{},"e":{"docs":{},"\"":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.0125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.02631578947368421},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976},"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.015037593984962405},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00517464424320828}}},"分":{"docs":{},"别":{"docs":{},"映":{"docs":{},"射":{"docs":{},"到":{"docs":{},"如":{"docs":{},"下":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}},"包":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"含":{"docs":{},"三":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}},"在":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"被":{"docs":{},"安":{"docs":{},"装":{"docs":{},"在":{"docs":{},"任":{"docs":{},"何":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},"(":{"docs":{},"并":{"docs":{},"且":{"docs":{},"包":{"docs":{},"括":{"docs":{},"在":{"docs":{},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{},"模":{"docs":{},"板":{"docs":{},"中":{"docs":{},"了":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}},"被":{"docs":{},"安":{"docs":{},"装":{"docs":{},"在":{"docs":{},"任":{"docs":{},"意":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"里":{"docs":{},"带":{"docs":{},"来":{"docs":{},"的":{"docs":{},",":{"docs":{},"它":{"docs":{},"把":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},"方":{"docs":{},"法":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"在":{"docs":{},"添":{"docs":{},"加":{"docs":{},"其":{"docs":{},"它":{"docs":{},"代":{"docs":{},"码":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"把":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},"条":{"docs":{},"目":{"docs":{},"置":{"docs":{},"于":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}},"程":{"docs":{},"序":{"docs":{},"以":{"docs":{},"这":{"docs":{},"种":{"docs":{},"方":{"docs":{},"式":{"docs":{},"分":{"docs":{},"割":{"docs":{},",":{"docs":{},"有":{"docs":{},"时":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}},"文":{"docs":{},"件":{"docs":{},"推":{"docs":{},"送":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},"下":{"docs":{},"面":{"docs":{},"这":{"docs":{},"行":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"u":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"中":{"docs":{},"的":{"docs":{},"任":{"docs":{},"意":{"docs":{},"位":{"docs":{},"置":{"docs":{},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"代":{"docs":{},"码":{"docs":{},"暂":{"docs":{},"停":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}},"你":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"服":{"docs":{},"务":{"docs":{},"作":{"docs":{},"为":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"翻":{"docs":{},"译":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{},"类":{"docs":{},"似":{"docs":{},"的":{"docs":{},"语":{"docs":{},"句":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}},"接":{"docs":{},"到":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"转":{"docs":{},"发":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"方":{"docs":{},"法":{"docs":{},"可":{"docs":{},"以":{"docs":{},"返":{"docs":{},"回":{"docs":{},"视":{"docs":{},"图":{"docs":{},"、":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}},"(":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{},"e":{"docs":{},"x":{"docs":{},",":{"docs":{},"a":{"docs":{},"b":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{},",":{"docs":{},"和":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}},"各":{"docs":{},"一":{"docs":{},"个":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"。":{"docs":{},"换":{"docs":{},"句":{"docs":{},"话":{"docs":{},"说":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"可":{"docs":{},"能":{"docs":{},"不":{"docs":{},"会":{"docs":{},"即":{"docs":{},"时":{"docs":{},"返":{"docs":{},"回":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"的":{"docs":{},"列":{"docs":{},"表":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"它":{"docs":{},"需":{"docs":{},"要":{"docs":{},"先":{"docs":{},"查":{"docs":{},"询":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{},"(":{"docs":{},"详":{"docs":{},"情":{"docs":{},"见":{"docs":{},"后":{"docs":{},"续":{"docs":{},"章":{"docs":{},"节":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"完":{"docs":{},"整":{"docs":{},"的":{"docs":{},"抹":{"docs":{},"掉":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"并":{"docs":{},"重":{"docs":{},"新":{"docs":{},"开":{"docs":{},"始":{"docs":{},",":{"docs":{},"运":{"docs":{},"行":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}},"首":{"docs":{},"先":{"docs":{},",":{"docs":{},"该":{"docs":{},"方":{"docs":{},"法":{"docs":{},"接":{"docs":{},"受":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}},"的":{"docs":{},"定":{"docs":{},"义":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"叫":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}},"签":{"docs":{},"名":{"docs":{},",":{"docs":{},"以":{"docs":{},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},"。":{"docs":{},"首":{"docs":{},"先":{"docs":{},",":{"docs":{},"它":{"docs":{},"用":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"中":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}},"顶":{"docs":{},"部":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"新":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"这":{"docs":{},"行":{"docs":{},"代":{"docs":{},"码":{"docs":{},"用":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}},"签":{"docs":{},"名":{"docs":{},"(":{"docs":{},"m":{"docs":{},"e":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"d":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}},"负":{"docs":{},"责":{"docs":{},"的":{"docs":{},"是":{"docs":{},"把":{"docs":{},"东":{"docs":{},"西":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"该":{"docs":{},"服":{"docs":{},"务":{"docs":{},"(":{"docs":{},"具":{"docs":{},"体":{"docs":{},"方":{"docs":{},"法":{"docs":{},",":{"docs":{},"稍":{"docs":{},"后":{"docs":{},"便":{"docs":{},"知":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}},",":{"docs":{},"在":{"docs":{},"当":{"docs":{},"前":{"docs":{},"情":{"docs":{},"况":{"docs":{},"里":{"docs":{},",":{"docs":{},"应":{"docs":{},"该":{"docs":{},"这":{"docs":{},"么":{"docs":{},"写":{"docs":{},":":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}},"(":{"docs":{},"通":{"docs":{},"过":{"docs":{},"你":{"docs":{},"声":{"docs":{},"明":{"docs":{},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},"私":{"docs":{},"有":{"docs":{},"变":{"docs":{},"量":{"docs":{},")":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}},"构":{"docs":{},"造":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"注":{"docs":{},"释":{"docs":{},"掉":{"docs":{},"或":{"docs":{},"删":{"docs":{},"除":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0036363636363636364}}}}}}}},"被":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"里":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"在":{"docs":{},"这":{"docs":{},"里":{"docs":{},"可":{"docs":{},"以":{"docs":{},"直":{"docs":{},"接":{"docs":{},"使":{"docs":{},"用":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}},"配":{"docs":{},"置":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}},"中":{"docs":{},"为":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}},"的":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}},"使":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"刚":{"docs":{},"好":{"docs":{},"相":{"docs":{},"反":{"docs":{},":":{"docs":{},"当":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"撤":{"docs":{},"销":{"docs":{},"(":{"docs":{},"回":{"docs":{},"滚":{"docs":{},")":{"docs":{},"变":{"docs":{},"更":{"docs":{},"时":{"docs":{},",":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}},"将":{"docs":{},"会":{"docs":{},"被":{"docs":{},"执":{"docs":{},"行":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{},"你":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}},"吩":{"docs":{},"咐":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"来":{"docs":{},"自":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"会":{"docs":{},"返":{"docs":{},"回":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"要":{"docs":{},"么":{"docs":{},"返":{"docs":{},"回":{"docs":{},"该":{"docs":{},"条":{"docs":{},"目":{"docs":{},"(":{"docs":{},"若":{"docs":{},"存":{"docs":{},"在":{"docs":{},")":{"docs":{},",":{"docs":{},"要":{"docs":{},"么":{"docs":{},"返":{"docs":{},"回":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"和":{"docs":{},"其":{"docs":{},"中":{"docs":{},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"查":{"docs":{},"找":{"docs":{},"该":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"详":{"docs":{},"细":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}},"强":{"docs":{},"制":{"docs":{},"用":{"docs":{},"户":{"docs":{},"再":{"docs":{},"次":{"docs":{},"登":{"docs":{},"录":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"以":{"docs":{},"确":{"docs":{},"保":{"docs":{},"它":{"docs":{},"在":{"docs":{},"应":{"docs":{},"用":{"docs":{},"程":{"docs":{},"序":{"docs":{},"启":{"docs":{},"动":{"docs":{},"前":{"docs":{},"完":{"docs":{},"成":{"docs":{},"。":{"docs":{},"你":{"docs":{},"一":{"docs":{},"般":{"docs":{},"是":{"docs":{},"用":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"取":{"docs":{},"出":{"docs":{},"存":{"docs":{},"储":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"断":{"docs":{},"言":{"docs":{},"其":{"docs":{},"中":{"docs":{},"的":{"docs":{},"属":{"docs":{},"性":{"docs":{},"被":{"docs":{},"设":{"docs":{},"置":{"docs":{},"了":{"docs":{},"预":{"docs":{},"期":{"docs":{},"的":{"docs":{},"值":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"并":{"docs":{},"遗":{"docs":{},"漏":{"docs":{},"了":{"docs":{},"某":{"docs":{},"些":{"docs":{},"以":{"docs":{},"上":{"docs":{},"的":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"。":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"行":{"docs":{},"为":{"docs":{},",":{"docs":{},"会":{"docs":{},"在":{"docs":{},"你":{"docs":{},"意":{"docs":{},"识":{"docs":{},"不":{"docs":{},"到":{"docs":{},"的":{"docs":{},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},"变":{"docs":{},"掉":{"docs":{},"!":{"docs":{},"你":{"docs":{},"有":{"docs":{},"办":{"docs":{},"法":{"docs":{},"避":{"docs":{},"免":{"docs":{},"这":{"docs":{},"个":{"docs":{},"情":{"docs":{},"况":{"docs":{},",":{"docs":{},"方":{"docs":{},"法":{"docs":{},"是":{"docs":{},"编":{"docs":{},"写":{"docs":{},"一":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"用":{"docs":{},"以":{"docs":{},"复":{"docs":{},"核":{"docs":{},"这":{"docs":{},"些":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"并":{"docs":{},"未":{"docs":{},"发":{"docs":{},"生":{"docs":{},"变":{"docs":{},"化":{"docs":{},"(":{"docs":{},"就":{"docs":{},"算":{"docs":{},"是":{"docs":{},"该":{"docs":{},"方":{"docs":{},"法":{"docs":{},"的":{"docs":{},"内":{"docs":{},"部":{"docs":{},"实":{"docs":{},"现":{"docs":{},"已":{"docs":{},"经":{"docs":{},"发":{"docs":{},"生":{"docs":{},"了":{"docs":{},"变":{"docs":{},"化":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"面":{"docs":{},":":{"docs":{},"管":{"docs":{},"理":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"账":{"docs":{},"号":{"docs":{},"(":{"docs":{},"注":{"docs":{},"册":{"docs":{},"、":{"docs":{},"登":{"docs":{},"录":{"docs":{},")":{"docs":{},",":{"docs":{},"安":{"docs":{},"全":{"docs":{},"地":{"docs":{},"验":{"docs":{},"证":{"docs":{},"用":{"docs":{},"户":{"docs":{},"(":{"docs":{},"登":{"docs":{},"录":{"docs":{},")":{"docs":{},",":{"docs":{},"并":{"docs":{},"在":{"docs":{},"验":{"docs":{},"证":{"docs":{},"后":{"docs":{},"做":{"docs":{},"出":{"docs":{},"授":{"docs":{},"权":{"docs":{},"决":{"docs":{},"策":{"docs":{},"。":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"案":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"想":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"应":{"docs":{},"用":{"docs":{},"上":{"docs":{},"使":{"docs":{},"用":{"docs":{},"自":{"docs":{},"己":{"docs":{},"指":{"docs":{},"定":{"docs":{},"的":{"docs":{},"域":{"docs":{},"名":{"docs":{},",":{"docs":{},"请":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}},"映":{"docs":{},"射":{"docs":{},"到":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}},"(":{"docs":{},"o":{"docs":{},"b":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}},"条":{"docs":{},"目":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":3.3342566943674976}},"就":{"docs":{},"更":{"docs":{},"好":{"docs":{},"了":{"docs":{},"。":{"docs":{},"要":{"docs":{},"达":{"docs":{},"成":{"docs":{},"这":{"docs":{},"个":{"docs":{},"目":{"docs":{},"的":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"去":{"docs":{},"编":{"docs":{},"辑":{"docs":{},"共":{"docs":{},"享":{"docs":{},"的":{"docs":{},"布":{"docs":{},"局":{"docs":{},"文":{"docs":{},"件":{"docs":{},"。":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"注":{"docs":{},"释":{"docs":{},"替":{"docs":{},"换":{"docs":{},"掉":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}},"意":{"docs":{},"一":{"docs":{},"下":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"的":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{},"是":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}},"到":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"渲":{"docs":{},"染":{"docs":{},"视":{"docs":{},"图":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}},"由":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"本":{"docs":{},"身":{"docs":{},"处":{"docs":{},"理":{"docs":{},"的":{"docs":{},"路":{"docs":{},"由":{"docs":{},"叫":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}},"于":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"你":{"docs":{},"删":{"docs":{},"除":{"docs":{},"了":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}},"看":{"docs":{},"到":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{},"暂":{"docs":{},"时":{"docs":{},"不":{"docs":{},"用":{"docs":{},"管":{"docs":{},"这":{"docs":{},"些":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}},"起":{"docs":{},"来":{"docs":{},"是":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},"一":{"docs":{},"下":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}},"给":{"docs":{},"了":{"docs":{},"你":{"docs":{},"足":{"docs":{},"够":{"docs":{},"的":{"docs":{},"灵":{"docs":{},"活":{"docs":{},"性":{"docs":{},",":{"docs":{},"以":{"docs":{},"返":{"docs":{},"回":{"docs":{},"上":{"docs":{},"面":{"docs":{},"提":{"docs":{},"到":{"docs":{},"的":{"docs":{},"任":{"docs":{},"意":{"docs":{},"一":{"docs":{},"个":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}}}},"待":{"docs":{},"办":{"docs":{},"清":{"docs":{},"单":{"docs":{},"功":{"docs":{},"能":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},",":{"docs":{},"取":{"docs":{},"名":{"docs":{},"叫":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}},"继":{"docs":{},"续":{"docs":{},"编":{"docs":{},"码":{"docs":{},"这":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}},",":{"docs":{},"在":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"类":{"docs":{},"里":{"docs":{},"用":{"docs":{},"方":{"docs":{},"法":{"docs":{},"表":{"docs":{},"示":{"docs":{},"。":{"docs":{},"比":{"docs":{},"如":{"docs":{},",":{"docs":{},"h":{"docs":{},"o":{"docs":{},"m":{"docs":{},"e":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125}}}}}}}}}}}}}}}}}}}}}}}}}}}},"并":{"docs":{},"添":{"docs":{},"加":{"docs":{},"如":{"docs":{},"下":{"docs":{},"代":{"docs":{},"码":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-controller.html":{"ref":"chapters/mvc-basics/create-controller.html","tf":0.003125},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"这":{"docs":{},"是":{"docs":{},"个":{"docs":{},"简":{"docs":{},"写":{"docs":{},",":{"docs":{},"表":{"docs":{},"示":{"docs":{},"该":{"docs":{},"属":{"docs":{},"性":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}},"应":{"docs":{},"用":{"docs":{},"变":{"docs":{},"更":{"docs":{},"时":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}},"只":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}},"?":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406}},",":{"docs":{},"每":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"都":{"docs":{},"必":{"docs":{},"须":{"docs":{},"带":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"截":{"docs":{},"止":{"docs":{},"日":{"docs":{},"期":{"docs":{},"。":{"docs":{},"i":{"docs":{},"d":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}},"[":{"docs":{},"r":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"i":{"docs":{},"r":{"docs":{},"e":{"docs":{},"d":{"docs":{},"]":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}}}}}}}}},"v":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"a":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"g":{"docs":{},"e":{"docs":{},"r":{"docs":{},"y":{"docs":{},"t":{"docs":{},"o":{"docs":{},"k":{"docs":{},"e":{"docs":{},"n":{"docs":{},"]":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}}}}}}}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"]":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.03759398496240601},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.004975124378109453},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.0038809831824062097}},",":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}},"(":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}},"f":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"]":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0051813471502590676},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"f":{"docs":{},"i":{"docs":{},"g":{"docs":{},"]":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}}}}}}}}},"\"":{"docs":{},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"\"":{"docs":{},",":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}},"w":{"docs":{},"e":{"docs":{},"l":{"docs":{},"k":{"docs":{},"i":{"docs":{},"e":{"docs":{},"]":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}},"z":{"docs":{},"h":{"docs":{},"i":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"h":{"docs":{},"]":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}}}},"偏":{"docs":{},"移":{"docs":{},"量":{"docs":{},"表":{"docs":{},"示":{"docs":{},"的":{"docs":{},"时":{"docs":{},"区":{"docs":{},"。":{"docs":{},"把":{"docs":{},"时":{"docs":{},"期":{"docs":{},"、":{"docs":{},"时":{"docs":{},"间":{"docs":{},"和":{"docs":{},"时":{"docs":{},"区":{"docs":{},"一":{"docs":{},"起":{"docs":{},"保":{"docs":{},"存":{"docs":{},",":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"在":{"docs":{},"不":{"docs":{},"同":{"docs":{},"时":{"docs":{},"区":{"docs":{},"的":{"docs":{},"系":{"docs":{},"统":{"docs":{},"上":{"docs":{},"准":{"docs":{},"确":{"docs":{},"地":{"docs":{},"显":{"docs":{},"示":{"docs":{},"时":{"docs":{},"间":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"全":{"docs":{},"局":{"docs":{},"(":{"docs":{},"g":{"docs":{},"l":{"docs":{},"o":{"docs":{},"b":{"docs":{},"a":{"docs":{},"l":{"docs":{},"l":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}},"向":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"用":{"docs":{},"户":{"docs":{},"展":{"docs":{},"示":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"的":{"docs":{},"视":{"docs":{},"图":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{},"添":{"docs":{},"加":{"docs":{},"表":{"docs":{},"单":{"docs":{},"元":{"docs":{},"素":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}},"唯":{"docs":{},"一":{"docs":{},"(":{"docs":{},"u":{"docs":{},"n":{"docs":{},"i":{"docs":{},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},")":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}},"因":{"docs":{},"此":{"docs":{},",":{"docs":{},"视":{"docs":{},"图":{"docs":{},"模":{"docs":{},"型":{"docs":{},"应":{"docs":{},"该":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"独":{"docs":{},"立":{"docs":{},"的":{"docs":{},"类":{"docs":{},",":{"docs":{},"里":{"docs":{},"面":{"docs":{},"包":{"docs":{},"含":{"docs":{},"着":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}},"为":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"这":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"(":{"docs":{},"在":{"docs":{},"命":{"docs":{},"名":{"docs":{},"空":{"docs":{},"间":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{},"c":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"s":{"docs":{},"中":{"docs":{},")":{"docs":{},"引":{"docs":{},"用":{"docs":{},"了":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"接":{"docs":{},"口":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"不":{"docs":{},"包":{"docs":{},"含":{"docs":{},"任":{"docs":{},"何":{"docs":{},"实":{"docs":{},"现":{"docs":{},"相":{"docs":{},"关":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},",":{"docs":{},"只":{"docs":{},"有":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"使":{"docs":{},"用":{"docs":{},"了":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},"返":{"docs":{},"回":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"结":{"docs":{},"构":{"docs":{},"里":{"docs":{},"存":{"docs":{},"在":{"docs":{},"多":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"(":{"docs":{},"w":{"docs":{},"e":{"docs":{},"b":{"docs":{},"项":{"docs":{},"目":{"docs":{},"和":{"docs":{},"两":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},")":{"docs":{},",":{"docs":{},"a":{"docs":{},"z":{"docs":{},"u":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},"可":{"docs":{},"以":{"docs":{},"没":{"docs":{},"有":{"docs":{},"值":{"docs":{},",":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"是":{"docs":{},"空":{"docs":{},"白":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},"或":{"docs":{},"者":{"docs":{},"包":{"docs":{},"含":{"docs":{},"任":{"docs":{},"意":{"docs":{},"文":{"docs":{},"本":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}},"段":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"上":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"服":{"docs":{},"务":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"的":{"docs":{},"对":{"docs":{},"象":{"docs":{},",":{"docs":{},"返":{"docs":{},"回":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"确":{"docs":{},"保":{"docs":{},"用":{"docs":{},"户":{"docs":{},"必":{"docs":{},"须":{"docs":{},"已":{"docs":{},"经":{"docs":{},"登":{"docs":{},"录":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}},"对":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"象":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}},"(":{"docs":{},"p":{"docs":{},"l":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}},"。":{"docs":{},"经":{"docs":{},"由":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"当":{"docs":{},"前":{"docs":{},"这":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"而":{"docs":{},"言":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"把":{"docs":{},"程":{"docs":{},"序":{"docs":{},"分":{"docs":{},"为":{"docs":{},"两":{"docs":{},"个":{"docs":{},"层":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{},"由":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"和":{"docs":{},"视":{"docs":{},"图":{"docs":{},"构":{"docs":{},"成":{"docs":{},"的":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"表":{"docs":{},"单":{"docs":{},"也":{"docs":{},"很":{"docs":{},"有":{"docs":{},"用":{"docs":{},"(":{"docs":{},"你":{"docs":{},"会":{"docs":{},"在":{"docs":{},"后":{"docs":{},"续":{"docs":{},"章":{"docs":{},"节":{"docs":{},"明":{"docs":{},"白":{"docs":{},"原":{"docs":{},"委":{"docs":{},")":{"docs":{},"。":{"docs":{},"要":{"docs":{},"学":{"docs":{},"习":{"docs":{},"其":{"docs":{},"它":{"docs":{},"的":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"属":{"docs":{},"性":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}},"是":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"一":{"docs":{},"个":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.005405405405405406}},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},",":{"docs":{},"用":{"docs":{},"于":{"docs":{},"保":{"docs":{},"存":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"的":{"docs":{},"名":{"docs":{},"称":{"docs":{},"或":{"docs":{},"者":{"docs":{},"简":{"docs":{},"述":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}},"没":{"docs":{},"有":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{},"可":{"docs":{},"空":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"是":{"docs":{},"必":{"docs":{},"须":{"docs":{},"的":{"docs":{},",":{"docs":{},"并":{"docs":{},"可":{"docs":{},"以":{"docs":{},"确":{"docs":{},"保":{"docs":{},"始":{"docs":{},"终":{"docs":{},"有":{"docs":{},"值":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"缺":{"docs":{},"省":{"docs":{},"值":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"可":{"docs":{},"空":{"docs":{},"标":{"docs":{},"记":{"docs":{},"。":{"docs":{},"c":{"docs":{},"#":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}},"进":{"docs":{},"行":{"docs":{},"访":{"docs":{},"问":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"。":{"docs":{},"在":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},",":{"docs":{},"会":{"docs":{},"生":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{},"指":{"docs":{},"向":{"docs":{},"路":{"docs":{},"由":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"让":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}},"要":{"docs":{},"求":{"docs":{},"用":{"docs":{},"户":{"docs":{},"在":{"docs":{},"访":{"docs":{},"问":{"docs":{},"指":{"docs":{},"定":{"docs":{},"的":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}},"c":{"docs":{},"u":{"docs":{},"r":{"docs":{},"r":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}},"从":{"docs":{},"而":{"docs":{},"导":{"docs":{},"致":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"视":{"docs":{},"图":{"docs":{},"对":{"docs":{},"所":{"docs":{},"有":{"docs":{},"人":{"docs":{},"可":{"docs":{},"见":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}},"告":{"docs":{},"知":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165}}}},"选":{"docs":{},"择":{"docs":{},"一":{"docs":{},"个":{"docs":{},"(":{"docs":{},"可":{"docs":{},"选":{"docs":{},"的":{"docs":{},")":{"docs":{},"日":{"docs":{},"期":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"用":{"docs":{},"这":{"docs":{},"个":{"docs":{},"日":{"docs":{},"期":{"docs":{},"替":{"docs":{},"换":{"docs":{},"那":{"docs":{},"个":{"docs":{},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{},"“":{"3":{"docs":{},"天":{"docs":{},"后":{"docs":{},"到":{"docs":{},"期":{"docs":{},"”":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"到":{"docs":{},"该":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},",":{"docs":{},"避":{"docs":{},"免":{"docs":{},"它":{"docs":{},"再":{"docs":{},"次":{"docs":{},"被":{"docs":{},"点":{"docs":{},"击":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}},"就":{"docs":{},"是":{"docs":{},"小":{"docs":{},"事":{"docs":{},"一":{"docs":{},"桩":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}},"持":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"轻":{"docs":{},"量":{"docs":{},"级":{"docs":{},"的":{"docs":{},"对":{"docs":{},"象":{"docs":{},",":{"docs":{},"包":{"docs":{},"括":{"docs":{},"了":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"一":{"docs":{},"些":{"docs":{},"(":{"docs":{},"并":{"docs":{},"非":{"docs":{},"全":{"docs":{},"部":{"docs":{},")":{"docs":{},"信":{"docs":{},"息":{"docs":{},"。":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"中":{"docs":{},"获":{"docs":{},"取":{"docs":{},"当":{"docs":{},"前":{"docs":{},"登":{"docs":{},"录":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},"—":{"docs":{},"—":{"docs":{},"该":{"docs":{},"属":{"docs":{},"性":{"docs":{},"在":{"docs":{},"当":{"docs":{},"前":{"docs":{},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}},"确":{"docs":{},"保":{"docs":{},"了":{"docs":{},"见":{"docs":{},"到":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"让":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"里":{"docs":{},"执":{"docs":{},"行":{"docs":{},"认":{"docs":{},"证":{"docs":{},"操":{"docs":{},"作":{"docs":{},"变":{"docs":{},"得":{"docs":{},"很":{"docs":{},"方":{"docs":{},"便":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"里":{"docs":{},"进":{"docs":{},"行":{"docs":{},"认":{"docs":{},"证":{"docs":{},"操":{"docs":{},"作":{"docs":{},"呢":{"docs":{},"?":{"docs":{},"比":{"docs":{},"如":{"docs":{},",":{"docs":{},"在":{"docs":{},"导":{"docs":{},"航":{"docs":{},"条":{"docs":{},"上":{"docs":{},"为":{"docs":{},"登":{"docs":{},"入":{"docs":{},"的":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"用":{"docs":{},"户":{"docs":{},"显":{"docs":{},"示":{"docs":{},"一":{"docs":{},"个":{"docs":{},"“":{"docs":{},"管":{"docs":{},"理":{"docs":{},"用":{"docs":{},"户":{"docs":{},"”":{"docs":{},"的":{"docs":{},"链":{"docs":{},"接":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"里":{"docs":{},"加":{"docs":{},"入":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"应":{"docs":{},"该":{"docs":{},"被":{"docs":{},"设":{"docs":{},"置":{"docs":{},"为":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"标":{"docs":{},"记":{"docs":{},"出":{"docs":{},"来":{"docs":{},")":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"运":{"docs":{},"行":{"docs":{},"它":{"docs":{},"找":{"docs":{},"到":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"类":{"docs":{},"似":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"输":{"docs":{},"出":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"布":{"docs":{},"尔":{"docs":{},"值":{"docs":{},"(":{"docs":{},"值":{"docs":{},"为":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}},"局":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}},"并":{"docs":{},"以":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"处":{"docs":{},"理":{"docs":{},"接":{"docs":{},"收":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},":":{"docs":{},"你":{"docs":{},"的":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"已":{"docs":{},"经":{"docs":{},"处":{"docs":{},"理":{"docs":{},"好":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}},"作":{"docs":{},"为":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},"为":{"docs":{},"其":{"docs":{},"它":{"docs":{},"字":{"docs":{},"段":{"docs":{},"设":{"docs":{},"置":{"docs":{},"缺":{"docs":{},"省":{"docs":{},"值":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"这":{"docs":{},"个":{"docs":{},"新":{"docs":{},"条":{"docs":{},"目":{"docs":{},"被":{"docs":{},"加":{"docs":{},"入":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"中":{"docs":{},"。":{"docs":{},"在":{"docs":{},"调":{"docs":{},"用":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"刷":{"docs":{},"新":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"未":{"docs":{},"关":{"docs":{},"联":{"docs":{},"到":{"docs":{},"特":{"docs":{},"定":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},"。":{"docs":{},"现":{"docs":{},"在":{"docs":{},",":{"docs":{},"[":{"docs":{},"a":{"docs":{},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"]":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}},"且":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}},"在":{"docs":{},"导":{"docs":{},"航":{"docs":{},"条":{"docs":{},"部":{"docs":{},"分":{"docs":{},"添":{"docs":{},"加":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},"把":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"非":{"docs":{},"添":{"docs":{},"加":{"docs":{},"身":{"docs":{},"份":{"docs":{},"鉴":{"docs":{},"别":{"docs":{},"的":{"docs":{},"唯":{"docs":{},"一":{"docs":{},"方":{"docs":{},"式":{"docs":{},"。":{"docs":{},"另":{"docs":{},"外":{"docs":{},"一":{"docs":{},"种":{"docs":{},"选":{"docs":{},"择":{"docs":{},"是":{"docs":{},"使":{"docs":{},"用":{"docs":{},"诸":{"docs":{},"如":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}},"上":{"docs":{},"传":{"docs":{},"你":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"即":{"docs":{},"可":{"docs":{},"。":{"docs":{},"下":{"docs":{},"一":{"docs":{},"节":{"docs":{},",":{"docs":{},"我":{"docs":{},"会":{"docs":{},"介":{"docs":{},"绍":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}},"不":{"docs":{},"具":{"docs":{},"有":{"docs":{},"负":{"docs":{},"载":{"docs":{},"均":{"docs":{},"衡":{"docs":{},"和":{"docs":{},"其":{"docs":{},"它":{"docs":{},"更":{"docs":{},"成":{"docs":{},"熟":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}},"知":{"docs":{},"道":{"docs":{},"该":{"docs":{},"把":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"发":{"docs":{},"布":{"docs":{},"出":{"docs":{},"去":{"docs":{},"。":{"docs":{},"为":{"docs":{},"解":{"docs":{},"决":{"docs":{},"这":{"docs":{},"个":{"docs":{},"问":{"docs":{},"题":{"docs":{},",":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"目":{"docs":{},"录":{"docs":{},"结":{"docs":{},"构":{"docs":{},"顶":{"docs":{},"层":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"浏":{"docs":{},"览":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"按":{"docs":{},"照":{"docs":{},"提":{"docs":{},"示":{"docs":{},"在":{"docs":{},"你":{"docs":{},"的":{"docs":{},"电":{"docs":{},"脑":{"docs":{},"上":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"为":{"docs":{},"这":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"执":{"docs":{},"行":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"些":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}},"监":{"docs":{},"听":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"日":{"docs":{},"期":{"docs":{},"/":{"docs":{},"时":{"docs":{},"间":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}},")":{"docs":{},"将":{"docs":{},"为":{"docs":{},"空":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"包":{"docs":{},"含":{"docs":{},"着":{"docs":{},"一":{"docs":{},"个":{"docs":{},"默":{"docs":{},"认":{"docs":{},"值":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}},"每":{"docs":{},"个":{"docs":{},"属":{"docs":{},"性":{"docs":{},"后":{"docs":{},"面":{"docs":{},"都":{"docs":{},"跟":{"docs":{},"着":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}},"自":{"docs":{},"增":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}},"动":{"docs":{},"化":{"docs":{},"测":{"docs":{},"试":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":10.0125}}}}},"为":{"docs":{},"你":{"docs":{},"生":{"docs":{},"成":{"docs":{},"。":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}},"身":{"docs":{},",":{"docs":{},"在":{"docs":{},"表":{"docs":{},"象":{"docs":{},"之":{"docs":{},"下":{"docs":{},",":{"docs":{},"也":{"docs":{},"只":{"docs":{},"不":{"docs":{},"过":{"docs":{},"是":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"你":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}},"己":{"docs":{},"处":{"docs":{},"理":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},":":{"docs":{},"不":{"docs":{},"推":{"docs":{},"荐":{"docs":{},",":{"docs":{},"除":{"docs":{},"非":{"docs":{},"你":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},"方":{"docs":{},"面":{"docs":{},"的":{"docs":{},"专":{"docs":{},"家":{"docs":{},"!":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"记":{"docs":{},"录":{"docs":{},"(":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},")":{"docs":{},")":{"docs":{},",":{"docs":{},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"将":{"docs":{},"与":{"docs":{},"视":{"docs":{},"图":{"docs":{},"结":{"docs":{},"合":{"docs":{},"(":{"docs":{},"m":{"docs":{},"v":{"docs":{},"c":{"docs":{},"里":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"首":{"docs":{},"先":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/mvc-basics/create-models.html":{"ref":"chapters/mvc-basics/create-models.html","tf":0.0018018018018018018},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"接":{"docs":{},"口":{"docs":{},"定":{"docs":{},"义":{"docs":{},"中":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"修":{"docs":{},"改":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"并":{"docs":{},"用":{"docs":{},"让":{"docs":{},"每":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"都":{"docs":{},"被":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"的":{"docs":{},"就":{"docs":{},"是":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"#":{"8":{"8":{"8":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}},"docs":{}},"docs":{}},"docs":{}},"&":{"docs":{},"#":{"docs":{},"x":{"2":{"7":{"1":{"4":{"docs":{},";":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}},"&":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}},"=":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0169971671388102},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.008241758241758242},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.02857142857142857},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.014545454545454545},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.01444043321299639},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.014773776546629732},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.02102803738317757},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.031840796019900496},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.034108527131782945},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.02936096718480138},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.018111254851228976},"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.003703703703703704}},">":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.01090909090909091},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"=":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.009345794392523364},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.01791044776119403},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}},"@":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},".":{"docs":{},"d":{"docs":{},"u":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}},".":{"docs":{},"h":{"docs":{},"u":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384}}}}}}}}}}}}}}}}}},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735}}}}}}}}}},"f":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},"n":{"docs":{},"j":{"docs":{},"e":{"docs":{},"c":{"docs":{},"t":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}},"m":{"docs":{},"o":{"docs":{},"d":{"docs":{},"e":{"docs":{},"l":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.007228915662650603},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0055248618784530384},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.00554016620498615},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}},"v":{"docs":{},"i":{"docs":{},"e":{"docs":{},"w":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},"[":{"docs":{},"\"":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"l":{"docs":{},"e":{"docs":{},"\"":{"docs":{},"]":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}}}}}},"{":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.004819277108433735},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{},".":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"l":{"docs":{},"i":{"docs":{},"n":{"docs":{},"k":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}},"。":{"docs":{},"t":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.011049723756906077},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"r":{"docs":{},".":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"i":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}},"i":{"docs":{},"d":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}}},"a":{"docs":{},"w":{"docs":{},"a":{"docs":{},"i":{"docs":{},"t":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}}}}}},"元":{"docs":{},"素":{"docs":{},")":{"docs":{},",":{"docs":{},"改":{"docs":{},"行":{"docs":{},"包":{"docs":{},"含":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"名":{"docs":{},"字":{"docs":{},"和":{"docs":{},"截":{"docs":{},"止":{"docs":{},"日":{"docs":{},"期":{"docs":{},"。":{"docs":{},"还":{"docs":{},"会":{"docs":{},"展":{"docs":{},"示":{"docs":{},"一":{"docs":{},"个":{"docs":{},"带":{"docs":{},"有":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}}}}}}}}}}}},"中":{"docs":{},"。":{"docs":{},"这":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},"你":{"docs":{},"不":{"docs":{},"必":{"docs":{},"硬":{"docs":{},"编":{"docs":{},"码":{"docs":{},"这":{"docs":{},"个":{"docs":{},"指":{"docs":{},"向":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}}}}}}}},"的":{"docs":{},"属":{"docs":{},"性":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}},"上":{"docs":{},"那":{"docs":{},"样":{"docs":{},"。":{"docs":{},"在":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}},"是":{"docs":{},"为":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"里":{"docs":{},",":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},",":{"docs":{},"你":{"docs":{},"能":{"docs":{},"预":{"docs":{},"见":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"包":{"docs":{},"含":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"隐":{"docs":{},"藏":{"docs":{},"元":{"docs":{},"素":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}},"定":{"docs":{},"制":{"docs":{},"样":{"docs":{},"式":{"docs":{},"表":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"库":{"docs":{},"。":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}},"样":{"docs":{},"式":{"docs":{},"规":{"docs":{},"则":{"docs":{},":":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}},"绝":{"docs":{},"大":{"docs":{},"多":{"docs":{},"数":{"docs":{},"视":{"docs":{},"图":{"docs":{},"代":{"docs":{},"码":{"docs":{},"就":{"docs":{},"是":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}},"该":{"docs":{},"视":{"docs":{},"图":{"docs":{},"要":{"docs":{},"绑":{"docs":{},"定":{"docs":{},"到":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"模":{"docs":{},"型":{"docs":{},"。":{"docs":{},"模":{"docs":{},"型":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}}}}}}}}}}}}}}}},"方":{"docs":{},"法":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"在":{"docs":{},"把":{"docs":{},"新":{"docs":{},"条":{"docs":{},"目":{"docs":{},"真":{"docs":{},"正":{"docs":{},"存":{"docs":{},"入":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"之":{"docs":{},"前":{"docs":{},",":{"docs":{},"做":{"docs":{},"了":{"docs":{},"多":{"docs":{},"个":{"docs":{},"判":{"docs":{},"断":{"docs":{},"与":{"docs":{},"假":{"docs":{},"设":{"docs":{},"(":{"docs":{},"换":{"docs":{},"句":{"docs":{},"话":{"docs":{},"说":{"docs":{},",":{"docs":{},"在":{"docs":{},"新":{"docs":{},"条":{"docs":{},"目":{"docs":{},"上":{"docs":{},"执":{"docs":{},"行":{"docs":{},"了":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},")":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"页":{"docs":{},"脚":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"首":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"面":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}},",":{"docs":{},"仅":{"docs":{},"对":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"们":{"docs":{},"可":{"docs":{},"见":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"普":{"docs":{},"通":{"docs":{},"用":{"docs":{},"户":{"docs":{},"试":{"docs":{},"图":{"docs":{},"访":{"docs":{},"问":{"docs":{},"它":{"docs":{},",":{"docs":{},"将":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"错":{"docs":{},"误":{"docs":{},"提":{"docs":{},"示":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{"chapters/mvc-basics/create-view.html":{"ref":"chapters/mvc-basics/create-view.html","tf":0.0024096385542168677}}},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}},"'":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"'":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.0028328611898017}}}}}}}}}}},"k":{"docs":{},"e":{"docs":{},"e":{"docs":{},"p":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}}},"↩":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}},"习":{"docs":{},"惯":{"docs":{},"上":{"docs":{},",":{"docs":{},"接":{"docs":{},"口":{"docs":{},"以":{"docs":{},"大":{"docs":{},"写":{"docs":{},"字":{"docs":{},"母":{"docs":{},"“":{"docs":{},"i":{"docs":{},"”":{"docs":{},"开":{"docs":{},"头":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}},"存":{"docs":{},"入":{"docs":{},"和":{"docs":{},"取":{"docs":{},"出":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}},"实":{"docs":{},"现":{"docs":{},"了":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}},"体":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"修":{"docs":{},"改":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},",":{"docs":{},"并":{"docs":{},"对":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"进":{"docs":{},"行":{"docs":{},"变":{"docs":{},"更":{"docs":{},"。":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}},"上":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"属":{"docs":{},"性":{"docs":{},",":{"docs":{},"让":{"docs":{},"每":{"docs":{},"个":{"docs":{},"条":{"docs":{},"目":{"docs":{},"都":{"docs":{},"能":{"docs":{},"够":{"docs":{},"“":{"docs":{},"记":{"docs":{},"住":{"docs":{},"”":{"docs":{},"拥":{"docs":{},"有":{"docs":{},"它":{"docs":{},"的":{"docs":{},"用":{"docs":{},"户":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"模":{"docs":{},"型":{"docs":{},"上":{"docs":{},"所":{"docs":{},"做":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}},"异":{"docs":{},"步":{"docs":{},"的":{"docs":{},"(":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"h":{"docs":{},"r":{"docs":{},"o":{"docs":{},"n":{"docs":{},"o":{"docs":{},"u":{"docs":{},"s":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}},"(":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},")":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085},"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762},"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":3.3361034164358263},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"条":{"docs":{},"目":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"。":{"docs":{},"为":{"docs":{},"了":{"docs":{},"能":{"docs":{},"存":{"docs":{},"储":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},"页":{"docs":{},"面":{"docs":{},"目":{"docs":{},"前":{"docs":{},"还":{"docs":{},"是":{"docs":{},"空":{"docs":{},"白":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}},":":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"。":{"docs":{},"现":{"docs":{},"在":{"docs":{},"你":{"docs":{},"有":{"docs":{},"了":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},",":{"docs":{},"就":{"docs":{},"可":{"docs":{},"以":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"类":{"docs":{},",":{"docs":{},"从":{"docs":{},"而":{"docs":{},"借":{"docs":{},"助":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"列":{"docs":{},"表":{"docs":{},"。":{"docs":{},"糟":{"docs":{},"糕":{"docs":{},"的":{"docs":{},"是":{"docs":{},",":{"docs":{},"你":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"添":{"docs":{},"加":{"docs":{},"的":{"docs":{},"任":{"docs":{},"何":{"docs":{},"条":{"docs":{},"目":{"docs":{},"也":{"docs":{},"都":{"docs":{},"会":{"docs":{},"凭":{"docs":{},"空":{"docs":{},"消":{"docs":{},"失":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"你":{"docs":{},"还":{"docs":{},"没":{"docs":{},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"依":{"docs":{},"然":{"docs":{},"由":{"docs":{},"所":{"docs":{},"有":{"docs":{},"用":{"docs":{},"户":{"docs":{},"共":{"docs":{},"享":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"执":{"docs":{},"行":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"跟":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"目":{"docs":{},"标":{"docs":{},"和":{"docs":{},"“":{"docs":{},"业":{"docs":{},"务":{"docs":{},"”":{"docs":{},"相":{"docs":{},"关":{"docs":{},"联":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"与":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"。":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"列":{"docs":{},"表":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},",":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},"“":{"docs":{},"为":{"docs":{},"新":{"docs":{},"任":{"docs":{},"务":{"docs":{},"设":{"docs":{},"置":{"docs":{},"一":{"docs":{},"个":{"docs":{},"默":{"docs":{},"认":{"docs":{},"的":{"docs":{},"截":{"docs":{},"止":{"docs":{},"时":{"docs":{},"间":{"docs":{},"”":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"“":{"docs":{},"仅":{"docs":{},"显":{"docs":{},"示":{"docs":{},"未":{"docs":{},"完":{"docs":{},"成":{"docs":{},"的":{"docs":{},"任":{"docs":{},"务":{"docs":{},"”":{"docs":{},"这":{"docs":{},"些":{"docs":{},"决":{"docs":{},"策":{"docs":{},"。":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"的":{"docs":{},"其":{"docs":{},"它":{"docs":{},"例":{"docs":{},"子":{"docs":{},",":{"docs":{},"包":{"docs":{},"括":{"docs":{},"“":{"docs":{},"基":{"docs":{},"于":{"docs":{},"产":{"docs":{},"品":{"docs":{},"价":{"docs":{},"格":{"docs":{},"和":{"docs":{},"税":{"docs":{},"率":{"docs":{},"计":{"docs":{},"算":{"docs":{},"总":{"docs":{},"价":{"docs":{},"”":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{},"“":{"docs":{},"在":{"docs":{},"游":{"docs":{},"戏":{"docs":{},"里":{"docs":{},"检":{"docs":{},"查":{"docs":{},"一":{"docs":{},"个":{"docs":{},"玩":{"docs":{},"家":{"docs":{},"是":{"docs":{},"否":{"docs":{},"有":{"docs":{},"足":{"docs":{},"够":{"docs":{},"的":{"docs":{},"经":{"docs":{},"验":{"docs":{},"值":{"docs":{},"升":{"docs":{},"级":{"docs":{},"”":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"架":{"docs":{},"构":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{},"表":{"docs":{},"示":{"docs":{},"层":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"服":{"docs":{},"务":{"docs":{},"层":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"数":{"docs":{},"据":{"docs":{},"仓":{"docs":{},"储":{"docs":{},"层":{"docs":{},"。":{"docs":{},"仓":{"docs":{},"储":{"docs":{},"(":{"docs":{},"r":{"docs":{},"e":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{},"i":{"docs":{},"t":{"docs":{},"o":{"docs":{},"r":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":3.3351800554016617},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}},"服":{"docs":{},"务":{"docs":{},"类":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":10.001416430594901}},"去":{"docs":{},"跟":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"日":{"docs":{},"期":{"docs":{},"选":{"docs":{},"择":{"docs":{},"框":{"docs":{},",":{"docs":{},"并":{"docs":{},"让":{"docs":{},"用":{"docs":{},"户":{"docs":{},"为":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}},"表":{"docs":{},"单":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"进":{"docs":{},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"。":{"docs":{},"这":{"docs":{},"意":{"docs":{},"味":{"docs":{},"着":{"docs":{},",":{"docs":{},"只":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"f":{"docs":{},"a":{"docs":{},"k":{"docs":{},"e":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{},"e":{"docs":{},"的":{"docs":{},"实":{"docs":{},"例":{"docs":{},"被":{"docs":{},"创":{"docs":{},"建":{"docs":{},",":{"docs":{},"并":{"docs":{},"在":{"docs":{},"每":{"docs":{},"次":{"docs":{},"被":{"docs":{},"请":{"docs":{},"求":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},"都":{"docs":{},"被":{"docs":{},"复":{"docs":{},"用":{"docs":{},"。":{"docs":{},"在":{"docs":{},"后":{"docs":{},"面":{"docs":{},",":{"docs":{},"当":{"docs":{},"你":{"docs":{},"写":{"docs":{},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},"去":{"docs":{},"跟":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},"时":{"docs":{},",":{"docs":{},"你":{"docs":{},"会":{"docs":{},"采":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},"(":{"docs":{},"叫":{"docs":{},"做":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"不":{"docs":{},"要":{"docs":{},"指":{"docs":{},"向":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}}}},"到":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}},"服":{"docs":{},"务":{"docs":{},"容":{"docs":{},"器":{"docs":{},"里":{"docs":{},",":{"docs":{},"并":{"docs":{},"通":{"docs":{},"过":{"docs":{},"配":{"docs":{},"置":{"docs":{},"(":{"docs":{},"a":{"docs":{},"p":{"docs":{},"p":{"docs":{},"s":{"docs":{},"e":{"docs":{},"t":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"s":{"docs":{},".":{"docs":{},"j":{"docs":{},"s":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{},"中":{"docs":{},"的":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},"标":{"docs":{},"记":{"docs":{},"。":{"docs":{},"在":{"docs":{},"处":{"docs":{},"理":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}},"外":{"docs":{},"来":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":10.002762430939226}}}}}}},"新":{"docs":{},"特":{"docs":{},"性":{"docs":{"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":10.03125},"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"服":{"docs":{},"务":{"docs":{},"方":{"docs":{},"法":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"(":{"docs":{},"函":{"docs":{},"数":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"这":{"docs":{},"个":{"docs":{},"功":{"docs":{},"能":{"docs":{},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"几":{"docs":{},"个":{"docs":{},"步":{"docs":{},"骤":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}},"一":{"docs":{},"功":{"docs":{},"能":{"docs":{},"。":{"docs":{},"在":{"docs":{},"本":{"docs":{},"例":{"docs":{},"中":{"docs":{},",":{"docs":{},"你":{"docs":{},"还":{"docs":{},"要":{"docs":{},"写":{"docs":{},"一":{"docs":{},"丁":{"docs":{},"点":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"认":{"docs":{},"证":{"docs":{},"提":{"docs":{},"示":{"docs":{},",":{"docs":{},"在":{"docs":{},"这":{"docs":{},"个":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"的":{"docs":{},"第":{"docs":{},"一":{"docs":{},"行":{"docs":{},"上":{"docs":{},"面":{"docs":{},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"个":{"docs":{},"属":{"docs":{},"性":{"docs":{},":":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}}}}}}}}}}},"条":{"docs":{},"目":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}},"用":{"docs":{},"户":{"docs":{},"管":{"docs":{},"理":{"docs":{},"页":{"docs":{},"面":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}},"章":{"docs":{},"节":{"docs":{},"中":{"docs":{},")":{"docs":{},"所":{"docs":{},"见":{"docs":{},"。":{"docs":{},"你":{"docs":{},"将":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"接":{"docs":{},"口":{"docs":{},"来":{"docs":{},"表":{"docs":{},"示":{"docs":{},"一":{"docs":{},"个":{"docs":{},"服":{"docs":{},"务":{"docs":{},",":{"docs":{},"该":{"docs":{},"服":{"docs":{},"务":{"docs":{},"负":{"docs":{},"责":{"docs":{},"就":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"事":{"docs":{},"宜":{"docs":{},"与":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},"。":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"那":{"docs":{},"个":{"docs":{},",":{"docs":{},"用":{"docs":{},"于":{"docs":{},"存":{"docs":{},"储":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}},",":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"所":{"docs":{},"见":{"docs":{},"到":{"docs":{},"的":{"docs":{},"那":{"docs":{},"样":{"docs":{},",":{"docs":{},"只":{"docs":{},"是":{"docs":{},"这":{"docs":{},"次":{"docs":{},"被":{"docs":{},"注":{"docs":{},"入":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"是":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}},"表":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}},"示":{"docs":{},"层":{"docs":{},",":{"docs":{},"用":{"docs":{},"来":{"docs":{},"处":{"docs":{},"理":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"交":{"docs":{},"互":{"docs":{},",":{"docs":{},"和":{"docs":{},"一":{"docs":{},"个":{"docs":{},"包":{"docs":{},"含":{"docs":{},"了":{"docs":{},"业":{"docs":{},"务":{"docs":{},"逻":{"docs":{},"辑":{"docs":{},"和":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"代":{"docs":{},"码":{"docs":{},"的":{"docs":{"chapters/mvc-basics/add-service-class.html":{"ref":"chapters/mvc-basics/add-service-class.html","tf":0.00141643059490085}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"将":{"docs":{},"会":{"docs":{},"被":{"docs":{},"丢":{"docs":{},"弃":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}},"(":{"docs":{},"其":{"docs":{},"列":{"docs":{},"与":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}},"单":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}},"新":{"docs":{},"添":{"docs":{},"一":{"docs":{},"个":{"docs":{},"列":{"docs":{},",":{"docs":{},"以":{"docs":{},"反":{"docs":{},"映":{"docs":{},"你":{"docs":{},"在":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}},"_":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"i":{"docs":{},"c":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}},"e":{"docs":{},".":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"i":{"docs":{},"n":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.005494505494505495},"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.009523809523809525}}}}}}}}}}}}}}}}}}}}}}}}}}}},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.003693444136657433}}}}}}}}}}}}}}}}}}}}}}}},"m":{"docs":{},"a":{"docs":{},"r":{"docs":{},"k":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"i":{"docs":{},"d":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.004672897196261682}}}}}}}}}}}}}}}}}}}}},";":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0027472527472527475},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781}}}}}}}}}}}}}}}}}},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"e":{"docs":{},"x":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}},".":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.010830324909747292},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.003980099502487562}},"s":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"(":{"docs":{},"n":{"docs":{},"e":{"docs":{},"w":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}},"s":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0018467220683287165},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}}}}}}}}}}}}}}}}}}}}}},";":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}}}}}}}},"l":{"docs":{},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},".":{"docs":{},"s":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"r":{"docs":{},"e":{"docs":{},"q":{"docs":{},"u":{"docs":{},"e":{"docs":{},"s":{"docs":{},"t":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}}}}}}},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}},"e":{"docs":{},"r":{"docs":{},".":{"docs":{},"g":{"docs":{},"e":{"docs":{},"t":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.007960199004975124}}}}}}}}}}}}}}}}}}}}},"u":{"docs":{},"s":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}},";":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.001990049751243781},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}},"l":{"docs":{},"a":{"docs":{},"y":{"docs":{},"o":{"docs":{},"u":{"docs":{},"t":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},"h":{"docs":{},"t":{"docs":{},"m":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0015503875968992248}}}}}}}}}}}}}}},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"v":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}},".":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"c":{"docs":{},"l":{"docs":{},"i":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}}}}}},"d":{"docs":{},"i":{"docs":{},"s":{"docs":{},"p":{"docs":{},"o":{"docs":{},"s":{"docs":{},"e":{"docs":{},"(":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}}}}},";":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}}}}}}}}},"与":{"docs":{},"之":{"docs":{},"如":{"docs":{},"出":{"docs":{},"一":{"docs":{},"辙":{"docs":{},":":{"docs":{},"承":{"docs":{},"诺":{"docs":{},"你":{"docs":{},",":{"docs":{},"肯":{"docs":{},"定":{"docs":{},"会":{"docs":{},"给":{"docs":{},"出":{"docs":{},"一":{"docs":{},"个":{"docs":{},"结":{"docs":{},"果":{"docs":{},"—":{"docs":{},"—":{"docs":{},"在":{"docs":{},"未":{"docs":{},"来":{"docs":{},"的":{"docs":{},"某":{"docs":{},"个":{"docs":{},"时":{"docs":{},"候":{"docs":{},"。":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"你":{"docs":{},"先":{"docs":{},"前":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"交":{"docs":{},"互":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"写":{"docs":{},"起":{"docs":{},"来":{"docs":{},"坑":{"docs":{},"很":{"docs":{},"多":{"docs":{},"。":{"docs":{},"除":{"docs":{},"非":{"docs":{},"你":{"docs":{},"对":{"docs":{},"其":{"docs":{},"了":{"docs":{},"如":{"docs":{},"指":{"docs":{},"掌":{"docs":{},",":{"docs":{},"否":{"docs":{},"则":{"docs":{},"在":{"docs":{},"程":{"docs":{},"序":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"粘":{"docs":{},"贴":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"建":{"docs":{},"立":{"docs":{},"连":{"docs":{},"接":{"docs":{},"。":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}},"真":{"docs":{},"实":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"进":{"docs":{},"行":{"docs":{},"交":{"docs":{},"互":{"docs":{},"!":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"相":{"docs":{},"比":{"docs":{},",":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"在":{"docs":{},"范":{"docs":{},"围":{"docs":{},"上":{"docs":{},"大":{"docs":{},"得":{"docs":{},"多":{"docs":{},"。":{"docs":{},"它":{"docs":{},"检":{"docs":{},"验":{"docs":{},"整":{"docs":{},"个":{"docs":{},"程":{"docs":{},"序":{"docs":{},"栈":{"docs":{},"。":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"并":{"docs":{},"不":{"docs":{},"会":{"docs":{},"把":{"docs":{},"一":{"docs":{},"个":{"docs":{},"类":{"docs":{},"或":{"docs":{},"组":{"docs":{},"件":{"docs":{},"隔":{"docs":{},"离":{"docs":{},"出":{"docs":{},"来":{"docs":{},",":{"docs":{},"而":{"docs":{},"是":{"docs":{},"确":{"docs":{},"保":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"组":{"docs":{},"件":{"docs":{},"协":{"docs":{},"作":{"docs":{},"良":{"docs":{},"好":{"docs":{},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"组":{"docs":{},"件":{"docs":{},"包":{"docs":{},"括":{"docs":{},":":{"docs":{},"路":{"docs":{},"由":{"docs":{},"、":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"、":{"docs":{},"服":{"docs":{},"务":{"docs":{},"、":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"访":{"docs":{},"问":{"docs":{},"等":{"docs":{},"等":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"较":{"docs":{},"慢":{"docs":{},",":{"docs":{},"并":{"docs":{},"且":{"docs":{},"涵":{"docs":{},"盖":{"docs":{},"的":{"docs":{},"范":{"docs":{},"围":{"docs":{},"较":{"docs":{},"大":{"docs":{},",":{"docs":{},"所":{"docs":{},"以":{"docs":{},",":{"docs":{},"一":{"docs":{},"般":{"docs":{},"来":{"docs":{},"说":{"docs":{},",":{"docs":{},"一":{"docs":{},"个":{"docs":{},"项":{"docs":{},"目":{"docs":{},"会":{"docs":{},"有":{"docs":{},"大":{"docs":{},"量":{"docs":{},"的":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"内":{"docs":{},"容":{"docs":{},",":{"docs":{},"而":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"则":{"docs":{},"屈":{"docs":{},"指":{"docs":{},"可":{"docs":{},"数":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"会":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}},"以":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}},"为":{"docs":{},"该":{"docs":{},"表":{"docs":{},"单":{"docs":{},"生":{"docs":{},"成":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"从":{"docs":{},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"提":{"docs":{},"取":{"docs":{},"信":{"docs":{},"息":{"docs":{},",":{"docs":{},"并":{"docs":{},"存":{"docs":{},"放":{"docs":{},"到":{"docs":{},"那":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}},"处":{"docs":{},"理":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"将":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{},"路":{"docs":{},"由":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}},"自":{"docs":{},"动":{"docs":{},"执":{"docs":{},"行":{"docs":{},"一":{"docs":{},"个":{"docs":{},"称":{"docs":{},"为":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"被":{"docs":{},"你":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"返":{"docs":{},"回":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"连":{"docs":{},"带":{"docs":{},"一":{"docs":{},"个":{"docs":{},"包":{"docs":{},"含":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"尝":{"docs":{},"试":{"docs":{},"将":{"docs":{},"其":{"docs":{},"解":{"docs":{},"析":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}},"依":{"docs":{},"赖":{"docs":{},"于":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}},"被":{"docs":{},"注":{"docs":{},"入":{"docs":{},"的":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"注":{"docs":{},"入":{"docs":{},"(":{"docs":{},"d":{"docs":{},"e":{"docs":{},"p":{"docs":{},"e":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}},"图":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}},"回":{"docs":{},"到":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}},"调":{"docs":{},"函":{"docs":{},"数":{"docs":{},",":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"k":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}},"顾":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"当":{"docs":{},"你":{"docs":{},"编":{"docs":{},"写":{"docs":{},"代":{"docs":{},"码":{"docs":{},"访":{"docs":{},"问":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"或":{"docs":{},"者":{"docs":{},"外":{"docs":{},"部":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}},"再":{"docs":{},"次":{"docs":{},"启":{"docs":{},"动":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"a":{"docs":{},"d":{"docs":{},"m":{"docs":{},"i":{"docs":{},"n":{"docs":{},"@":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},".":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}},"把":{"docs":{},"程":{"docs":{},"序":{"docs":{},"部":{"docs":{},"署":{"docs":{},"到":{"docs":{},"生":{"docs":{},"产":{"docs":{},"环":{"docs":{},"境":{"docs":{},",":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"添":{"docs":{},"加":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}},"某":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"在":{"docs":{},"你":{"docs":{},"刚":{"docs":{},"刚":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"表":{"docs":{},"单":{"docs":{},"里":{"docs":{},"点":{"docs":{},"击":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}},"视":{"docs":{},"图":{"docs":{},"中":{"docs":{},"的":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}},"一":{"docs":{},"个":{"docs":{},"有":{"docs":{},"效":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},"被":{"docs":{},"标":{"docs":{},"记":{"docs":{},"为":{"docs":{},"完":{"docs":{},"成":{"docs":{},"状":{"docs":{},"态":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}},"程":{"docs":{},"序":{"docs":{},"运":{"docs":{},"转":{"docs":{},"正":{"docs":{},"常":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"操":{"docs":{},"作":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}},"上":{"docs":{},",":{"docs":{},"而":{"docs":{},"后":{"docs":{},",":{"docs":{},"在":{"docs":{},"底":{"docs":{},"层":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"或":{"docs":{},"者":{"docs":{},"网":{"docs":{},"络":{"docs":{},"请":{"docs":{},"求":{"docs":{},"结":{"docs":{},"束":{"docs":{},"时":{"docs":{},",":{"docs":{},"从":{"docs":{},"暂":{"docs":{},"停":{"docs":{},"的":{"docs":{},"地":{"docs":{},"方":{"docs":{},"恢":{"docs":{},"复":{"docs":{},"执":{"docs":{},"行":{"docs":{},"。":{"docs":{},"就":{"docs":{},"是":{"docs":{},"说":{"docs":{},",":{"docs":{},"你":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"并":{"docs":{},"没":{"docs":{},"有":{"docs":{},"卡":{"docs":{},"住":{"docs":{},"或":{"docs":{},"者":{"docs":{},"阻":{"docs":{},"塞":{"docs":{},"住":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"它":{"docs":{},"可":{"docs":{},"以":{"docs":{},"处":{"docs":{},"理":{"docs":{},"其":{"docs":{},"它":{"docs":{},"的":{"docs":{},"请":{"docs":{},"求":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"现":{"docs":{},"在":{"docs":{},"想":{"docs":{},"不":{"docs":{},"通":{"docs":{},"也":{"docs":{},"别":{"docs":{},"担":{"docs":{},"心":{"docs":{},",":{"docs":{},"跟":{"docs":{},"着":{"docs":{},"做":{"docs":{},"下":{"docs":{},"去":{"docs":{},"就":{"docs":{},"行":{"docs":{},"!":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"既":{"docs":{},"然":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737},"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}},"你":{"docs":{},"没":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}},"修":{"docs":{},"改":{"docs":{},"了":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"里":{"docs":{},"的":{"docs":{},"实":{"docs":{},"体":{"docs":{},"模":{"docs":{},"型":{"docs":{},",":{"docs":{},"就":{"docs":{},"应":{"docs":{},"该":{"docs":{},"同":{"docs":{},"步":{"docs":{},"修":{"docs":{},"改":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{},"在":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"里":{"docs":{},"用":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"现":{"docs":{},"在":{"docs":{},"把":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},"要":{"docs":{},"使":{"docs":{},"用":{"docs":{},"你":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},"的":{"docs":{},"类":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"引":{"docs":{},"用":{"docs":{},"指":{"docs":{},"向":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"这":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},"项":{"docs":{},"目":{"docs":{},"要":{"docs":{},"用":{"docs":{},"到":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},"中":{"docs":{},"的":{"docs":{},"类":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"引":{"docs":{},"用":{"docs":{},"指":{"docs":{},"向":{"docs":{},"主":{"docs":{},"项":{"docs":{},"目":{"docs":{},":":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"现":{"docs":{},"成":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"时":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}},"考":{"docs":{},"虑":{"docs":{},"到":{"docs":{},"安":{"docs":{},"全":{"docs":{},"性":{"docs":{},"的":{"docs":{},"因":{"docs":{},"素":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}},"特":{"docs":{},"定":{"docs":{},"的":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}},"别":{"docs":{},"致":{"docs":{},"谢":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"胜":{"docs":{},"利":{"docs":{},"在":{"docs":{},"望":{"docs":{},"!":{"docs":{},"你":{"docs":{},"已":{"docs":{},"经":{"docs":{},"让":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}},"被":{"docs":{},"一":{"docs":{},"个":{"docs":{},"构":{"docs":{},"造":{"docs":{},"函":{"docs":{},"数":{"docs":{},"(":{"docs":{},"或":{"docs":{},"其":{"docs":{},"它":{"docs":{},"什":{"docs":{},"么":{"docs":{},"地":{"docs":{},"方":{"docs":{},")":{"docs":{},"被":{"docs":{},"请":{"docs":{},"求":{"docs":{},",":{"docs":{},"就":{"docs":{},"用":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}},"称":{"docs":{},"为":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}},"调":{"docs":{},"用":{"docs":{},"之":{"docs":{},"后":{"docs":{},"才":{"docs":{},"会":{"docs":{},"把":{"docs":{},"修":{"docs":{},"改":{"docs":{},"的":{"docs":{},"内":{"docs":{},"容":{"docs":{},"持":{"docs":{},"久":{"docs":{},"化":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"。":{"docs":{},"s":{"docs":{},"a":{"docs":{},"v":{"docs":{},"e":{"docs":{},"c":{"docs":{},"h":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{},"e":{"docs":{},"s":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"分":{"docs":{},"配":{"docs":{},"了":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"创":{"docs":{},"建":{"docs":{},"时":{"docs":{},",":{"docs":{},"把":{"docs":{},"这":{"docs":{},"些":{"docs":{},"对":{"docs":{},"象":{"docs":{},"逐":{"docs":{},"一":{"docs":{},"地":{"docs":{},"注":{"docs":{},"入":{"docs":{},"到":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"图":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}},"要":{"docs":{},"声":{"docs":{},"明":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"“":{"docs":{},"关":{"docs":{},"联":{"docs":{},"”":{"docs":{},")":{"docs":{},"具":{"docs":{},"体":{"docs":{},"的":{"docs":{},"类":{"docs":{},"到":{"docs":{},"每":{"docs":{},"个":{"docs":{},"接":{"docs":{},"口":{"docs":{},"上":{"docs":{},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"写":{"docs":{},"在":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}}},"在":{"docs":{},"代":{"docs":{},"码":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},",":{"docs":{},"你":{"docs":{},"通":{"docs":{},"常":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"文":{"docs":{},"件":{"docs":{},"顶":{"docs":{},"端":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}},"主":{"docs":{},"布":{"docs":{},"局":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{},"这":{"docs":{},"个":{"docs":{},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"编":{"docs":{},"辑":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}},"把":{"docs":{},"它":{"docs":{},"加":{"docs":{},"入":{"docs":{},"到":{"docs":{},"你":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},",":{"docs":{},"在":{"docs":{},"终":{"docs":{},"端":{"docs":{},"窗":{"docs":{},"口":{"docs":{},"运":{"docs":{},"行":{"docs":{},"这":{"docs":{},"个":{"docs":{},"命":{"docs":{},"令":{"docs":{},":":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}},"编":{"docs":{},"写":{"docs":{},"一":{"docs":{},"个":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"来":{"docs":{},"检":{"docs":{},"验":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"执":{"docs":{},"行":{"docs":{},"一":{"docs":{},"个":{"docs":{},"集":{"docs":{},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"你":{"docs":{},"也":{"docs":{},"可":{"docs":{},"以":{"docs":{},"启":{"docs":{},"动":{"docs":{},"程":{"docs":{},"序":{"docs":{},",":{"docs":{},"并":{"docs":{},"手":{"docs":{},"动":{"docs":{},"向":{"docs":{},"h":{"docs":{},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},":":{"docs":{},"/":{"docs":{},"/":{"docs":{},"l":{"docs":{},"o":{"docs":{},"c":{"docs":{},"a":{"docs":{},"l":{"docs":{},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},":":{"5":{"0":{"0":{"0":{"docs":{},"发":{"docs":{},"起":{"docs":{},"请":{"docs":{},"求":{"docs":{},"。":{"docs":{},"不":{"docs":{},"过":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}},"docs":{}},"docs":{}},"docs":{}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"跟":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}},"依":{"docs":{},"附":{"docs":{},"代":{"docs":{},"码":{"docs":{},"打":{"docs":{},"交":{"docs":{},"道":{"docs":{},"要":{"docs":{},"容":{"docs":{},"易":{"docs":{},"得":{"docs":{},"多":{"docs":{},",":{"docs":{},"这":{"docs":{},"归":{"docs":{},"功":{"docs":{},"于":{"docs":{},"神":{"docs":{},"奇":{"docs":{},"的":{"docs":{},"关":{"docs":{},"键":{"docs":{},"字":{"docs":{"chapters/mvc-basics/use-dependency-injection.html":{"ref":"chapters/mvc-basics/use-dependency-injection.html","tf":0.0013736263736263737}}}}}}}}}}}}}}}}}}}}}}}}}},"。":{"docs":{},"你":{"docs":{},"会":{"docs":{},"看":{"docs":{},"到":{"docs":{},"自":{"docs":{},"己":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"视":{"docs":{},"图":{"docs":{},",":{"docs":{},"展":{"docs":{},"示":{"docs":{},"着":{"docs":{},"(":{"docs":{},"暂":{"docs":{},"时":{"docs":{},")":{"docs":{},"从":{"docs":{},"伪":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"层":{"docs":{},"提":{"docs":{},"取":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"。":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}},"完":{"docs":{},"成":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":10.004761904761905}}}}},"事":{"docs":{},"项":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"这":{"docs":{},"种":{"docs":{},"操":{"docs":{},"作":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"整":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"尽":{"docs":{},"管":{"docs":{},"可":{"docs":{},"以":{"docs":{},"径":{"docs":{},"直":{"docs":{},"浏":{"docs":{},"览":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}},"属":{"docs":{},"性":{"docs":{},"的":{"docs":{},"名":{"docs":{},"字":{"docs":{},"是":{"docs":{},"授":{"docs":{},"权":{"docs":{},"(":{"docs":{},"a":{"docs":{},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},")":{"docs":{},",":{"docs":{},"我":{"docs":{},"们":{"docs":{},"在":{"docs":{},"这":{"docs":{},"里":{"docs":{},"检":{"docs":{},"查":{"docs":{},"的":{"docs":{},"其":{"docs":{},"实":{"docs":{},"是":{"docs":{},"认":{"docs":{},"证":{"docs":{},"(":{"docs":{},"a":{"docs":{},"u":{"docs":{},"t":{"docs":{},"h":{"docs":{},"o":{"docs":{},"r":{"docs":{},"i":{"docs":{},"z":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{},",":{"docs":{},"而":{"docs":{},"非":{"docs":{},"检":{"docs":{},"查":{"docs":{},"授":{"docs":{},"权":{"docs":{},",":{"docs":{},"很":{"docs":{},"抱":{"docs":{},"歉":{"docs":{},"会":{"docs":{},"有":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{},"混":{"docs":{},"淆":{"docs":{},"。":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"按":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}},"惯":{"docs":{},"例":{"docs":{},",":{"docs":{},"通":{"docs":{},"常":{"docs":{},"把":{"docs":{},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"的":{"docs":{},"名":{"docs":{},"字":{"docs":{},"以":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}},"角":{"docs":{},"色":{"docs":{},"进":{"docs":{},"行":{"docs":{},"授":{"docs":{},"权":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":10.00077519379845}}}}}}}},"提":{"docs":{},"示":{"docs":{},"创":{"docs":{},"建":{"docs":{},"密":{"docs":{},"码":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"最":{"docs":{},"后":{"docs":{},"一":{"docs":{},"步":{"docs":{},",":{"docs":{},"让":{"docs":{},"我":{"docs":{},"们":{"docs":{},"来":{"docs":{},"完":{"docs":{},"成":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"的":{"docs":{},"编":{"docs":{},"码":{"docs":{},"。":{"docs":{},"控":{"docs":{},"制":{"docs":{},"器":{"docs":{},"现":{"docs":{},"在":{"docs":{},"已":{"docs":{},"经":{"docs":{},"从":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}}}}}}}}}}}}}}}}}}}}},"行":{"docs":{},"创":{"docs":{},"建":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},",":{"docs":{},"t":{"docs":{},"o":{"docs":{},"a":{"docs":{},"r":{"docs":{},"r":{"docs":{},"a":{"docs":{},"y":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}},"修":{"docs":{},"改":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}},"为":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"开":{"docs":{},"始":{"docs":{},"的":{"docs":{},"地":{"docs":{},"方":{"docs":{},"进":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}},"终":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"操":{"docs":{},"作":{"docs":{},"顺":{"docs":{},"利":{"docs":{},"完":{"docs":{},"成":{"docs":{},",":{"docs":{},"a":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}},"一":{"docs":{},"切":{"docs":{},"顺":{"docs":{},"利":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"器":{"docs":{},"会":{"docs":{},"被":{"docs":{},"重":{"docs":{},"定":{"docs":{},"向":{"docs":{},"到":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}},"测":{"docs":{},"试":{"docs":{},"一":{"docs":{},"下":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}},")":{"docs":{},"较":{"docs":{},"大":{"docs":{},",":{"docs":{},"模":{"docs":{},"拟":{"docs":{},"实":{"docs":{},"际":{"docs":{},"的":{"docs":{},"应":{"docs":{},"用":{"docs":{},"场":{"docs":{},"景":{"docs":{},",":{"docs":{},"并":{"docs":{},"检":{"docs":{},"验":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"里":{"docs":{},"的":{"docs":{},"多":{"docs":{},"个":{"docs":{},"层":{"docs":{},"次":{"docs":{},"或":{"docs":{},"组":{"docs":{},"件":{"docs":{},"。":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"的":{"docs":{},"编":{"docs":{},"写":{"docs":{},"在":{"docs":{},"构":{"docs":{},"建":{"docs":{},"任":{"docs":{},"何":{"docs":{},"程":{"docs":{},"序":{"docs":{},"时":{"docs":{},"都":{"docs":{},"很":{"docs":{},"重":{"docs":{},"要":{"docs":{},"。":{"docs":{},"测":{"docs":{},"试":{"docs":{},"代":{"docs":{},"码":{"docs":{},"有":{"docs":{},"助":{"docs":{},"于":{"docs":{},"发":{"docs":{},"现":{"docs":{},"及":{"docs":{},"避":{"docs":{},"免":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"专":{"docs":{},"用":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"是":{"docs":{},"个":{"docs":{},"宽":{"docs":{},"泛":{"docs":{},"的":{"docs":{},"话":{"docs":{},"题":{"docs":{},",":{"docs":{},"还":{"docs":{},"有":{"docs":{},"很":{"docs":{},"多":{"docs":{},"东":{"docs":{},"西":{"docs":{},"需":{"docs":{},"要":{"docs":{},"学":{"docs":{},"习":{"docs":{},"。":{"docs":{},"本":{"docs":{},"章":{"docs":{},"节":{"docs":{},"没":{"docs":{},"有":{"docs":{},"涉":{"docs":{},"及":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"也":{"docs":{},"没":{"docs":{},"有":{"docs":{},"对":{"docs":{},"前":{"docs":{},"端":{"docs":{},"(":{"docs":{},"j":{"docs":{},"a":{"docs":{},"v":{"docs":{},"a":{"docs":{},"s":{"docs":{},"c":{"docs":{},"r":{"docs":{},"i":{"docs":{},"p":{"docs":{},"t":{"docs":{},")":{"docs":{},"代":{"docs":{},"码":{"docs":{},"进":{"docs":{},"行":{"docs":{},"测":{"docs":{},"试":{"docs":{},"—":{"docs":{},"—":{"docs":{},"它":{"docs":{},"本":{"docs":{},"身":{"docs":{},"可":{"docs":{},"能":{"docs":{},"就":{"docs":{},"需":{"docs":{},"要":{"docs":{},"一":{"docs":{},"整":{"docs":{},"本":{"docs":{},"书":{"docs":{},"去":{"docs":{},"讲":{"docs":{},"述":{"docs":{},"。":{"docs":{},"不":{"docs":{},"过":{"docs":{},",":{"docs":{},"你":{"docs":{},"应":{"docs":{},"该":{"docs":{},"已":{"docs":{},"经":{"docs":{},"掌":{"docs":{},"握":{"docs":{},"了":{"docs":{},"一":{"docs":{},"些":{"docs":{},"基":{"docs":{},"本":{"docs":{},"的":{"docs":{},"技":{"docs":{},"能":{"docs":{},"和":{"docs":{},"知":{"docs":{},"识":{"docs":{},",":{"docs":{},"可":{"docs":{},"用":{"docs":{},"于":{"docs":{},"实":{"docs":{},"践":{"docs":{},"并":{"docs":{},"学":{"docs":{},"习":{"docs":{},"更":{"docs":{},"多":{"docs":{},"相":{"docs":{},"关":{"docs":{},"测":{"docs":{},"试":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"编":{"docs":{},"写":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"端":{"docs":{},"口":{"docs":{},"上":{"docs":{},"运":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}}}}},"吗":{"docs":{},"?":{"docs":{},"这":{"docs":{},"里":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}},"映":{"docs":{},"射":{"docs":{},"到":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"的":{"docs":{},"容":{"docs":{},"器":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},")":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},",":{"docs":{},"把":{"docs":{},"请":{"docs":{},"求":{"docs":{},"转":{"docs":{},"发":{"docs":{},"到":{"docs":{},"另":{"docs":{},"一":{"docs":{},"个":{"docs":{},"运":{"docs":{},"行":{"docs":{},"着":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}},"绑":{"docs":{},"定":{"docs":{},":":{"docs":{"chapters/mvc-basics/finish-controller.html":{"ref":"chapters/mvc-basics/finish-controller.html","tf":0.004761904761904762}}},"模":{"docs":{},"型":{"docs":{},"(":{"docs":{},"b":{"docs":{},"i":{"docs":{},"n":{"docs":{},"d":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}},"位":{"docs":{},"于":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}},"替":{"docs":{},"换":{"docs":{},"成":{"docs":{},"真":{"docs":{},"正":{"docs":{},"的":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}},"链":{"docs":{},"接":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"t":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/mvc-basics/update-the-layout.html":{"ref":"chapters/mvc-basics/update-the-layout.html","tf":0.005813953488372093}}}}}}}}},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}},"几":{"docs":{},"乎":{"docs":{},"任":{"docs":{},"何":{"docs":{},"东":{"docs":{},"西":{"docs":{},":":{"docs":{},"日":{"docs":{},"期":{"docs":{},"、":{"docs":{},"时":{"docs":{},"间":{"docs":{},"、":{"docs":{},"时":{"docs":{},"长":{"docs":{},"、":{"docs":{},"数":{"docs":{},"字":{"docs":{},"等":{"docs":{},"等":{"docs":{},"。":{"docs":{},"它":{"docs":{},"是":{"docs":{},"个":{"docs":{},"很":{"docs":{},"好":{"docs":{},"很":{"docs":{},"有":{"docs":{},"用":{"docs":{},"的":{"docs":{},"开":{"docs":{},"源":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"根":{"docs":{},"据":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"即":{"docs":{},"是":{"docs":{},"包":{"docs":{},"管":{"docs":{},"理":{"docs":{},"工":{"docs":{},"具":{"docs":{},",":{"docs":{},"也":{"docs":{},"是":{"docs":{},"官":{"docs":{},"方":{"docs":{},"的":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"仓":{"docs":{},"库":{"docs":{},"(":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}},"天":{"docs":{},"”":{"docs":{},"这":{"docs":{},"样":{"docs":{},",":{"docs":{},"不":{"docs":{},"是":{"docs":{},"更":{"docs":{},"好":{"docs":{},"吗":{"docs":{},"?":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}},"将":{"docs":{},"用":{"docs":{},"于":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"中":{"docs":{},"改":{"docs":{},"写":{"docs":{},"日":{"docs":{},"期":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"直":{"docs":{},"接":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"里":{"docs":{},"使":{"docs":{},"用":{"docs":{},"它":{"docs":{},"。":{"docs":{},"首":{"docs":{},"先":{"docs":{},"在":{"docs":{},"视":{"docs":{},"图":{"docs":{},"顶":{"docs":{},"端":{"docs":{},"添":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"变":{"docs":{},"更":{"docs":{},"应":{"docs":{},"用":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"时":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}},"幸":{"docs":{},"福":{"docs":{},"地":{"docs":{},"对":{"docs":{},"这":{"docs":{},"个":{"docs":{},"变":{"docs":{},"化":{"docs":{},"毫":{"docs":{},"无":{"docs":{},"察":{"docs":{},"觉":{"docs":{},",":{"docs":{},"但":{"docs":{},"在":{"docs":{},"底":{"docs":{},"层":{"docs":{},",":{"docs":{},"你":{"docs":{},"将":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}},"有":{"docs":{},"能":{"docs":{},"力":{"docs":{},"缓":{"docs":{},"存":{"docs":{},"这":{"docs":{},"些":{"docs":{},"重":{"docs":{},"建":{"docs":{},"的":{"docs":{},"包":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"当":{"docs":{},"你":{"docs":{},"修":{"docs":{},"改":{"docs":{},"代":{"docs":{},"码":{"docs":{},"(":{"docs":{},"而":{"docs":{},"没":{"docs":{},"修":{"docs":{},"改":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"中":{"docs":{},"定":{"docs":{},"义":{"docs":{},"的":{"docs":{},"包":{"docs":{},")":{"docs":{},"时":{"docs":{},",":{"docs":{},"重":{"docs":{},"建":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"改":{"docs":{},"写":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}},"机":{"docs":{},"器":{"docs":{},"学":{"docs":{},"习":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"修":{"docs":{},"改":{"docs":{},"那":{"docs":{},"行":{"docs":{},"写":{"docs":{},"着":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}},"w":{"docs":{},"h":{"docs":{},"e":{"docs":{},"r":{"docs":{},"e":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}},"m":{"docs":{},"a":{"docs":{},"i":{"docs":{},"n":{"docs":{},"(":{"docs":{},")":{"docs":{},"的":{"docs":{},"下":{"docs":{},"面":{"docs":{},"添":{"docs":{},"加":{"docs":{},"这":{"docs":{},"个":{"docs":{},"新":{"docs":{},"方":{"docs":{},"法":{"docs":{},":":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}},"运":{"docs":{},"行":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"(":{"docs":{},"一":{"docs":{},"个":{"docs":{},"叫":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}},"。":{"docs":{},"这":{"docs":{},"样":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"不":{"docs":{},"必":{"docs":{},"在":{"docs":{},"项":{"docs":{},"目":{"docs":{},"文":{"docs":{},"件":{"docs":{},"里":{"docs":{},"添":{"docs":{},"加":{"docs":{},"数":{"docs":{},"百":{"docs":{},"个":{"docs":{},"软":{"docs":{},"件":{"docs":{},"包":{"docs":{},"的":{"docs":{},"引":{"docs":{},"用":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"集":{"docs":{},"合":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}},",":{"docs":{},"以":{"docs":{},"获":{"docs":{},"取":{"docs":{},"协":{"docs":{},"助":{"docs":{},",":{"docs":{},"来":{"docs":{},"完":{"docs":{},"成":{"docs":{},"几":{"docs":{},"乎":{"docs":{},"任":{"docs":{},"何":{"docs":{},"能":{"docs":{},"想":{"docs":{},"到":{"docs":{},"的":{"docs":{},"任":{"docs":{},"务":{"docs":{},"和":{"docs":{},"难":{"docs":{},"题":{"docs":{},"。":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}}}}}},"并":{"docs":{},"在":{"docs":{},"自":{"docs":{},"己":{"docs":{},"的":{"docs":{},"机":{"docs":{},"器":{"docs":{},"上":{"docs":{},"使":{"docs":{},"用":{"docs":{},"终":{"docs":{},"端":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/add-external-packages/":{"ref":"chapters/add-external-packages/","tf":0.0027624309392265192}}}}}}}}}}}}}}}}}}}}},"关":{"docs":{},"系":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}},"心":{"docs":{},"“":{"docs":{},"用":{"docs":{},"户":{"docs":{},"在":{"docs":{},"登":{"docs":{},"录":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}},"的":{"docs":{},"是":{"docs":{},"用":{"docs":{},"户":{"docs":{},"登":{"docs":{},"录":{"docs":{},"与":{"docs":{},"否":{"docs":{},",":{"docs":{},"而":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}},"于":{"docs":{},"作":{"docs":{},"者":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"支":{"docs":{},"持":{"docs":{},"多":{"docs":{},"个":{"docs":{},"不":{"docs":{},"同":{"docs":{},"类":{"docs":{},"型":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"并":{"docs":{},"允":{"docs":{},"许":{"docs":{},"你":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}}}}}}},"查":{"docs":{},"询":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},"就":{"docs":{},"是":{"docs":{},"个":{"docs":{},"糟":{"docs":{},"糕":{"docs":{},"的":{"docs":{},"决":{"docs":{},"定":{"docs":{},"。":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/use-a-database/":{"ref":"chapters/use-a-database/","tf":0.005154639175257732}}}}}}}}}}}}}}}},"子":{"docs":{},"句":{"docs":{},"也":{"docs":{},"需":{"docs":{},"要":{"docs":{},"检":{"docs":{},"查":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}},"了":{"docs":{},":":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}},"找":{"docs":{},"一":{"docs":{},"个":{"docs":{},"条":{"docs":{},"目":{"docs":{},"。":{"docs":{},"s":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},"l":{"docs":{},"e":{"docs":{},"o":{"docs":{},"r":{"docs":{},"d":{"docs":{},"e":{"docs":{},"f":{"docs":{},"a":{"docs":{},"u":{"docs":{},"l":{"docs":{},"t":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"+":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.006993006993006993},"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.011363636363636364},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00258732212160414}}},"借":{"docs":{},"助":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"无":{"docs":{},"论":{"docs":{},"你":{"docs":{},"连":{"docs":{},"接":{"docs":{},"本":{"docs":{},"地":{"docs":{},"文":{"docs":{},"件":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"(":{"docs":{},"s":{"docs":{},"q":{"docs":{},"l":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},")":{"docs":{},"还":{"docs":{},"是":{"docs":{},"位":{"docs":{},"于":{"docs":{},"其":{"docs":{},"它":{"docs":{},"主":{"docs":{},"机":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"都":{"docs":{},"需":{"docs":{},"要":{"docs":{},"定":{"docs":{},"义":{"docs":{},"一":{"docs":{},"个":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{},",":{"docs":{},"其":{"docs":{},"中":{"docs":{},"包":{"docs":{},"含":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"经":{"docs":{},"由":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}},"连":{"docs":{},"接":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.01048951048951049}}}}},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":10.003496503496503}},",":{"docs":{},"需":{"docs":{},"要":{"docs":{},"做":{"docs":{},"一":{"docs":{},"些":{"docs":{},"准":{"docs":{},"备":{"docs":{},"工":{"docs":{},"作":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{},"你":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/use-a-database/connect-to-a-database.html":{"ref":"chapters/use-a-database/connect-to-a-database.html","tf":0.0034965034965034965}}}}}}}}}}}}}}}}}}}}},"到":{"docs":{},"了":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},",":{"docs":{},"就":{"docs":{},"为":{"docs":{},"“":{"docs":{},"给":{"docs":{},"程":{"docs":{},"序":{"docs":{},"添":{"docs":{},"加":{"docs":{},"更":{"docs":{},"多":{"docs":{},"新":{"docs":{},"特":{"docs":{},"性":{"docs":{},"”":{"docs":{},"做":{"docs":{},"好":{"docs":{},"准":{"docs":{},"备":{"docs":{},"了":{"docs":{},"。":{"docs":{},"首":{"docs":{},"先":{"docs":{},"是":{"docs":{},"这":{"docs":{},"个":{"docs":{},"功":{"docs":{},"能":{"docs":{},":":{"docs":{},"使":{"docs":{},"用":{"docs":{},"一":{"docs":{},"个":{"docs":{},"表":{"docs":{},"单":{"docs":{},",":{"docs":{},"添":{"docs":{},"加":{"docs":{},"新":{"docs":{},"的":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"。":{"docs":{"chapters/add-more-features/":{"ref":"chapters/add-more-features/","tf":0.03125}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"变":{"docs":{},"更":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}},"(":{"docs":{},"m":{"docs":{},"i":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}},"按":{"docs":{},"时":{"docs":{},"间":{"docs":{},"记":{"docs":{},"录":{"docs":{},"着":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"结":{"docs":{},"构":{"docs":{},"的":{"docs":{},"变":{"docs":{},"化":{"docs":{},"。":{"docs":{},"它":{"docs":{},"们":{"docs":{},"使":{"docs":{},"以":{"docs":{},"下":{"docs":{},"的":{"docs":{},"操":{"docs":{},"作":{"docs":{},"成":{"docs":{},"为":{"docs":{},"可":{"docs":{},"能":{"docs":{},":":{"docs":{},"撤":{"docs":{},"销":{"docs":{},"(":{"docs":{},"回":{"docs":{},"滚":{"docs":{},")":{"docs":{},"一":{"docs":{},"部":{"docs":{},"分":{"docs":{},"修":{"docs":{},"改":{"docs":{},",":{"docs":{},"或":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"—":{"docs":{},"—":{"docs":{},"与":{"docs":{},"原":{"docs":{},"有":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"结":{"docs":{},"构":{"docs":{},"一":{"docs":{},"致":{"docs":{},"。":{"docs":{},"有":{"docs":{},"了":{"docs":{},"变":{"docs":{},"更":{"docs":{},",":{"docs":{},"你":{"docs":{},"有":{"docs":{},"一":{"docs":{},"个":{"docs":{},"完":{"docs":{},"整":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"历":{"docs":{},"史":{"docs":{},",":{"docs":{},"记":{"docs":{},"录":{"docs":{},"着":{"docs":{},"对":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"修":{"docs":{},"改":{"docs":{},",":{"docs":{},"例":{"docs":{},"如":{"docs":{},"添":{"docs":{},"加":{"docs":{},"或":{"docs":{},"删":{"docs":{},"除":{"docs":{},"字":{"docs":{},"段":{"docs":{},"(":{"docs":{},"以":{"docs":{},"及":{"docs":{},"整":{"docs":{},"个":{"docs":{},"表":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"记":{"docs":{},"录":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"量":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"工":{"docs":{},"具":{"docs":{},"的":{"docs":{},"文":{"docs":{},"档":{"docs":{},",":{"docs":{},"以":{"docs":{},"此":{"docs":{},"对":{"docs":{},"你":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"进":{"docs":{},"行":{"docs":{},"逆":{"docs":{},"向":{"docs":{},"工":{"docs":{},"程":{"docs":{},",":{"docs":{},"自":{"docs":{},"动":{"docs":{},"地":{"docs":{},"为":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"结":{"docs":{},"构":{"docs":{},"生":{"docs":{},"成":{"docs":{},"相":{"docs":{},"应":{"docs":{},"的":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},",":{"docs":{},"原":{"docs":{},"因":{"docs":{},"请":{"docs":{},"参":{"docs":{},"考":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}},"知":{"docs":{},"道":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}}}}}},"晓":{"docs":{},"该":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"集":{"docs":{},"合":{"docs":{},"。":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"名":{"docs":{},"为":{"docs":{"chapters/use-a-database/update-context.html":{"ref":"chapters/use-a-database/update-context.html","tf":0.0043859649122807015}}}}}}}},"既":{"docs":{},"然":{"docs":{},"现":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"上":{"docs":{},"下":{"docs":{},"文":{"docs":{},"里":{"docs":{},"包":{"docs":{},"括":{"docs":{},"了":{"docs":{},"一":{"docs":{},"个":{"docs":{},"集":{"docs":{},"合":{"docs":{},"(":{"docs":{},"或":{"docs":{},"者":{"docs":{},"说":{"docs":{},"表":{"docs":{},")":{"docs":{},",":{"docs":{},"而":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"没":{"docs":{},"有":{"docs":{},"它":{"docs":{},",":{"docs":{},"你":{"docs":{},"就":{"docs":{},"需":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"更":{"docs":{},"来":{"docs":{},"修":{"docs":{},"改":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},":":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"成":{"docs":{},"测":{"docs":{},"试":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":10.001293661060801}}}}}},"带":{"docs":{},"有":{"docs":{},"你":{"docs":{},"创":{"docs":{},"建":{"docs":{},"它":{"docs":{},"时":{"docs":{},"候":{"docs":{},"的":{"docs":{},"时":{"docs":{},"间":{"docs":{},"戳":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}},"来":{"docs":{},"的":{"docs":{},"身":{"docs":{},"份":{"docs":{},"系":{"docs":{},"统":{"docs":{},",":{"docs":{},"就":{"docs":{},"像":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}},"搞":{"docs":{},"定":{"docs":{},"!":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}},"!":{"docs":{},"请":{"docs":{},"用":{"docs":{},"两":{"docs":{},"个":{"docs":{},"不":{"docs":{},"同":{"docs":{},"的":{"docs":{},"账":{"docs":{},"号":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"一":{"docs":{},"下":{"docs":{},"。":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"现":{"docs":{},"在":{"docs":{},"是":{"docs":{},"每":{"docs":{},"个":{"docs":{},"账":{"docs":{},"户":{"docs":{},"的":{"docs":{},"私":{"docs":{},"密":{"docs":{},"信":{"docs":{},"息":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"相":{"docs":{},"匹":{"docs":{},"配":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}},"关":{"docs":{},"信":{"docs":{},"息":{"docs":{},"的":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}},"第":{"docs":{},"一":{"docs":{},"个":{"docs":{},"变":{"docs":{},"更":{"docs":{},"文":{"docs":{},"件":{"docs":{},"(":{"0":{"0":{"docs":{},"_":{"docs":{},"c":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"t":{"docs":{},"e":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},"s":{"docs":{},"c":{"docs":{},"h":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},".":{"docs":{},"c":{"docs":{},"s":{"docs":{},")":{"docs":{},",":{"docs":{},"是":{"docs":{},"在":{"docs":{},"你":{"docs":{},"执":{"docs":{},"行":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"docs":{}},"docs":{}}}}}},"验":{"docs":{},"证":{"docs":{},"步":{"docs":{},"骤":{"docs":{},"是":{"docs":{},"个":{"docs":{},"明":{"docs":{},"智":{"docs":{},"的":{"docs":{},"检":{"docs":{},"查":{"docs":{},":":{"docs":{},"内":{"docs":{},"存":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"保":{"docs":{},"存":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},"绝":{"docs":{},"不":{"docs":{},"会":{"docs":{},"超":{"docs":{},"过":{"docs":{},"一":{"docs":{},"条":{"docs":{},"。":{"docs":{},"假":{"docs":{},"设":{"docs":{},"这":{"docs":{},"个":{"docs":{},"检":{"docs":{},"查":{"docs":{},"通":{"docs":{},"过":{"docs":{},"了":{"docs":{},",":{"docs":{},"测":{"docs":{},"试":{"docs":{},"会":{"docs":{},"使":{"docs":{},"用":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"绕":{"docs":{},"开":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}},"迁":{"docs":{},"移":{"docs":{},"的":{"docs":{},"名":{"docs":{},"称":{"docs":{},":":{"docs":{},"d":{"docs":{},"o":{"docs":{},"t":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/use-a-database/create-migration.html":{"ref":"chapters/use-a-database/create-migration.html","tf":0.0018181818181818182}}}}}}}}}}}}}},"*":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0036101083032490976}}},"删":{"docs":{},"除":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}},"文":{"docs":{},"件":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}},"一":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"自":{"docs":{},"动":{"docs":{},"创":{"docs":{},"建":{"docs":{},"的":{"docs":{},"文":{"docs":{},"件":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}},"取":{"docs":{},"出":{"docs":{},"所":{"docs":{},"有":{"docs":{},"过":{"docs":{},"滤":{"docs":{},"后":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"并":{"docs":{},"作":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"数":{"docs":{},"组":{"docs":{},"返":{"docs":{},"回":{"docs":{},"。":{"docs":{},"t":{"docs":{},"o":{"docs":{},"a":{"docs":{},"r":{"docs":{},"r":{"docs":{},"a":{"docs":{},"y":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"决":{"docs":{},"于":{"docs":{},"该":{"docs":{},"条":{"docs":{},"目":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"的":{"docs":{},"结":{"docs":{},"果":{"docs":{},"成":{"docs":{},"功":{"docs":{},"与":{"docs":{},"否":{"docs":{},",":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"i":{"docs":{},"t":{"docs":{},"e":{"docs":{},"m":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"底":{"docs":{},"层":{"docs":{},"以":{"docs":{},"请":{"docs":{},"求":{"docs":{},"为":{"docs":{},"单":{"docs":{},"位":{"docs":{},"管":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"连":{"docs":{},"接":{"docs":{},"。":{"docs":{},"要":{"docs":{},"避":{"docs":{},"免":{"docs":{},"这":{"docs":{},"些":{"docs":{},"问":{"docs":{},"题":{"docs":{},",":{"docs":{},"请":{"docs":{},"在":{"docs":{},"跟":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488}}}}}}}}}}}}}}}}}}}}}}}}}}}},"试":{"docs":{},"试":{"docs":{},"看":{"docs":{"chapters/use-a-database/create-service-class.html":{"ref":"chapters/use-a-database/create-service-class.html","tf":0.0018050541516245488},"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582},"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"着":{"docs":{},"运":{"docs":{},"行":{"docs":{},"程":{"docs":{},"序":{"docs":{},"并":{"docs":{},"在":{"docs":{},"未":{"docs":{},"登":{"docs":{},"录":{"docs":{},"的":{"docs":{},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},"访":{"docs":{},"问":{"docs":{"chapters/security-and-identity/require-authentication.html":{"ref":"chapters/security-and-identity/require-authentication.html","tf":0.007518796992481203}}}}}}}}}}}}}}}}}}},"主":{"docs":{},"视":{"docs":{},"图":{"docs":{},"里":{"docs":{},"引":{"docs":{},"用":{"docs":{},"它":{"docs":{},":":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}},"机":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"传":{"docs":{},"给":{"docs":{},"它":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}},"再":{"docs":{},"检":{"docs":{},"视":{"docs":{},"一":{"docs":{},"次":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}},"通":{"docs":{},"过":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}},"列":{"docs":{},"表":{"docs":{},"里":{"docs":{},"。":{"docs":{},"因":{"docs":{},"为":{"docs":{},"这":{"docs":{},"些":{"docs":{},"条":{"docs":{},"目":{"docs":{},"存":{"docs":{},"储":{"docs":{},"在":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},",":{"docs":{},"就":{"docs":{},"算":{"docs":{},"你":{"docs":{},"关":{"docs":{},"闭":{"docs":{},"程":{"docs":{},"序":{"docs":{},"后":{"docs":{},"再":{"docs":{},"重":{"docs":{},"新":{"docs":{},"运":{"docs":{},"行":{"docs":{},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"条":{"docs":{},"目":{"docs":{},"都":{"docs":{},"还":{"docs":{},"保":{"docs":{},"存":{"docs":{},"在":{"docs":{},"那":{"docs":{},"里":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"添":{"docs":{},"加":{"docs":{},"条":{"docs":{},"目":{"docs":{},",":{"docs":{},"这":{"docs":{},"功":{"docs":{},"能":{"docs":{},"很":{"docs":{},"棒":{"docs":{},",":{"docs":{},"但":{"docs":{},"无":{"docs":{},"论":{"docs":{},"如":{"docs":{},"何":{"docs":{},",":{"docs":{},"这":{"docs":{},"些":{"docs":{},"事":{"docs":{},"项":{"docs":{},"都":{"docs":{},"得":{"docs":{},"被":{"docs":{},"处":{"docs":{},"理":{"docs":{},"掉":{"docs":{},"。":{"docs":{},"在":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"去":{"docs":{},"查":{"docs":{},"找":{"docs":{},"(":{"docs":{},"并":{"docs":{},"验":{"docs":{},"证":{"docs":{},")":{"docs":{},"那":{"docs":{},"个":{"docs":{},"隐":{"docs":{},"藏":{"docs":{},"的":{"docs":{},"验":{"docs":{},"证":{"docs":{},"标":{"docs":{},"记":{"docs":{},",":{"docs":{},"就":{"docs":{},"是":{"docs":{},"由":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}}}}}}}},"看":{"docs":{},"运":{"docs":{},"行":{"docs":{},"在":{"docs":{},"容":{"docs":{},"器":{"docs":{},"中":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}},"监":{"docs":{},"听":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"就":{"docs":{},"这":{"docs":{},"样":{"docs":{},"创":{"docs":{},"建":{"docs":{},"好":{"docs":{},"了":{"docs":{},"。":{"docs":{},"然":{"docs":{},"后":{"docs":{},",":{"docs":{},"要":{"docs":{},"在":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}}},"(":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}},"攻":{"docs":{},"击":{"docs":{},"。":{"docs":{},"在":{"docs":{},"你":{"docs":{},"编":{"docs":{},"写":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}},"跨":{"docs":{},"站":{"docs":{},"请":{"docs":{},"求":{"docs":{},"伪":{"docs":{},"造":{"docs":{},"(":{"docs":{},"c":{"docs":{},"r":{"docs":{},"o":{"docs":{},"s":{"docs":{},"s":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}},"(":{"docs":{},"c":{"docs":{},"s":{"docs":{},"r":{"docs":{},"f":{"docs":{},")":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}}}}}}}}}}},"错":{"docs":{},"误":{"docs":{},"。":{"docs":{"chapters/add-more-features/add-todo-items.html":{"ref":"chapters/add-more-features/add-todo-items.html","tf":0.0009233610341643582}}}}},"$":{"docs":{},"(":{"docs":{},"'":{"docs":{},".":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"u":{"docs":{},"m":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},")":{"docs":{},".":{"docs":{},"r":{"docs":{},"e":{"docs":{},"a":{"docs":{},"d":{"docs":{},"y":{"docs":{},"(":{"docs":{},"f":{"docs":{},"u":{"docs":{},"n":{"docs":{},"c":{"docs":{},"t":{"docs":{},"i":{"docs":{},"o":{"docs":{},"n":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}}}}}}}}}}}}}},"r":{"docs":{},"o":{"docs":{},"w":{"docs":{},")":{"docs":{},".":{"docs":{},"a":{"docs":{},"d":{"docs":{},"d":{"docs":{},"c":{"docs":{},"l":{"docs":{},"a":{"docs":{},"s":{"docs":{},"s":{"docs":{},"(":{"docs":{},"'":{"docs":{},"d":{"docs":{},"o":{"docs":{},"n":{"docs":{},"e":{"docs":{},"'":{"docs":{},")":{"docs":{},";":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.002336448598130841}}}}}}}}}}}}}}}}}}}}}}}}},"h":{"docs":{},"o":{"docs":{},"s":{"docs":{},"t":{"docs":{},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}}}},"t":{"docs":{},"t":{"docs":{},"p":{"docs":{},"_":{"docs":{},"u":{"docs":{},"p":{"docs":{},"g":{"docs":{},"r":{"docs":{},"a":{"docs":{},"d":{"docs":{},"e":{"docs":{},";":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0033984706881903144}}}}}}}}}}}}}}}},"事":{"docs":{},"件":{"docs":{},"。":{"docs":{},"当":{"docs":{},"一":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"被":{"docs":{},"点":{"docs":{},"击":{"docs":{},",":{"docs":{},"m":{"docs":{},"a":{"docs":{},"r":{"docs":{},"k":{"docs":{},"c":{"docs":{},"o":{"docs":{},"m":{"docs":{},"p":{"docs":{},"l":{"docs":{},"e":{"docs":{},"t":{"docs":{},"e":{"docs":{},"d":{"docs":{},"(":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"函":{"docs":{},"数":{"docs":{},"就":{"docs":{},"被":{"docs":{},"执":{"docs":{},"行":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"的":{"docs":{},"功":{"docs":{},"能":{"docs":{},"如":{"docs":{},"下":{"docs":{},":":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"被":{"docs":{},"选":{"docs":{},"中":{"docs":{},"了":{"docs":{},",":{"docs":{},"而":{"docs":{},"无":{"docs":{},"法":{"docs":{},"知":{"docs":{},"道":{"docs":{},"是":{"docs":{},"哪":{"docs":{},"个":{"docs":{},"。":{"docs":{},")":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}},"制":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"循":{"docs":{},"环":{"docs":{},"运":{"docs":{},"行":{"docs":{},"并":{"docs":{},"为":{"docs":{},"每":{"docs":{},"个":{"docs":{},"待":{"docs":{},"办":{"docs":{},"事":{"docs":{},"项":{"docs":{},"条":{"docs":{},"目":{"docs":{},"显":{"docs":{},"示":{"docs":{},"一":{"docs":{},"行":{"docs":{},",":{"docs":{},"每":{"docs":{},"一":{"docs":{},"行":{"docs":{},"都":{"docs":{},"会":{"docs":{},"包":{"docs":{},"含":{"docs":{},"此":{"docs":{},"表":{"docs":{},"单":{"docs":{},"的":{"docs":{},"一":{"docs":{},"个":{"docs":{},"副":{"docs":{},"本":{"docs":{},"。":{"docs":{},"隐":{"docs":{},"藏":{"docs":{},"的":{"docs":{},"输":{"docs":{},"入":{"docs":{},"框":{"docs":{},"包":{"docs":{},"含":{"docs":{},"该":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"找":{"docs":{},"出":{"docs":{},"页":{"docs":{},"面":{"docs":{},"上":{"docs":{},"的":{"docs":{},"所":{"docs":{},"有":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},",":{"docs":{},"将":{"docs":{},"一":{"docs":{},"些":{"docs":{},"代":{"docs":{},"码":{"docs":{},"关":{"docs":{},"联":{"docs":{},"到":{"docs":{},"其":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}},"某":{"docs":{},"个":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"点":{"docs":{},"击":{"docs":{},"这":{"docs":{},"个":{"docs":{},"复":{"docs":{},"选":{"docs":{},"框":{"docs":{},"(":{"docs":{},"还":{"docs":{},")":{"docs":{},"不":{"docs":{},"会":{"docs":{},"导":{"docs":{},"致":{"docs":{},"任":{"docs":{},"何":{"docs":{},"结":{"docs":{},"果":{"docs":{},"。":{"docs":{},"像":{"docs":{},"上":{"docs":{},"一":{"docs":{},"章":{"docs":{},"节":{"docs":{},"一":{"docs":{},"样":{"docs":{},",":{"docs":{},"你":{"docs":{},"要":{"docs":{},"通":{"docs":{},"过":{"docs":{},"表":{"docs":{},"单":{"docs":{},"和":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"规":{"docs":{},"则":{"docs":{},",":{"docs":{},"改":{"docs":{},"变":{"docs":{},"该":{"docs":{},"行":{"docs":{},"的":{"docs":{},"外":{"docs":{},"观":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}}},"辅":{"docs":{},"助":{"docs":{},"库":{"docs":{},")":{"docs":{},",":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}},"达":{"docs":{},"成":{"docs":{},"这":{"docs":{},"一":{"docs":{},"点":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}},"过":{"docs":{},"滤":{"docs":{},"器":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}},"输":{"docs":{},"入":{"docs":{},"数":{"docs":{},"据":{"docs":{},",":{"docs":{},"避":{"docs":{},"免":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},"返":{"docs":{},"回":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0017271157167530224}},"一":{"docs":{},"个":{"docs":{},"整":{"docs":{},"数":{"docs":{},",":{"docs":{},"表":{"docs":{},"示":{"docs":{},"在":{"docs":{},"这":{"docs":{},"次":{"docs":{},"保":{"docs":{},"存":{"docs":{},"操":{"docs":{},"作":{"docs":{},"中":{"docs":{},"被":{"docs":{},"更":{"docs":{},"新":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{},"的":{"docs":{},"数":{"docs":{},"量":{"docs":{},"。":{"docs":{},"在":{"docs":{},"当":{"docs":{},"前":{"docs":{},"的":{"docs":{},"情":{"docs":{},"况":{"docs":{},"下":{"docs":{},",":{"docs":{},"它":{"docs":{},"要":{"docs":{},"么":{"docs":{},"是":{"1":{"docs":{},"(":{"docs":{},"条":{"docs":{},"目":{"docs":{},"更":{"docs":{},"新":{"docs":{},"了":{"docs":{},")":{"docs":{},",":{"docs":{},"要":{"docs":{},"么":{"docs":{},"是":{"0":{"docs":{},"(":{"docs":{},"有":{"docs":{},"错":{"docs":{},"误":{"docs":{},"发":{"docs":{},"生":{"docs":{},")":{"docs":{},"。":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}}}}}},"docs":{}}}}}}}}}}}}},"docs":{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"非":{"docs":{},"常":{"docs":{},"简":{"docs":{},"单":{"docs":{},",":{"docs":{},"这":{"docs":{},"跟":{"docs":{"chapters/add-more-features/complete-with-checkbox.html":{"ref":"chapters/add-more-features/complete-with-checkbox.html","tf":0.0011682242990654205}}}}}}},"适":{"docs":{},"合":{"docs":{},"。":{"docs":{},"对":{"docs":{},"于":{"docs":{},"更":{"docs":{},"复":{"docs":{},"杂":{"docs":{},"的":{"docs":{},"项":{"docs":{},"目":{"docs":{},",":{"docs":{},"我":{"docs":{},"建":{"docs":{},"议":{"docs":{},"对":{"docs":{},"各":{"docs":{},"选":{"docs":{},"项":{"docs":{},"都":{"docs":{},"作":{"docs":{},"一":{"docs":{},"些":{"docs":{},"研":{"docs":{},"究":{"docs":{},"和":{"docs":{},"尝":{"docs":{},"试":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"找":{"docs":{},"到":{"docs":{},"你":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"最":{"docs":{},"佳":{"docs":{},"方":{"docs":{},"案":{"docs":{},"。":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"二":{"docs":{},"者":{"docs":{},"常":{"docs":{},"被":{"docs":{},"混":{"docs":{},"淆":{"docs":{},"。":{"docs":{},"验":{"docs":{},"证":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}},"密":{"docs":{},"码":{"docs":{},"重":{"docs":{},"置":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}},"授":{"docs":{},"权":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.008522727272727272},"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}},"确":{"docs":{},"保":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"用":{"docs":{},"户":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}},"你":{"docs":{},"把":{"docs":{},"这":{"docs":{},"个":{"docs":{},"文":{"docs":{},"件":{"docs":{},"保":{"docs":{},"存":{"docs":{},"为":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"社":{"docs":{},"交":{"docs":{},"账":{"docs":{},"号":{"docs":{},"登":{"docs":{},"录":{"docs":{},"、":{"docs":{},"以":{"docs":{},"及":{"docs":{},"借":{"docs":{},"助":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}},"区":{"docs":{},",":{"docs":{},"并":{"docs":{},"希":{"docs":{},"望":{"docs":{},"以":{"docs":{},"我":{"docs":{},"的":{"docs":{},"微":{"docs":{},"薄":{"docs":{},"之":{"docs":{},"力":{"docs":{},"付":{"docs":{},"出":{"docs":{},"回":{"docs":{},"报":{"docs":{},"。":{"docs":{},"希":{"docs":{},"望":{"docs":{},"它":{"docs":{},"帮":{"docs":{},"助":{"docs":{},"你":{"docs":{},"学":{"docs":{},"了":{"docs":{},"一":{"docs":{},"点":{"docs":{},"儿":{"docs":{},"新":{"docs":{},"东":{"docs":{},"西":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"能":{"docs":{},"否":{"docs":{},"做":{"docs":{},"某":{"docs":{},"些":{"docs":{},"事":{"docs":{},"”":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"认":{"docs":{},"为":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}},"设":{"docs":{},"计":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}},"想":{"docs":{},"一":{"docs":{},"下":{"docs":{},",":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"或":{"docs":{},"者":{"docs":{},"其":{"docs":{},"他":{"docs":{},"什":{"docs":{},"么":{"docs":{},"人":{"docs":{},"重":{"docs":{},"构":{"docs":{},"了":{"docs":{},"这":{"docs":{},"个":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}},"置":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852},"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0016992353440951572}}}},"身":{"docs":{},"份":{"docs":{},"验":{"docs":{},"证":{"docs":{},"(":{"docs":{},"i":{"docs":{},"d":{"docs":{},"e":{"docs":{},"n":{"docs":{},"t":{"docs":{},"i":{"docs":{},"t":{"docs":{},"y":{"docs":{},")":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}},"输":{"docs":{},"入":{"docs":{},"密":{"docs":{},"码":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}},"出":{"docs":{},"结":{"docs":{},"束":{"docs":{},"之":{"docs":{},"后":{"docs":{},",":{"docs":{},"浏":{"docs":{},"览":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}},"邮":{"docs":{},"箱":{"docs":{},"地":{"docs":{},"址":{"docs":{},"/":{"docs":{},"密":{"docs":{},"码":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}},"都":{"docs":{},"要":{"docs":{},"重":{"docs":{},"点":{"docs":{},"关":{"docs":{},"注":{"docs":{},"的":{"docs":{},"。":{"docs":{},"确":{"docs":{},"保":{"docs":{},"用":{"docs":{},"户":{"docs":{},"或":{"docs":{},"顾":{"docs":{},"客":{"docs":{},"的":{"docs":{},"数":{"docs":{},"据":{"docs":{},"安":{"docs":{},"全":{"docs":{},"并":{"docs":{},"免":{"docs":{},"遭":{"docs":{},"黑":{"docs":{},"客":{"docs":{},"染":{"docs":{},"指":{"docs":{},",":{"docs":{},"是":{"docs":{},"非":{"docs":{},"常":{"docs":{},"重":{"docs":{},"要":{"docs":{},"的":{"docs":{},"。":{"docs":{},"这":{"docs":{},"个":{"docs":{},"话":{"docs":{},"题":{"docs":{},"所":{"docs":{},"涉":{"docs":{},"甚":{"docs":{},"广":{"docs":{},",":{"docs":{},"包":{"docs":{},"括":{"docs":{},"了":{"docs":{},":":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"是":{"docs":{},"用":{"docs":{},"于":{"docs":{},"了":{"docs":{},"解":{"docs":{},"更":{"docs":{},"多":{"docs":{},"知":{"docs":{},"识":{"docs":{},"以":{"docs":{},"及":{"docs":{},"遇":{"docs":{},"到":{"docs":{},"问":{"docs":{},"题":{"docs":{},"时":{"docs":{},"查":{"docs":{},"找":{"docs":{},"答":{"docs":{},"案":{"docs":{},"的":{"docs":{},"好":{"docs":{},"资":{"docs":{},"源":{"docs":{},"。":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}}}}}}}}}}}}}}},"问":{"docs":{},"的":{"docs":{},"是":{"docs":{},":":{"docs":{},"“":{"docs":{},"这":{"docs":{},"个":{"docs":{},"用":{"docs":{},"户":{"docs":{},"有":{"docs":{},"权":{"docs":{},"限":{"docs":{},"做":{"docs":{},"某":{"docs":{},"件":{"docs":{},"事":{"docs":{},"吗":{"docs":{},"?":{"docs":{},"”":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}},"防":{"docs":{},"止":{"docs":{},"利":{"docs":{},"用":{"docs":{},"表":{"docs":{},"单":{"docs":{},"(":{"docs":{},"f":{"docs":{},"o":{"docs":{},"r":{"docs":{},"m":{"docs":{},")":{"docs":{},"进":{"docs":{},"行":{"docs":{},"的":{"docs":{},"跨":{"docs":{},"域":{"docs":{},"(":{"docs":{},"c":{"docs":{},"s":{"docs":{},"r":{"docs":{},"f":{"docs":{},")":{"docs":{},"攻":{"docs":{},"击":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.002840909090909091}}}}}}}}}}}}}}}}}}}}}}}}}}},"验":{"docs":{},"证":{"docs":{"chapters/security-and-identity/":{"ref":"chapters/security-and-identity/","tf":0.005681818181818182}}}},"而":{"docs":{},"既":{"docs":{},"然":{"docs":{},"你":{"docs":{},"修":{"docs":{},"改":{"docs":{},"了":{"docs":{"chapters/security-and-identity/using-identity-in-the-application.html":{"ref":"chapters/security-and-identity/using-identity-in-the-application.html","tf":0.0009950248756218905}}}}}}}}},"!":{"docs":{},"=":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0031007751937984496}}}},"个":{"docs":{},"已":{"docs":{},"登":{"docs":{},"录":{"docs":{},"用":{"docs":{},"户":{"docs":{},",":{"docs":{},"u":{"docs":{},"s":{"docs":{},"e":{"docs":{},"r":{"docs":{},"m":{"docs":{},"a":{"docs":{},"n":{"docs":{},"a":{"docs":{},"g":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}},"容":{"docs":{},"器":{"docs":{},"和":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}},"所":{"docs":{},"需":{"docs":{},"要":{"docs":{},"的":{"docs":{},"工":{"docs":{},"作":{"docs":{},"是":{"docs":{},"一":{"docs":{},"样":{"docs":{},"的":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}},"做":{"docs":{},"这":{"docs":{},"件":{"docs":{},"事":{"docs":{},",":{"docs":{},"但":{"docs":{},"是":{"docs":{},"因":{"docs":{},"为":{"docs":{},"某":{"docs":{},"些":{"docs":{},"技":{"docs":{},"术":{"docs":{},"原":{"docs":{},"因":{"docs":{},",":{"docs":{},"你":{"docs":{},"无":{"docs":{},"法":{"docs":{},"在":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}},"判":{"docs":{},"断":{"docs":{},"用":{"docs":{},"户":{"docs":{},"是":{"docs":{},"否":{"docs":{},"已":{"docs":{},"经":{"docs":{},"登":{"docs":{},"录":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"没":{"docs":{},"有":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"其":{"docs":{},"余":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"就":{"docs":{},"都":{"docs":{},"被":{"docs":{},"跳":{"docs":{},"过":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"这":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"填":{"docs":{},"充":{"docs":{},"(":{"docs":{},"s":{"docs":{},"e":{"docs":{},"e":{"docs":{},"d":{"docs":{},"i":{"docs":{},"n":{"docs":{},"g":{"docs":{},")":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}},"拒":{"docs":{},"绝":{"docs":{},"访":{"docs":{},"问":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}},"此":{"docs":{},"方":{"docs":{},"法":{"docs":{},"查":{"docs":{},"看":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"里":{"docs":{},"是":{"docs":{},"否":{"docs":{},"存":{"docs":{},"在":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}},"获":{"docs":{},"取":{"docs":{},"s":{"docs":{},"e":{"docs":{},"e":{"docs":{},"d":{"docs":{},"d":{"docs":{},"a":{"docs":{},"t":{"docs":{},"a":{"docs":{},".":{"docs":{},"i":{"docs":{},"n":{"docs":{},"i":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{},"i":{"docs":{},"z":{"docs":{},"e":{"docs":{},"a":{"docs":{},"s":{"docs":{},"y":{"docs":{},"n":{"docs":{},"c":{"docs":{},"(":{"docs":{},")":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"服":{"docs":{},"务":{"docs":{},"集":{"docs":{},"合":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"执":{"docs":{},"行":{"docs":{},"它":{"docs":{},"以":{"docs":{},"便":{"docs":{},"初":{"docs":{},"始":{"docs":{},"化":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"出":{"docs":{},"现":{"docs":{},"错":{"docs":{},"误":{"docs":{},",":{"docs":{},"将":{"docs":{},"会":{"docs":{},"记":{"docs":{},"录":{"docs":{},"一":{"docs":{},"条":{"docs":{},"错":{"docs":{},"误":{"docs":{},"日":{"docs":{},"志":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"直":{"docs":{},"接":{"docs":{},"注":{"docs":{},"入":{"docs":{},"到":{"docs":{},"视":{"docs":{},"图":{"docs":{},"里":{"docs":{},"来":{"docs":{},"进":{"docs":{},"行":{"docs":{},"这":{"docs":{},"些":{"docs":{},"操":{"docs":{},"作":{"docs":{},"。":{"docs":{},"为":{"docs":{},"保":{"docs":{},"持":{"docs":{},"你":{"docs":{},"视":{"docs":{},"图":{"docs":{},"整":{"docs":{},"洁":{"docs":{},"有":{"docs":{},"序":{"docs":{},",":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"新":{"docs":{},"的":{"docs":{},"局":{"docs":{},"部":{"docs":{},"视":{"docs":{},"图":{"docs":{},"(":{"docs":{},"p":{"docs":{},"a":{"docs":{},"r":{"docs":{},"t":{"docs":{},"i":{"docs":{},"a":{"docs":{},"l":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"角":{"docs":{},"色":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"没":{"docs":{},"有":{"docs":{},",":{"docs":{},"它":{"docs":{},"就":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{},"。":{"docs":{},"为":{"docs":{},"免":{"docs":{},"反":{"docs":{},"复":{"docs":{},"地":{"docs":{},"输":{"docs":{},"入":{"docs":{},"字":{"docs":{},"符":{"docs":{},"串":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}},"请":{"docs":{},"尝":{"docs":{},"试":{"docs":{},"用":{"docs":{},"这":{"docs":{},"个":{"docs":{},"账":{"docs":{},"号":{"docs":{},"登":{"docs":{},"录":{"docs":{},",":{"docs":{},"并":{"docs":{},"浏":{"docs":{},"览":{"docs":{},"位":{"docs":{},"于":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}},"外":{"docs":{},"加":{"docs":{},"一":{"docs":{},"个":{"docs":{},"测":{"docs":{},"试":{"docs":{},"用":{"docs":{},"的":{"docs":{},"管":{"docs":{},"理":{"docs":{},"员":{"docs":{},"账":{"docs":{},"号":{"docs":{},"添":{"docs":{},"加":{"docs":{},"到":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"中":{"docs":{},"。":{"docs":{},"向":{"docs":{},"数":{"docs":{},"据":{"docs":{},"库":{"docs":{},"添":{"docs":{},"加":{"docs":{},"初":{"docs":{},"始":{"docs":{},"数":{"docs":{},"据":{"docs":{},"的":{"docs":{},"行":{"docs":{},"为":{"docs":{},",":{"docs":{},"被":{"docs":{},"称":{"docs":{},"为":{"docs":{},"初":{"docs":{},"始":{"docs":{},"化":{"docs":{},",":{"docs":{},"或":{"docs":{},"者":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"才":{"docs":{},"能":{"docs":{},"查":{"docs":{},"看":{"docs":{},"这":{"docs":{},"个":{"docs":{},"页":{"docs":{},"面":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}},",":{"docs":{},"相":{"docs":{},"对":{"docs":{},"于":{"docs":{},"普":{"docs":{},"通":{"docs":{},"用":{"docs":{},"户":{"docs":{},",":{"docs":{},"他":{"docs":{},"们":{"docs":{},"拥":{"docs":{},"有":{"docs":{},"更":{"docs":{},"多":{"docs":{},"的":{"docs":{},"权":{"docs":{},"限":{"docs":{},"和":{"docs":{},"能":{"docs":{},"力":{"docs":{},"。":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}}}}}}}}}}}}}}}},"路":{"docs":{},"径":{"docs":{},"。":{"docs":{},"你":{"docs":{},"会":{"docs":{},"见":{"docs":{},"到":{"docs":{},"这":{"docs":{},"样":{"docs":{},"的":{"docs":{"chapters/security-and-identity/authorization-with-roles.html":{"ref":"chapters/security-and-identity/authorization-with-roles.html","tf":0.0007751937984496124}}}}}}}}}}}},"帮":{"docs":{},"助":{"docs":{},"你":{"docs":{},"添":{"docs":{},"加":{"docs":{},"诸":{"docs":{},"如":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":0.005076142131979695}}}}}}}}},"附":{"docs":{},"加":{"docs":{},"资":{"docs":{},"源":{"docs":{"chapters/security-and-identity/more-resources.html":{"ref":"chapters/security-and-identity/more-resources.html","tf":10.00507614213198}}}}}},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{"chapters/automated-testing/":{"ref":"chapters/automated-testing/","tf":0.0125},"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":10.000863557858377}},"是":{"docs":{},"短":{"docs":{},"小":{"docs":{},"的":{"docs":{},"测":{"docs":{},"试":{"docs":{},",":{"docs":{},"检":{"docs":{},"查":{"docs":{},"单":{"docs":{},"个":{"docs":{},"方":{"docs":{},"法":{"docs":{},"或":{"docs":{},"类":{"docs":{},"的":{"docs":{},"行":{"docs":{},"为":{"docs":{},"。":{"docs":{},"当":{"docs":{},"你":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"代":{"docs":{},"码":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"其":{"docs":{},"它":{"docs":{},"方":{"docs":{},"法":{"docs":{},"或":{"docs":{},"类":{"docs":{},"时":{"docs":{},",":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"于":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"页":{"docs":{},"面":{"docs":{},"应":{"docs":{},"用":{"docs":{},",":{"docs":{},"例":{"docs":{},"如":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}},"例":{"docs":{},"如":{"docs":{},",":{"docs":{},"t":{"docs":{},"o":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"o":{"docs":{},"n":{"docs":{},"t":{"docs":{},"r":{"docs":{},"o":{"docs":{},"l":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}},"另":{"docs":{},"一":{"docs":{},"方":{"docs":{},"面":{"docs":{},",":{"docs":{},"当":{"docs":{},"你":{"docs":{},"写":{"docs":{},"单":{"docs":{},"元":{"docs":{},"测":{"docs":{},"试":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"你":{"docs":{},"需":{"docs":{},"要":{"docs":{},"自":{"docs":{},"己":{"docs":{},"处":{"docs":{},"理":{"docs":{},"这":{"docs":{},"个":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"图":{"docs":{},"。":{"docs":{},"典":{"docs":{},"刑":{"docs":{},"的":{"docs":{},"做":{"docs":{},"法":{"docs":{},"是":{"docs":{},",":{"docs":{},"提":{"docs":{},"供":{"docs":{},"这":{"docs":{},"些":{"docs":{},"依":{"docs":{},"赖":{"docs":{},"的":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"只":{"docs":{},"返":{"docs":{},"回":{"docs":{},"某":{"docs":{},"个":{"docs":{},"特":{"docs":{},"定":{"docs":{},"用":{"docs":{},"户":{"docs":{},"的":{"docs":{},"条":{"docs":{},"目":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"简":{"docs":{},"单":{"docs":{},"几":{"docs":{},"步":{"docs":{},"。":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"通":{"docs":{},"过":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}},"断":{"docs":{},"言":{"docs":{},"—":{"docs":{},"—":{"docs":{},"a":{"docs":{},"r":{"docs":{},"r":{"docs":{},"a":{"docs":{},"n":{"docs":{},"g":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}},"一":{"docs":{},"个":{"docs":{},"日":{"docs":{},"期":{"docs":{},"时":{"docs":{},"间":{"docs":{},"值":{"docs":{},"有":{"docs":{},"点":{"docs":{},"棘":{"docs":{},"手":{"docs":{},",":{"docs":{},"因":{"docs":{},"为":{"docs":{},"比":{"docs":{},"较":{"docs":{},"两":{"docs":{},"个":{"docs":{},"日":{"docs":{},"期":{"docs":{},"值":{"docs":{},"的":{"docs":{},"时":{"docs":{},"候":{"docs":{},",":{"docs":{},"就":{"docs":{},"算":{"docs":{},"是":{"docs":{},"只":{"docs":{},"有":{"docs":{},"毫":{"docs":{},"秒":{"docs":{},"部":{"docs":{},"分":{"docs":{},"不":{"docs":{},"同":{"docs":{},",":{"docs":{},"两":{"docs":{},"个":{"docs":{},"值":{"docs":{},"也":{"docs":{},"是":{"docs":{},"不":{"docs":{},"等":{"docs":{},"的":{"docs":{},"。":{"docs":{},"替":{"docs":{},"代":{"docs":{},"方":{"docs":{},"案":{"docs":{},"是":{"docs":{},",":{"docs":{},"检":{"docs":{},"查":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"窗":{"docs":{},"口":{"docs":{},",":{"docs":{},"以":{"docs":{},"便":{"docs":{},"代":{"docs":{},"码":{"docs":{},"完":{"docs":{},"成":{"docs":{},"功":{"docs":{},"能":{"docs":{},"在":{"docs":{},"新":{"docs":{},"项":{"docs":{},"目":{"docs":{},"里":{"docs":{},"生":{"docs":{},"效":{"docs":{},"。":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}}}}}}}}}}}}}}}}}}},"需":{"docs":{},"要":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"完":{"docs":{},"整":{"docs":{},"、":{"docs":{},"详":{"docs":{},"尽":{"docs":{},"的":{"docs":{},"变":{"docs":{},"更":{"docs":{},"记":{"docs":{},"录":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"到":{"docs":{},":":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}},"顺":{"docs":{},"带":{"docs":{"chapters/automated-testing/unit-testing.html":{"ref":"chapters/automated-testing/unit-testing.html","tf":0.0008635578583765112}}}},"像":{"docs":{},"以":{"docs":{},"往":{"docs":{},"一":{"docs":{},"样":{"docs":{},",":{"docs":{},"a":{"docs":{},"s":{"docs":{},"p":{"docs":{},".":{"docs":{},"n":{"docs":{},"e":{"docs":{},"t":{"docs":{"chapters/automated-testing/integration-testing.html":{"ref":"chapters/automated-testing/integration-testing.html","tf":0.00129366106080207}}}}}}}}}}}}}}},"万":{"docs":{},"事":{"docs":{},"俱":{"docs":{},"备":{"docs":{},",":{"docs":{},"只":{"docs":{},"欠":{"docs":{},"东":{"docs":{},"风":{"docs":{},"。":{"docs":{},"当":{"docs":{},"一":{"docs":{},"个":{"docs":{},"良":{"docs":{},"好":{"docs":{},"的":{"docs":{},"程":{"docs":{},"序":{"docs":{},"构":{"docs":{},"建":{"docs":{},"完":{"docs":{},"成":{"docs":{},",":{"docs":{},"就":{"docs":{},"应":{"docs":{},"该":{"docs":{},"与":{"docs":{},"全":{"docs":{},"世":{"docs":{},"界":{"docs":{},"分":{"docs":{},"享":{"docs":{},"它":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},"任":{"docs":{},"何":{"docs":{},"有":{"docs":{},"能":{"docs":{},"力":{"docs":{},"托":{"docs":{},"管":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}},"容":{"docs":{},"器":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"机":{"docs":{},"器":{"docs":{},"都":{"docs":{},"能":{"docs":{},"用":{"docs":{},"来":{"docs":{},"托":{"docs":{},"管":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}},")":{"docs":{},"里":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}},"监":{"docs":{},"听":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"自":{"docs":{},"己":{"docs":{},"也":{"docs":{},"需":{"docs":{},"要":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}},"托":{"docs":{},"管":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}},"程":{"docs":{},"序":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"用":{"docs":{},"的":{"docs":{},"是":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}},"更":{"docs":{},"容":{"docs":{},"易":{"docs":{},"(":{"docs":{},"也":{"docs":{},"更":{"docs":{},"便":{"docs":{},"宜":{"docs":{},")":{"docs":{},",":{"docs":{},"不":{"docs":{},"过":{"docs":{},"你":{"docs":{},"要":{"docs":{},"是":{"docs":{},"愿":{"docs":{},"意":{"docs":{},"自":{"docs":{},"己":{"docs":{},"管":{"docs":{},"理":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}},"多":{"docs":{},"的":{"docs":{},"b":{"docs":{},"u":{"docs":{},"g":{"docs":{},"修":{"docs":{},"正":{"docs":{},"和":{"docs":{},"一":{"docs":{},"些":{"docs":{},"小":{"docs":{},"改":{"docs":{},"进":{"docs":{},"。":{"docs":{},"添":{"docs":{},"加":{"docs":{},"译":{"docs":{},"版":{"docs":{},"的":{"docs":{},"链":{"docs":{},"接":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}}}}}}}}},"深":{"docs":{},"入":{"docs":{},"的":{"docs":{},"学":{"docs":{},"习":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"网":{"docs":{},"络":{"docs":{},"服":{"docs":{},"务":{"docs":{},"器":{"docs":{},"托":{"docs":{},"管":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}},"应":{"docs":{},"用":{"docs":{},"。":{"docs":{},"如":{"docs":{},"果":{"docs":{},"你":{"docs":{},"本":{"docs":{},"地":{"docs":{},"目":{"docs":{},"录":{"docs":{},"尚":{"docs":{},"未":{"docs":{},"作":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}}}}}}},"订":{"docs":{},"阅":{"docs":{},",":{"docs":{},"你":{"docs":{},"只":{"docs":{},"要":{"docs":{},"创":{"docs":{},"建":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}},"(":{"docs":{},"免":{"docs":{},"费":{"docs":{},"的":{"docs":{},"订":{"docs":{},"阅":{"docs":{},"就":{"docs":{},"可":{"docs":{},"以":{"docs":{},"了":{"docs":{},")":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}}}},"部":{"docs":{},"署":{"docs":{},"方":{"docs":{},"式":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}},"程":{"docs":{},"序":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":10.002597402597402}}}},"到":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":5.0018518518518515}}}}},"镜":{"docs":{},"像":{"docs":{},"是":{"docs":{},"个":{"docs":{},"非":{"docs":{},"常":{"docs":{},"快":{"docs":{},"捷":{"docs":{},"的":{"docs":{},"部":{"docs":{},"署":{"docs":{},"程":{"docs":{},"序":{"docs":{},"的":{"docs":{},"方":{"docs":{},"式":{"docs":{},",":{"docs":{},"尤":{"docs":{},"其":{"docs":{},"是":{"docs":{},"在":{"docs":{},"你":{"docs":{},"熟":{"docs":{},"悉":{"docs":{"chapters/deploy-the-application/":{"ref":"chapters/deploy-the-application/","tf":0.0025974025974025974}}}}}}}}}}}}}}}}}}}}}}}},"将":{"docs":{},"会":{"docs":{},"非":{"docs":{},"常":{"docs":{},"迅":{"docs":{},"速":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}},",":{"docs":{},"里":{"docs":{},"面":{"docs":{},"包":{"docs":{},"含":{"docs":{},"你":{"docs":{},"程":{"docs":{},"序":{"docs":{},"运":{"docs":{},"行":{"docs":{},"所":{"docs":{},"需":{"docs":{},"的":{"docs":{},"一":{"docs":{},"切":{"docs":{},",":{"docs":{},"然":{"docs":{},"后":{"docs":{},"在":{"docs":{},"任":{"docs":{},"何":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}}},"得":{"docs":{},"到":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}},"才":{"docs":{},"初":{"docs":{},"次":{"docs":{},"安":{"docs":{},"装":{"docs":{},"完":{"docs":{},"成":{"docs":{},",":{"docs":{},"运":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"资":{"docs":{},"源":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}},"组":{"docs":{},"(":{"docs":{},"r":{"docs":{},"e":{"docs":{},"s":{"docs":{},"o":{"docs":{},"u":{"docs":{},"r":{"docs":{},"c":{"docs":{"chapters/deploy-the-application/deploy-to-azure.html":{"ref":"chapters/deploy-the-application/deploy-to-azure.html","tf":0.001851851851851852}}}}}}}}}}}}},"于":{"docs":{},"镜":{"docs":{},"像":{"docs":{},"中":{"docs":{},"重":{"docs":{},"建":{"docs":{},"这":{"docs":{},"些":{"docs":{},"包":{"docs":{},",":{"docs":{},"d":{"docs":{},"o":{"docs":{},"c":{"docs":{},"k":{"docs":{},"e":{"docs":{},"r":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}},"冲":{"docs":{},"突":{"docs":{},",":{"docs":{},"在":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"头":{"docs":{},"字":{"docs":{},"段":{"docs":{},"为":{"docs":{},"一":{"docs":{},"个":{"docs":{},"已":{"docs":{},"知":{"docs":{},"的":{"docs":{},"有":{"docs":{},"效":{"docs":{},"值":{"docs":{},"(":{"docs":{},"k":{"docs":{},"n":{"docs":{},"o":{"docs":{},"w":{"docs":{},"n":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}},"官":{"docs":{},"网":{"docs":{},"的":{"docs":{},"提":{"docs":{},"示":{"docs":{},"内":{"docs":{},"容":{"docs":{},"。":{"docs":{},"要":{"docs":{},"检":{"docs":{},"验":{"docs":{},"是":{"docs":{},"否":{"docs":{},"安":{"docs":{},"装":{"docs":{},"成":{"docs":{},"功":{"docs":{},",":{"docs":{},"可":{"docs":{},"以":{"docs":{},"执":{"docs":{},"行":{"docs":{},":":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}}}}}}}},"方":{"docs":{},"的":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}},"宿":{"docs":{},"主":{"docs":{},"。":{"docs":{},"例":{"docs":{},"如":{"docs":{},",":{"docs":{},"你":{"docs":{},"可":{"docs":{},"以":{"docs":{},"用":{"docs":{},"亚":{"docs":{},"马":{"docs":{},"逊":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}},"机":{"docs":{},"上":{"docs":{},"作":{"docs":{},"为":{"docs":{},"容":{"docs":{},"器":{"docs":{},"启":{"docs":{},"动":{"docs":{},"起":{"docs":{},"来":{"docs":{},"就":{"docs":{},"行":{"docs":{},"了":{"docs":{},"。":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}}}},"搭":{"docs":{},"建":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}},"整":{"docs":{},"体":{"docs":{},"架":{"docs":{},"构":{"docs":{},"会":{"docs":{},"包":{"docs":{},"括":{"docs":{},"两":{"docs":{},"个":{"docs":{},"容":{"docs":{},"器":{"docs":{},":":{"docs":{},"一":{"docs":{},"个":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}}}}}}}}}}}},"清":{"docs":{},"单":{"docs":{},"创":{"docs":{},"建":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}}},"电":{"docs":{},"脑":{"docs":{},"的":{"docs":{"chapters/deploy-the-application/deploy-with-docker.html":{"ref":"chapters/deploy-the-application/deploy-with-docker.html","tf":0.0008496176720475786}}}}},"z":{"docs":{},"h":{"docs":{},"y":{"docs":{},"l":{"docs":{},"i":{"docs":{},"c":{"docs":{},"h":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.004319654427645789}}}}}}}}},"初":{"docs":{},"次":{"docs":{},"发":{"docs":{},"布":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}},"博":{"docs":{},"客":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}},"嗨":{"docs":{},",":{"docs":{},"我":{"docs":{},"是":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}},"大":{"docs":{},"幅":{"docs":{},"度":{"docs":{},"重":{"docs":{},"写":{"docs":{},"了":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}},"祝":{"docs":{},"你":{"docs":{},"代":{"docs":{},"码":{"docs":{},"敲":{"docs":{},"得":{"docs":{},"愉":{"docs":{},"快":{"docs":{},"!":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}},"笔":{"docs":{},"误":{"docs":{},"修":{"docs":{},"正":{"docs":{},"和":{"docs":{},"一":{"docs":{},"些":{"docs":{},"读":{"docs":{},"者":{"docs":{},"建":{"docs":{},"议":{"docs":{},"的":{"docs":{},"改":{"docs":{},"进":{"docs":{},"。":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":0.0021598272138228943}}}}}}}}}}}}}}}}},"结":{"docs":{},"束":{"docs":{},"语":{"docs":{"chapters/conclusion/":{"ref":"chapters/conclusion/","tf":10.002159827213823}}}}}},"length":9094},"corpusTokens":["!=","\"..\\\\..\\\\..\\\\..\\\\aspnetcoretodo\"));","\".deployment\",","\".deployment\",以此避免被添加一个","\"/login?returnurl=%2ftodo\",","\"/todo\");","\"80\"","\"80:80\"","\"a","\"admin@todo.local\"","\"admin@todo.local\")","\"admin@todo.local\",","\"administrator\")]","\"administrator\",","\"administrator\";","\"administrator\",创建一个名为","\"amazon","\"aspnetcoretodo.dll\"]","\"backend\")","\"base\"","\"build","\"business\"","\"callback","\"could","\"db\"","\"db\")","\"digitalocean","\"do","\"doe","\"dotnet","\"download","\"error","\"fake","\"fake@example.com\"","\"first","\"frontend\")","\"get","\"hello","\"hello\"","\"http://localhost:8888/account\"","\"humanize\"","\"i\".","\"injected\"","\"items\");","\"items\",","\"layers\"","\"learn","\"manag","\"metapackage\"","\"mocked\"","\"models\",","\"notsecure123!!\");","\"plain","\"remember\"","\"root\"","\"scaffold","\"test_addnewitem\").options;","\"testing?\"","\"versions\"","\"wire","\"x","#888;","$('.done","$(document).ready(function()","$(row).addclass('done');","$host;","$http_upgrade;","✔","&&","'keep","'todoitem'","(","(!modelstate.isvalid)","(!successful)","($10/month)","(...","(.c","(2.1.104)","(2017","(2018","(@nbarbettini)","(a","(admittedli","(alreadyexists)","(also","(and","(appsettings.json).","(are","(arrang","(aspnetcoretodo.servic","(asserts)","(at","(await","(but","(c#,","(call","(chinese)","(common","(compil","(connect","(csrf)","(currentus","(depend","(despit","(document)","(dto).","(english","(entity)","(etc...)","(even","(except","(follow","(for","(give","(html,","(https://docs.asp.net)","(https://github.com/github/gitignore)","(https://www.nuget.org/packages/humanizer)","(https://www.recaffeinate.co).","(i'll","(id","(if","(in","(includ","(index,","(integer)","(isadmin)","(isdon","(it","(item","(javascript)","(just","(jvm)","(languag","(layers)","(like","(littleasp.net/book)","(log","(mac/windows/linux)\"","(make","(mark","(model","(more","(multi","(mvc)","(mytodoapp","(naturally).","(no","(not","(on","(optional)","(or","(or,","(orm)","(output","(pocos).","(port","(protect","(really)","(roll","(rubi","(search","(separate)","(signinmanager.issignedin(user))","(similar","(simplifi","(some","(someth","(sometim","(testadmin","(text","(the","(thi","(title)","(tri","(true/fals","(turkish)","(use","(usual","(var","(via","(when","(where","(whether","(which","(with","(without","(yet).","(you'll","(不带","(土耳其语)","(简体中文)","(连同","*","+",".","..","...","../aspnetcoretodo/aspnetcoretodo.csproj","./","./app/aspnetcoretodo/","./aspnetcoretodo/","./dockerfil","./nginx","./nginx/dockerfil",".additemasync(newitem,",".c",".configureappconfiguration((context,",".cshtml",".csproj",".deploy",".deployment,而不带有什么其它的零碎儿。(在",".getincompleteitemsasync(currentuser);",".getrequiredservice>();",".getusersinroleasync(\"administrator\"))",".gitignor",".items.countasync();",".markdoneasync(id,",".net",".net,",".net标准",".net标准1.0",".net标准1.5",".net标准2.0",".net标准,这些命名有些混乱,所以在此做一简短的释疑:",".roleexistsasync(constants.administratorrole);",".singleordefaultasync();",".toarray();",".toarrayasync();",".txt",".useinmemorydatabase(databasename:",".usestartup()",".where(x","/","//","/app","/app/aspnetcoretodo","/app/aspnetcoretodo/","/app/aspnetcoretodo/.","/app/aspnetcoretodo/out","/etc/nginx/nginx.conf","/foo","/foo,","/manageus","/p:publishwithaspnetcoretargetmanifest=\"false\"","/todo","/todo/additem","/todo/additem。眼下这不会有效果,因为还没有任何","/todo/index","/todo/index,后者会刷新页面。","/todo/index,后者会刷新页面并向用户显示新的待办事项列表。","/todo/index,并刷新页面。","/todo。你会被自动重定向到登录页面:","/todo,并验证浏览器被重定向到了登录页面。","0","0,","0.","000\",","00_createidentityschema.cs)","01","03):","05","06","09","0xnf","0,或在","1","1.","1.0.","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1;","1.5,","1.9074","10","10.13","100","1024;","10x","11","11):","13):","15):","15.3","15px;","18):","1;","1。","2.0","2.0,","2.0588","2.0,一个用于创建","2.1.104","20):","200","2017","2018.","23):","3","3.0","387","3级","3,使用如下命令进行安装。","4","4,","4.0","4.x","4.x,","400","404","43ec09f2","48ec687460","4f4b","5","5000","5000.","5,而后者的名字最终被改成了","65011d5781bb.","65011d5781bb。因为","75615","7f70","80","80).","80,","80.","8080","8080!).","8080:80","8080!)。nginx","80;","80?","80端口。打开你的浏览器,浏览地址","8601","8601),","8601)对机器来说很方便,但是人类看着就不爽了。如果看到的是“还剩","9559","978",":","=","==","=>",">","?","?,每个待办事项都必须带有一个截止日期。id","@","@await","@foreach","@html.actionlink()","@html.actionlink()。tag","@if","@inject","@item.dueat","@item.dueat.humanize()","@item.titl","@model","@use","@user.email","@user.id","@viewdata[\"title\"]","@{","[\"dotnet\",","[authorize(rol","[authorize]","[authorize],","[config]","[fact]","[required]","[validateantiforgerytoken]","[welkie]","[zhilich]","_","_client","_client.sendasync(request);","_client;","_context","_context.item","_context.items.add(newitem);","_context.savechangesasync();","_context;","_layout.cshtml","_server","_server.createclient();","_server.dispose();","_server;","_todoitemservic","_todoitemservice.additemasync(newitem);","_todoitemservice.getincompleteitemsasync();","_todoitemservice.markdoneasync(id);","_todoitemservice;","_usermanag","_usermanager.getuserasync(user);","_usermanager.us","_usermanager;","aaa","aaa(布置","abil","about()","about,","about.","abov","above)","above,","absolut","abstract","accept","access","accident","accomplish","account","account'","account,","account.","accounts,","accounts.","accur","achiev","act","act:","action","action!","action,","action.","action:","actions,","actions.","action名","action,asp.net","action,把那句","action:","activ","activerecord","actual","ad","add","added.)","addit","additem","additem(todoitem","additemasync","additemasync(","additemasync()","additemasync():","additemasync(newtodoitem","additemasync(todoitem","additempartial.cshtml","additems。","additemuserid","addnewitemasincompletewithduedate()","address","addscop","addsingleton","add,其浏览器会构建一个","admin","admin@todo.loc","administr","administrator.","administratorrol","admins,","adminstrator,","advanc","advantag","affect","again","again,","again.","against","agnost","agnostic,","ahead","ajax","alive';","all)","allow","along","along!","alreadi","already,","already:","alreadyexist","alright,","altern","alternative:","although","alway","amaz","amazon","amount","and,","andrew","android","angular","angular.","anonym","anoth","answer","anyon","anyth","anything,","anything:","anywher","apach","api","api.","api:","apis,","apis.","api。值得指出的是,.net","api。这是你将要安装到机器上,用来构建和运行","app","app!","app,","app.","app.db","app.db。","append","appli","applic","application!","application,","application.","application:","application_start","applicationdbcontext","applicationdbcontext(","applicationdbcontext(options))","applicationdbcontext,","applicationdbcontext.","applicationdbcontext。applicationdbcontext","applicationdbcontext。(你可以画一条线表示","applicationdbcontext,后者通常连接到你的开发或生产环境里的数据库。你不该把这些数据库用于测试。相反,你可以在测试代码里使用","applicationdbcontext,这种方式被称为","applications,","applications.","applicationus","applicationuser[]","approach","appropri","apps\",","appservic","appsettings.json","architect","architectur","architecture.","architecture:","area","aren't","aren't,","args)","around","arrang","array","array.","ask","asks,","asp","asp.net","asp.net,","aspect","aspnetcor","aspnetcore_url","aspnetcoretodo","aspnetcoretodo).","aspnetcoretodo.","aspnetcoretodo.control","aspnetcoretodo.csproj","aspnetcoretodo.csproj,会看到新增了一行","aspnetcoretodo.data;","aspnetcoretodo.dll.","aspnetcoretodo.dll。这条命令告诉","aspnetcoretodo.integrationtest","aspnetcoretodo.integrationtests.csproj","aspnetcoretodo.integrationtests/","aspnetcoretodo.integrationtests/testfixture.c","aspnetcoretodo.integrationtests/todorouteshould.c","aspnetcoretodo.model","aspnetcoretodo.models;","aspnetcoretodo.models中),它需要在文件顶部包含一条","aspnetcoretodo.servic","aspnetcoretodo.services.","aspnetcoretodo.services;","aspnetcoretodo.services。命名空间是一种组织","aspnetcoretodo.unittest","aspnetcoretodo.unittests.csproj","aspnetcoretodo.unittests/","aspnetcoretodo.unittests/todoitemserviceshould.c","aspnetcoretodo/","aspnetcoretodo/*.csproj","aspnetcoretodo/.","aspnetcoretodo/aspnetcoretodo.csproj","aspnetcoretodo_sampl","aspnetcoretodogroup","aspnetcoretodoplan","aspnetcoretodo)。然后使用以下命令搭建出一个新的测试项目:","assembl","assert","assert)","assert.equal(","assert.equal(\"testing?\",","assert.equal(1,","assert.equal(false,","assert.true(differ","assert:","assert)模式:对象和数据首先被建立出来,然后执行一些动作,最后测试程序检查(断言)预期表现的存在。","asset","assign","assum","assumpt","async","async:","asynchron","asynchronous.","async:","atom,","atom、sublime、notepad","attach","attack","attackers.","attacks)","attacks,","attacks.","attribut","attribute).","attribute.","attributes.","auth","authent","authenticated.","authentication,","author","authorization.","auto","autom","automat","automatically,","automatically.","avail","available,","available.","avoid","await","await。","await。这是个罕见的例外","await!","await(等待)","await,以确保你的代码暂停,直到结果就绪才继续执行。","awar","away","away,","away.","awesom","az","azur","azure,","azure.","azure,这些就都是自动为你处理的。在","b","b2c","back","back)","backend","background).","bad","badli","badrequest(\"could","badrequest(new","bake","balanc","bar","barbettini","base","base(options)","base.onmodelcreating(builder);","basic","basic,","basic,f#)可以用来编写","be","becam","becom","befor","begin","behavior","behind","behind.","below","below.","below.)","benefit","best","better","between","big","big,","bin","bind","binder,","binding,","binding.","binding/validation,","bing.com)","bit","bit.","blank","blank.","blissfulli","bloat","block","block:","blocked,","blog","blog.","book","book!","book,","book.","book/book/)的版本更新。有关版本信息和更新内容,请查阅本书的最后一页。","book/releas","book:","bookstore.","bool","boolean","bootstrap","both","bottom","bound","box","box,","box:","break","breakpoint","breakpoints):","bring","broad","brought","brows","browser","browser,","browser.","bug","bugs,","bug修正和一些小改进。","bug,并使你后续重构代码的工作轻松些,以免破坏现有功能或引入新的问题。","build","build.","build:","builder","builder)","buildwebhost(args);","built","bundl","busi","button","c","c#","c#,","c#、javascript、html","c#里的字符串总是可空的,所以没必要给","c.","cach","caffein","calcul","call","callback","came","can't","candid","capabl","care","case),","case).","case,","case.","cases,","catch","caus","cd","cd.","cd。dockerfil","center,","certain","challenge()","challenge();","challenge,","challengeanonymoususer()","chang","changed!","changelog","changelog.","changes).","changes,","changes.","chapter","chapter!","chapter).","chapter,","chapter.","chapter.)","cheaper)","check","check,","check:","checkbox","checkbox').on('click',","checkbox,","checkbox.","checkbox.closest('form');","checkbox.closest('tr');","checkbox.dis","checked,","checked.","checks.","chines","chinese)","choice,","choos","chunk","clarifi","class","class,","class.","class:","class?","classes,","claus","clean","cli","cli)","cli.","click","clicked,","client","client.baseaddress","client.dispose();","clipboard,","cli。搜索","cli(按照","cli)确保一切正常工作:","close","closer","cloud","clunki","clutter","code","code\"","code)","code),","code)。如果你用的是","code,","code.","code...)","code:","codes,","code”再按指令操作即可。(译者的话:别用","code。","code。这是个免费、跨平台的代码编辑器,对于","code(或者","code),或者在终端窗口里运行","code,你可能需要关闭并重新打开","code,当你鼠标指针指向一个红色波浪线时,编辑器会提示你添加这些","coding!","collect","color:","column","columns:","combin","come","command","commands:","comment","comment:","commercially).","commit","commit!\"","common","commonli","commun","communicate.","compar","compil","compiled,","compiler,","compiles:","complet","complete,","complete.","complete:","completely,","complex","compon","components,","components:","compos","compose.yml","compose.yml:","compose.yml:","comprehensive,","compris","concept","concern","concern.","concerns:","conclus","concret","config","config)","config.addjsonfile(\"appsettings.json\");","config.setbasepath(path.combine(","configur","configuration.getconnectionstring(\"defaultconnection\")));","configureservic","configureservices(iservicecollect","configureservices.","conflict","confus","confused.","confusing,","connect","connect.","connectors,","cons.","consid","consist","consol","console.writeline(\"hello","const","constant","constants.administratorrole);","constants.c","constraints:","construct","constructor","constructor,","constructor:","contact","contact()","contact)","contact),由","contain","container","container!","container'","container,","containers),","containers.","containers:","container)的生命周期添加说明,阐释服务端口和","content","content,","content.","context","context)","context)是一个","context,","context.","context.items.firstasync();","context;","continu","contribut","contributor","contributors,","control","controller)","controller),","controller,","controller.","controller:","controllers,","controllers.","controllers/","controllers/manageuserscontroller.c","controllers/todocontroller.c","controllers目录里放置着","controller)、依赖注入,和一个由中间件构成的请求处理管线。它基于","controller)是一个构建","controller)架构的组件。下一章,你将一探他们三者的究竟。","conveni","convent","convention,","conventions.","convert","copi","copy,","copyright","core","core!","core\"","core\",","core'","core)","core,","core.","core?","core”,在微软为你所在平台提供的下载页面,获取","core、c#和mvc模式","core。","core。ent","core包","core(以及你的数据库)打交道,如果用单件(或其它)生命周期会引发麻烦,原因在于","core,你想把","core,在任何时候,只要","core,该视图需要配合","core?","correct","correctli","correctly,","correspond","cost","couldn't","coupl","coupon,","cours","course,","cover","coverag","crazi","creat","create.","create:","created,","created.","created:","createidentityschema","creating:","creativ","credenti","credit","credit.","cross","csharphelloworld","csharphelloworld.csproj","csrf)","css","css,","css、javascript、图片文件","ctrl","ctrl+c","current","currentus","currentuser);","currentuser,","cursor","custom","customari","cycl","c。","d1","d1($10/月)或更高级的方案。","data","data,","data.","data/applicationdbcontext.c","data/migr","data/migrations/_additems.c","data:","databas","database!","database\"","database)","database,","database.","database.)","database:","database”相关的内容,并阅读微软的关于使用","datasource=app.db.","datasource=app.db。","date","date)","date,","date.","date/tim","dates,","datetim","datetimeoffset","datetimeoffset,","datetimeoffset.now.adddays(1)","datetimeoffset.now.adddays(2)","datetimeoffset.now.adddays(3)","datetimeoffset.now.adddays(3);","datetimeoffset?","datetimeoffset,c#","day","days.","db.\");","dbcontext","dbcontextopt","dbcontextoptionsbuild","dbcontextoptionsbuilder()","dbset","dbset:","deal","debug","decid","decis","declar","declared)","decoration:","decoupl","deep","default","default,","default.","default:","defin","defined,","definit","definition.","definition:","delet","deni","depend","dependencies.","dependencies:","deploy","deployed,","deployment.","deployment:","depth","describ","descript","deserialization,","deserv","design","design!","detail","details...)","determin","develop","developer,","development,","development.","didn't","differ","difference!","different.","digitalocean","digitalocean,因为他们把入门的门槛降得非常低。digitalocean","dir","direct","directives.","directli","directly.","directori","directories.","directory),","directory):","directory,","directory.","directory.getcurrentdirectory(),","directory:","disabl","disappear","discovered:","discovering:","display","dispose()","distinct","div.todo","dive","django,","do","do,","docker","docker\"","docker\").","docker.","dockerfil","dockerfile,","dockerfile.","dockerfile。","dockerfile。为避免跟你刚才创建那个","dockerfile(没有扩展名)的文件。用你常用的编辑器打开它,输入下面这行:","dockerfile,它就像个清单,告诉","docker”","docker”)。","document","documentation.","does.","doesn't","doing,","domain","don't","done","done!","done,","done.\");","dotnet","dotnet,使用先前由","doubl","down","down(migrationbuild","down.","down:","download","draw","driven","drop","dropped.","due","dueat","duplicated,","durat","durations,","dure","e","each","earlier.","earlier:","easi","easier","easier,","easiest)","ec2","ec2,","ecosystem","ecosystem,","ecosystem.","edit","editor","editor,","editor.","ef","ef\",","ef\",请确保在正确的目录下。","efficiency.","el","element","element)","element,","element.","else!","else'","else).","else,","elsewhere,","email","email/password","email:","empti","empty,","empty.","enabl","encourag","encryption)","end","engin","enough","ensur","ensure:","ensurerolesasync(","ensurerolesasync()","ensurerolesasync(rolemanager);","ensuretestadminasync(","ensuretestadminasync()","ensuretestadminasync(usermanager);","enter","entir","entiti","entities,","entity),","entri","entrypoint","env","environ","environment,","environment:","environments:","equal","equival","eras","erb","erb,在","error","error.","errors),","errors,","especi","establish","ether,","even","event","eventu","everyon","everyone.","everyth","everything'","everything.","everywher","ex","ex)","exactli","examin","exampl","example)","example,","examples),","except","exception.","execut","execution,","exercis","exist","exists,","exiting,","exotic.","expect","experi","experience.","experiment,","expert!","explain","explan","explanation:","explicit","explicitli","explor","explore,","express","extens","extension)","extension).","extension.","extern","extra","extrem","f#).","f1","f5","facebook","facebook,","fact","fact,","factor","fail","failed:","fake","faketodoitemservic","faketodoitemservice,","faketodoitemservice.c","faketodoitemservice.cs,并创建一个新文件:","faketodoitemservice。","faketodoitemservice。因为服务是从服务容器里“注入(injected)”的,这个模式被称为","faketodoitemservice,其中包含硬编码的","faketodoitemservice,或者是其它读写数据库的类,或者别的什么类。只要它符合该接口的要求,控制器就能工作。这使你可以轻而易举地,独立测试程序的各部分。(我会在","fakeus","fakeuser);","fals","false)","false),","false;","false。你后面会编写代码,在用户在视图里点击某个条目的复选框时,修改这个属性为","false。如果该操作因为某些原因失败了,act","false)","false:","familiar","fantast","far","fast,","fast.","faster","favorit","favorite,","featur","features.","federation),","feel","feel.","few","field","file","file),","file,","file.","file:","filename,","files)","files,","files.","files:","filter","final","finally,","find","finds.","fine)","fine).","fine.","finish","finished:","finishes.","first","first,","first.","first:","firstasync","fit","fit.","fix","fixed,","fixes,","fixture)","fixture.client;","flag","flag,","flag:","flavor","fledg","flexibl","flow","focu","focus","folder","folder).","folder.","folder:","follow","foocontrol","footer","for=\"title\"","for=\"title\",让","forc","foreach","forgeri","forgot","form","form'","form,","form.","form.submit();","form:","format","format,","format:","former","forms,","form:","fortunately,","forward","found","found.","framework","framework).","framework,","framework?","free","free,","freeli","frequent","friendli","from=build","front","frontend","fuel","full","full,","function","function(e)","functionality,","functionality.","futur","future.","g","game.","gather","gems,","gems,或者","gener","generation,","get","get;","getincompleteitemsasync","getincompleteitemsasync(","getincompleteitemsasync()","getincompleteitemsasync(),","getincompleteitemsasync();","getincompleteitemsasync(),就该修改","getter","getuserasync()","git","github","github'","github:","github:","gitignor","git(使用","give","given.","global","global.asax","global.asax.","go","go!","go,","go.","goe","gone,","good","good,","good?","googl","grab","graph","graph).","great","great,","great.","greek","ground","group","group):","guess","guessed,","gui,","guid","guid,","guid.","guid.empty)","guid.empty.","guid.empty。如果这种情况发生,act","guid.newguid();","guids)","guid。这项功能得益于你在表单里加入的那个名为","guid(或者guid)是一个由字母和数字组成的长长的字符串,看起来是这样的","guid,则","guid,或者说是","gut","hackish)","halfway","hand","hand,","handl","handlebar","handlebars,","handlebars、pug、razor","happen","happens!)","happi","hard","harder","hash","hash:","hasn't","have","have.","have?","haven't","header","hear","hell\"","hello","help","helper","helper.","helpers.","helper。在视图被渲染之前,asp.net","helper,可以参考位于","here","here'","here,","here.","here:","hey,","hibern","hidden","higher.","highli","histori","hold","home","home!","home:","homecontrol","homecontroller,就是你访问","hood","hood,","hood.","hope","host","host)","host.","host.run();","host.services.createscope())","hostnam","however,","href","html","html,","html.","html.partialasync","html.partialasync(\"_adminactionspartial\")","html.partialasync(\"_loginpartial\")","html.partialasync(\"additempartial\",","html。这些","html,偶尔掺杂一点","html:","http","http://+:80","http://docs.asp.net","http://kestrel:80.","http://kestrel:80;","http://kestrel:80。(你马上就会知道为什么要使用","http://localhost","http://localhost:5000","http://localhost:5000.","http://localhost:5000/manageus","http://localhost:5000/manageusers.","http://localhost:5000/todo","http://localhost:5000/todo,","http://localhost:5000/todo.","http://localhost:5000/todo。硬编码的那些条目不见了,你的程序对数据库发起了真正的查询。数据库里刚好还没有任何已存的","http://localhost:5000/todo,但如果导航栏上有一个","http://localhost:5000。你将看到","http://localhost:8080","http://localhost(不是","http://mytodoapp.azurewebsites.net","http://yourappname.azurewebsites.net","httpclient","httpmethod.get,","httprequestmessage(","https(tls),避免在","https://creativecommons.org/licenses/by/4.0/","https://docs.asp.net","https://docs.asp.net)","https://docs.asp.net.","https://docs.asp.net)有几个示例可以参考。","https://docs.asp.net,其中包含了一些有关这些主题的,深入详尽的教程。本人强烈推荐。","https://en.wikipedia.org/wiki/futures_and_promis","https://github.com/aspnet/announcements/issues/295","https://github.com/azure/azur","https://github.com/nbarbettini/littl","https://nate@mytodoapp.scm.azurewebsites.net/mytodoapp.git","https://twitter.com/nbarbettini","https://www.github.com/nbarbettini/littl","https://www.nuget.org).","https://www.nuget.org)。你可以在网页上检索","https://www.recaffeinate.co","https://www.recaffeinate.co.","httpstatuscode.redirect,","https,只需寥寥数行代码即可。本章主要关注安全性的","huge.","human","humanizer'","humanizer.","humanizer。","humans.","hundr","i'd","i'll","i'm","iactionresult","iactionresult,","iactionresult,并标记为","iclassfixtur","icon","id","id)","id);","id,","id.","id:","idea","idea.)","idea:","ideally,","ideas.","ident","identifier.","identity,","identity.","identity:","identity?","identitydbcontext","identityrole(constants.administratorrole));","identity(一个验证和身份系统,属于","identity,为项目添加安全及认证等特性。","identity:你免费获得随模板而来的大量代码,易于上手。对于进阶的情形,你依然需要写一部分代码,并维护一个数据库以存储用户信息。","idispos","ids.","ids:","id、一个标题或者名称、该事项是否已经完成,以及截至日期是什么时候。每行定义了这个类的一个属性:","id,","id,以便你的控制器代码辨别是哪个复选框被选中了。(如果没有它,你只能知道","id,以防止恶意的用户通过猜测","id:","ignor","ignored.","ii","iis,","imag","image,","image:","imagin","imagine.","implement","implement.","import","important!","improv","improvements.","in)","in,","in.","includ","included,","incom","incomplet","incomplete.","increment","incrementing.","index","index()","index.","indic","individu","individual认证","individual验证","info","inform","information,","information.","information:","init","initi","initializeasync(","initializeasync()","initializedatabase():","initializedatabase(host);","initializedatabase(iwebhost","inject","injected.","injection)。","injection,","injection.","inner","input","insid","inside)","inspir","instal","installed)","installing,","instanc","instead","instead,","instead.","instruct","instructions,","instructions.","integer)作为数据库记录的标识,但你需要在数据库里配置,以便这个数字在添加新条目的时候始终增长。因为","integr","intellig","intend","interact","intercept","interest","interfac","interface,","interface.","interface:","interfaces,","intermedi","intern","internet","interpret","interpreter.","introduc","introduct","introduction.","invalid","involv","io","is).","is,","is.","is:","is?\"","isadmin","isbn:","isdon","iserviceprovid","iserviceprovider(在startup.configureservices()方法中设置过的服务集合)从","isinroleasync()","isinroleasync().","isn't","iso","isol","issu","it!","it'","it'd","it'll","it,","it.","it:","item","item'","item)","item,","item.","item.\"","item.\");","item.dueat;","item.isdon","item.isdone);","item.title);","item1","item1,","item2","item:","items)","items,","items.","items:","items;","itemsindatabas","itemsindatabase);","items,直接返回查询结果(跟原来功能一样):","itodoitemservic","itodoitemservice,","itodoitemservice.","itodoitemservice:","itself","itself,","itself.","itself.)","jade、pug","java","java,","javascript","javascript)","javascript,","javascript.","jennifer,","jennifer,她总是支持我各种疯狂的点子。","job","jqueri","jquery(一个","jquery,便于你快捷地创建一个","json","juggl","katana","keep","kept","kestrel","kestrel,","kestrel.","kestrel:","kestrel:kestrel","kestrel。但强烈建议你在","kestrel。这两个容器显式地链接在一起,所以它们可以互相通信。","keyword","keyword!","kitabı","know","know.","knowledg","known","l","languag","language,","languages,","languages:","laravel,","larg","large,","larger","larger,","last","later","later).","later,","later.","later.)","latest","latter","latter.","layer","layer,","layer.","layer:","layers:","layout","layout,","layout:","learn","learn.","learn:","left","legacy,","less","let","let'","letter","level","level.","librari","libraries,","library)","license,","license.","lifecycl","lifecycle.","lifecycles)","lifecycles,","lightbulb","lightweight","like,","like.","like:","limit","line","line).","line,","line.","line:","lines:","link","linkedin","links:","linq","linq(languag","linter","linux","linux,","linux.","linux(和","list","list\";","list.","list:","listen","littl","live","live.","load","local","localhost:5000/hom","localhost:5000/home/about","localhost:5000/home/contact","locat","lock","log","logged.","logger","logger.logerror(ex,","logic","logic).","logic,","logic.","login","login,","login.","long","long,","longer","look","loop","lot","love","low","ls","luck.","m","mac","mac,","machin","machine,","machine.","machines).","made","magic","main","main()","main():","main(string[]","mainli","maintain","major","make","malici","manag","manager;","manageuserscontrol","manageuserscontroller(","manageusersviewmodel","mani","manual","map","mapper","mapper)","margin","margin.","margin:","mark","markcompleted()","markcompleted(checkbox)","markcompleted(e.target);","markdon","markdone(guid","markdoneasync","markdoneasync(","markdoneasync()","markdoneasync(guid","markdoneasync:","markdone:","massiv","master","match","matt","matter","matur","maven).","maven)上有成千上万的软件包。有现成的包可用来完成","mean","meantime,","measur","measure,","memori","memory)","memory,","mention","menu","messag","message.","message:","metadata","method","method'","method)","method,","method.","method:","methods).","methods,","methods:","microservic","microservices.","microsoft","microsoft'","microsoft.aspnetcore.al","microsoft.aspnetcore.authorization;","microsoft.aspnetcore.hosting;","microsoft.aspnetcore.ident","microsoft.aspnetcore.identity;","microsoft.aspnetcore.mvc;","microsoft.aspnetcore.testhost","microsoft.aspnetcore.testhost;","microsoft.aspnetcore.testhost:","microsoft.entityframeworkcore;","microsoft.extensions.configuration;","microsoft.extensions.dependencyinjection;","microsoft/dotnet:2.0","middlewar","middleware,","middleware.","migrat","migration,","migration.","migration:","migrationbuilder)","migrationbuilder.addforeignkey","migrationbuilder.createtable(","migrationbuilder.dropforeignkey","migrationbuilder.droptable(","migrations,","millisecond","minifi","minute).","minute.","mirror","miss","missing:","mit","mkdir","mobil","mock","mode","mode.","model","model).","model,","model.","model.administrators)","model.everyone)","model.item","model.items)","model.items,","model:","models,","models/manageusersviewmodel.c","models/todoitem.c","models/todoviewmodel.c","modelst","modelstate。取而代之,你可以直接检查","modelstate(模型核验的结果)是否有效。习惯上,这种核验都在","models、views,和","model)","model)。","modern","modif","modifi","module)","moment.)","mongo","mongo.","mongodb,","more","more)","more,","more.","more:","moustaches,","moustaches,在","move","much","much.","multi","multilingu","multipl","multithread","mv","mvc","mvc)","mvc,","mvc.","mvc、视图模板和依赖注入。你将使用","mvc基础","mvc(model","mvc(模型","mvc,那你在","mv)发送到用户的浏览器。因为他们都可以被称为模型,我将称后者为","mysql","mysql,","mysql,就不需要这样(有点旁门左道的)绕弯了。","mytodoapp","mytodoapp)在","n","name","name,","name.","name:","namespac","namespace)","namespace),","namespace,","namespace.","naming,","nate","nate!","nate'","nate@barbettini.com.","nate!我在一个漫长的灌着咖啡的周末写了这本","nativ","navbar","navbar,","navbar.","navig","necessarili","necessary.","need","need.","needed.","needs,","netcoreapp2.0","network","network)","never","new","new!","new,","new.","newer","newitem","newitem)","newitem);","newitem,","newitem.dueat","newitem.id","newitem.isdon","newitem.titl","newitem.userid","newtodoitem)","newtodoitem),仅用于这个","next","next,","nginx","nginx)","nginx).","nginx.conf","nginx/dockerfil","nginx/nginx.conf","nginx:","nginx,用","nice","nicer","ninject","ninject。整个框架已经针对速度和运行时效率进行了优化。","node,","node.j","node.js.","node/express,","node、python、ruby、go","none","normal","normally,","nosql","nosql数据库","nosql(文档)","not),","not,","note","notepad,","noth","notic","now","now\"?","now).","now,","now.","npm","npm).","npm,","npm、rubi","nuget","nuget(.net","null","null)","null,","nullable,","nullable.","null——如果找不到。","null。无论如何,做个明智的检查都没错,以防万一嘛。如果用户信息没找到,你可以用","null,设置","number","numbers,","n级架构。在某些情况下,这些层级被隔离在完全分离的项目中,也有时候这仅仅意味着各个类之间组织和调用的方式。重点在于考量如何把你的程序分割成多个可管理的部分,以避免控制器或者某些臃肿的类试图去处理所有事情。","o","oauth","obj","object","object\"","object'","object)”","object)(dto)。这个模式常见于更大更复杂的项目。","obviou","occasion","occur","occurred.","of.","offici","offset","often,","often.","ok","okta","ok和404","old","older","on","on).","on.","on:","onc","once.","one)","one.","one.)","only.","onmodelcreating(modelbuild","open","open,","openid","oper","operation,","operation.","oppos","opposite:","optim","option","optional.","options)","options.usesqlite(","options:","order","organ","organized,","origin","orm","orms.","orm。","orm,其中有一个由微软开发,并默认包含在","os","out","out.","output","outsid","over","over,","overal","overflow","overrid","owin/katana","own","own.","p","packag","package,","package.json","package.json),你不需要经常手动编辑这个文件。","package:","packagerefer","packagereference,引用了","packages,","packages.","page","page,","page.","page:","page?","pages.","pair","panel","paramet","parameter,","parameter.","parameter?","paranoid","parent","pars","part","parti","partial","particular","pass","passed:","password","password.","passwords,","past","path","pattern","pattern.","pattern:","patterns)","paus","pdf","pdf,","pdf、电子书,或者打印版,请查阅官网(littleasp.net/book,中文版为","peek","peopl","per","perform","performed,","period!","permiss","persist","pick","picker","piec","pieces,","pipelin","pipeline.","place","placehold","plan","plan.","plan:","platform","player","pleas","plenti","plu","plugin","pluralsight","pluralsight.","plus,","poco.","poco。","point","point,","point.","polyglot","popular","port","port)","portal,","ports:","possibl","possible,","possible.","post","postfix","postgresql,","power","powershel","powershell)。一路","powershell),并使用","practic","practices.","pre","prefer","prefer,","prefix","present","press","pretti","prevent","previou","price","print","privat","pro","probabl","problem","problem:","problems,","problems.","problems:","process","processes,","procrastinating).","produc","product","product,","program","program!","program,","program.","program.c","programm","programming,","progression:","project","project'","project,","project.","project:","projects),","projects,","projects.","promis","promise,","promise1,这里使用它的原因是,这将是个","prompt","proper","properly.","properly:","properti","properties.","property.","property:","protect","protocol","provid","provider,","provider。","provider。因为整个数据库都存在于内存里,每次测试重新开始的时候,他就会被清空。并且,因为这是个合乎规格的","provider,todoitemservic","provider,然后对","proxi","proxy.","proxy_cache_bypass","proxy_http_vers","proxy_pass","proxy_set_head","public","publish","publish.","pug,","pull","purpos","push","put","python,","queri","query)","query),","question","question,","quick","quickli","quickly.","quickly:","quit","quot","rail","rails,","rails、django、laravel","raman","ran","random","randomly,","rare","rates,","raw","razor","razor)","razor,应该会注意到一些语法的差异。生成一个指向","re","reach","react","read","read/writ","readabl","readable:","readers.","readi","readonli","real","realiz","realli","reason","reason,","reasons,","rebuild","receiv","recip","recipe,","recipe.","recommend","recommended,","recovery,","red","redirect","redirecttoaction(\"index\");","redis,","redistribut","reduc","refactor","refer","reference?)","reflect","refresh","refreshed.","regardless","region.","regist","registr","registration,","relat","releas","release.","reli","rememb","remix","remot","remote:","remov","renam","render","rendered,","rendered.","reopen","repeat","repeatedli","replac","repo","repo,","repositori","repository:","repres","request","request.","requested.","requests,","request。","requir","required.","research","reserved.","reset","reset,","resourc","responds.","respons","response.headers.location.tostring());","response.statuscode);","rest","restart","restarted.","restor","restrict","result","result)","retriev","return","return;","reus","revers","rework","rewrit","rich","right","right,","right:","rm","rogu","role","role.","rolemanag","rolemanager)","rolemanager.createasync(","roll","root","root,","root:","rout","route,","route.","routing),","routing,","row","row.","rubi","ruby,","ruby.","ruby。asp.net","rule","rules.","run","run,","run.","running:","runtim","runtime,","run。如果代码通过编译而没有报错,服务器将在默认的","run,它一步就完成了这些事情。)","safe","sahinyanlik","same","sample,","sanit","saniti","save","savechangesasync()","savechangesasync().","saved,","saveresult","saw","say","scaffold","scale","scan","scenario","scenarios,","scenes.","scope","scope,","scope.","scope.serviceprovider;","scoped)","scoped)。我会在","scratch!","screen","screen).","screen.","sdk","sdk,","sdk.","sdk。完成","sdk,包括运行时,基础库以及用于构建","sdk,需要手动安装","search","second","second)","section.","section:","sections.","secur","secure!","securely,","security.","security:","see","see,","see.","see:","seed","seeddata","seeddata.c","seeddata.initializeasync()","seeddata.initializeasync(services).wait();","seeddata:","seeddata:","seem","select","semicolon","send","sens","sensit","sent","sentenc","separ","separate.","separately.","sequenc","seriously,","serv","server","server,","server.","server_nam","servers.","server、postgresql","server,mysql,mongodb,redis,或者什么其它稀奇古怪的玩意儿。这个模型定义了数据库里的行或者记录在","servic","service,","service.","service.additemasync(new","services)","services,","services.","services.adddbcontext(opt","services.addmvc","services.addmvc();","services.addscoped();","services.addsingleton();","services/faketodoitemservice.c","services/itodoitemservice.c","services/todoitemservic","services/todoitemservice.c","set","set;","set;,","set;}","setter","setup","sha","share","share,","shift","ship","short","shortcut","shorter,","shorthand","should,","show","shut","side","sign","signalr","signatur","signature)","signature))。该方法不需要任何参数,并且返回一个","signature.","significantli","signinmanag","silli","similar","simpl","simple.","simpli","simplicity,","simplifi","simplifies)","simul","singl","single,","singleordefaultasync()","singleton","singleton.","site","site.","site.css","site.j","skill","skip","skipped.","skipped:","sku","slower","small","small,","small.","smaller","social","solut","solv","someon","someth","sometim","sound","sourc","special","specif","specifically,","specify.","speed","speed.","spend","spin","spit","splash","split","sport","spring,","sql","sqlite","sqlite)","sql注入","squigg","squiggl","squiggli","stack","stack.","stackoverflow","stamp","standard","standard.","start","start,","started.","started:","starting:","startup","startup.","startup.c","startup.configureservices()","statement","statement,","statement:","static","statu","stay","step","step,","step.","step.)","steps.","steps:","stick","still","stop","store","stream","streamlin","string","string,","string.","structur","structure:","structuremap","stuck.","studio","studio).","studio,","studio),下面这几个有益的小技巧将帮你轻松上手:","studio,你需要直接打开","stuff","style","style!","style.css","stylesheet","subdirectori","sublime,","submit","subscript","subscription,","succe","succeeded:","success","successful,","successful.","successfulli","such","suggest","suggests,","super","suppli","support","support.","sure","surfac","swap","switch","symbol.","sync,","syntax","system","system,","system.","system.collections.generic;","system.componentmodel.dataannotations;","system.io;","system.linq;","system.net.http;","system.net;","system.threading.tasks;","system.web,","system.web、iis、和","system;","systems,","t","tabl","table)","table,","table.column(nullable:","table.primarykey(\"pk_items\",","tables).","tag","tag,","take","talk","task","task),","task),所以必须执行一次","task,","task.","task.fromresult(new[]","task?","tasks,","tasks.","task”的意思是说,该方法不能立刻给出一个结果,但是你可以使用关键字","task。","task。“返回一个","task,代替之前的","task,就必须使用","tax","teach","team","technic","technically,","technolog","technology.","tell","templat","template).","template,","template:","templates,","temporari","ten,","termin","terminal,","terminal.","terminal:","test","test,","test.","testadmin","testadmin,","testfixtur","testfixture()","testfixture:","testing.","testing?","testing?,","tests)","tests,","tests.","tests:","testserv","testserver(builder);","testserver,","testserver,并使测试代码干净利索。","test,如果一切工作顺利,你会看到这样的成功信息:","text","text.","thank","that'","that,","them.","them:","themselv","themselves.","then,","there!","there'","there:","they'll","they'v","thing","thing):","thing.","things:","think","think:","third","this,","this:","thorough","those","thoughts.","thousand","three","three,","through","through;","throughout","thymeleaf","ti","tidy.","tier","time","time,","time.","time:","times,","times.","timestamp","timezon","timezones.","tini","tip","titl","to,","to.","to:","toarrayasync","todo","todo/index.cshtml","todo:","todoconteol","todocontrol","todocontroller(itodoitemservic","todocontroller,","todocontroller.","todocontroller:","todocontroller)类创建一个新的实例的时候被调用。在构造函数中加入的","todocontroller,你必须提供一个能匹配","todocontroller,当控制器需要一个itodoitemservic","todocontroller,添加一些代码以使用","todoitem","todoitem())","todoitem)","todoitem:","todoitem[]","todoitems\".","todoitems.","todoitems:","todoitemservic","todoitemservice(applicationdbcontext","todoitemservice(context);","todoitemservice)","todoitemservice,","todoitemservice.","todoitemservice:","todoitemservice;","todoitemserviceshould","todoitem,以一个空条目初始化该表单。(请尝试添加{","todorouteshould","todorouteshould(testfixtur","todorouteshould:","todoviewmodel","todoviewmodel()","todoviewmodel,并把该","togeth","together)","token","token.","told","too.","tool","tool,也叫","top","top:","topic,","topics.","total","touch","tr.done","track","trail","transfer","transform","translat","translations.","travel","tri","trick","tricky,","tricky.","true","true)","true),","true,","true/false)。默认情况下,所有新建条目的该值为","true;","true。","truly).","try.","tsv","turn","turn,","tutori","tutorial.","twitter","twitter.","twitter:","twitter发帖,包罗万象。asp.net","twitter(@nbarbettini)上和我保持联系,或者在我的博客上(https://www.recaffeinate.co)。你还可以通过电子邮件(nate@barbettini.com)联系我。","two","two,","type","type?","types,","typic","typo","ubuntu)","ubuntu)都可以搭建成一个","ui","ultim","unawar","under","underli","underscore,","understand","understand,","undo","unfortunately,","uniqu","unit","unittest1.c","unittest1.cs。你已经为第一个测试的编写准备就绪了。","unittest1.cs,这样你就为集成测试的编写准备就绪了。","unless","unlik","until","up","up\")","up(migrationbuild","up.","up:","updat","updated)","updated,","update,重新搭建数据库并应用到到当前的变更。","upgrad","upload","uri(\"http://localhost:8888\");","url","url.","url:","urls:","url,就像你将其应用在一个","url:","url:http://mytodoapp.azurewebsites.net","us","us)地区创建了一个资源组。如果你距离美国西部很远,请使用","us,","used,","used.","user","user'","user)","user);","user,","user.","user.id)","user.id;","userid","usermanag","usermanager)","usermanager.","usermanager.addtoroleasync(","usermanager.createasync(","usermanager.getuserasync(user);","usermanager.isinroleasync(","usermanager.us","usermanager;","usermanager。todoitemservic","usermanager:","usernam","users\"","users\";","users,","users.","using,","usual","utc","utc.","valid","valid.","validated.","validation.","validation)。核验操作检查从传入请求绑定到模型的数据,鉴别其合理性和有效性。你可以在模型中添加属性,告知","validity.","valu","value).","value.","value:","values.","values)。更多信息请参见:https://github.com/aspnet/announcements/issues/295","var","variabl","variable.","variat","veri","verif","verifi","verify)","version","version)","version,","version:","via","videos,","view","view(model);","view),以便在布局中的导航条里添加一个项目:","view,","view.","view:","view?","viewdata[\"title\"]","views,","views.","views/manageus","views/manageusers/index.cshtml","views/shared/_adminactionspartial.cshtml","views/shared/_layout.cshtml","views/shared/_layout.cshtml.","views/shared/_layout.cshtml。","views/todo/additempartial.cshtml","views/todo/index.cshtml","view)","virtual","visit","visual","void","wait","wait()","wait...","want","want,","wasn't","way","way,","way.","we'll","web","web,","webapp","webhostbuilder()","websit","website.","websocket","web应用","web框架(rubi","weekend","welcom","welk","well","well.","went","west","western","westu","what'","whatev","whenev","where()","whether","whole","why?","wide","widnow","winddow","window","windows)","windows).","windows,","windows.","windows、mac","windows、mac、linux上。","windows、mac或者linux上安装的","windows、mac,和","windows,ii","windst","windsting,","windsting.github.io/littl","windsting、yuyi","wipe","wire","within","without","won't","wonder","words,","work","work!","workaround","workaround.","workaround:","workdir","worker_connect","working!","working:","world","world!","world!\");","world\"","world.","world”,就是创建一个待办事项清单应用程序。这是个很棒的练习,麻雀小,五脏俱全,它将涉及","worri","worries!","worry!","worry,","would.","wouldn't","wrap","write","written","wrong).","wrong,","wrote","wwwroot","wwwroot/css","wwwroot/css/site.css","wwwroot/j","wwwroot/js/site.j","x","x.id","x.id);","x.isdon","x.userid","x.usernam","x?\"","xml","xml解析","xml,其中定义了一些关于项目的元数据。到后面,你引用其它包的时候,那些包将被记录在这里(类似于","xunit","xunit.net","xunit;","ye","yet!","yet.","yet:","you!","you'd","you'll","you'r","you'v","you,","you.","your","yourself","yourself,","yourself.","yuyi","zhylich","{","}","});","},","};","},看看会发生什么!)","©","—","——","“amazon","“hello","“回调地狱”,那你现在走运了。在","“截止日期”一栏所展示的日期,这种格式(叫做","↩","、","。dotnet","。你会看到自己创建的视图,展示着(暂时)从伪数据库层提取的数据。","一个","一个用于存储用户待办事项条目的数据库,使用","一个登录及安全检查表单,以便每个用户的待办事项列表都保持私密","一层。(这个目录也叫做","一旦你确定","一旦镜像创建完成,你可以运行","一章讲解。)","一章讲解测试相关的内容。)","一章里说明原因。","一章,深入地使用了整个","一部","万事俱备,只欠东风。当一个良好的程序构建完成,就应该与全世界分享它了。","上","上。在","上。这件事也可以用","上一个","上一章结尾处,待办事项","上一章节里,你在数据库上下文里添加了一个","上传输的数据被窃取","上使用","上发表看法:https://twitter.com/nbarbettini","上就有很多非常精彩(其中某些就是来自于你们读者)。如果你在上面没有账号或者想要一张优惠券,请发信到:nate@barbettini.com。","上必须是全局唯一的。一旦这个应用创建好了,会具有一个以下格式的默认","上有也写一些有关","上有多个","上有着大量的软件包,从","上构建并运行","上的","上的其它属性(isdon","上的教程","上的移动应用也是","上的软件包","上等待访问请求。","上,但我不会过多涉及这个主题。","上,你可能需要把文件名用引号括起来,比如","上,你拥有多种部署程序的方式。这一章里,我将教给你最常用(也是最简单)的上线方式。","下。注意实际的代码(.c","下一步是修改数据库查询,并添加一层过滤,仅显示当前用户创建的条目。但在做这些之前,你需要在数据库里添加一个新的字段。","下一章里,你将使用另一套","下一章,你将在程序中添加更多的功能,从“创建新","下划线开始,但这不是强制性的。","下用","下面是","下面看到红色的波浪线,因为该方法尚未定义。","下,也可以用","不会察觉有什么异样。","不再有区别:控制器可以方便的返回视图、状态码,或者数据。依赖注入功能已经内置了,所以,如果你不想费劲的话,完全可以不用再安装并配置一个服务容器了,比如","不同,那个","不是","不要漏掉结尾那个句点!它告诉","不论你此前在","不论你用什么编辑器或者平台,都需要安装","不论是单元测试还是集成测试,都遵循","与之如出一辙:承诺你,肯定会给出一个结果——在未来的某个时候。","与你先前创建的","与单元测试相比,集成测试在范围上大得多。它检验整个程序栈。集成测试并不会把一个类或组件隔离出来,而是确保你程序的所有组件协作良好,这些组件包括:路由、控制器、服务、数据库访问等等。","与单元测试相比,集成测试较慢,并且涵盖的范围较大,所以,一般来说,一个项目会有大量的单元测试内容,而集成测试的内容则屈指可数。","与数据库交互的代码写起来坑很多。除非你对其了如指掌,否则在程序代码里粘贴","与数据库建立连接。你需要在","与真实的数据库进行交互!","专用的","个容器和","个容器所需要的工作是一样的。","个已登录用户,usermanag","中","中之后的命令都会在这个","中受益,而且已经正常工作了,请试着注册一个账号并用它登录。","中定义的那些程序所需的","中所有的","中有几个惯例(常见的模式),比如这个","中有效:","中注入一个","中添加一个名为","中添加具体的实现:","中用过","中的","中的逻辑,在你的测试项目中创建一个新类:","中获取rolemanager和usermanager。","中,并仅具有特定的字段(title),用于添加新的待办事项条目。模型绑定流程依然要用到,但现在,你分离了两个模型,一个用于在数据库中存储待办事项条目,另一个用于绑定传入的请求数据。这个方案,也被称作","中,这就是","为了向导航栏添加新条目,请先找到原有导航栏的","为了把“数据库上下文中的改动”反映到数据库里,你需要创建一个","为了测试整个程序栈(包括控制器路由),集成测试往往像网络浏览器那样向程序发起","为你完成了很多工作!","为保持各部分独立且组织良好,你应该以","为包含该复选框的行添加","为基础创建你的镜像。这个镜像是微软发布的,其中包含了执行","为服务容器(servic","为测试创建独立的项目是一个良好的实践,以便把它们和你的程序代码分离开。新的测试项目应该被置于你主项目的同级目录(而非在主项目目录内)。","为项目的所有文件创建一个名为","为验证业务逻辑执行的正确性,请在原有的","主机","主视图里引用它:","之前","之前添加一个反向代理,因为","之前,先试着创建并运行一个简单的应用程序吧。","之前,它是唯一的","之类的反向代理服务器,把请求代理到","之类的后端语言写程序,你会注意到很多熟悉的概念,比如","之类的模板语言),它接收传入的数据并展示给用户。模型则保管着数据,要么是准备发送给视图的,要么是用户输入的。","之类的状态码。返回类型","之类的身份提供者的","也为多线程和异步任务作了专门的优化。与使用","也便于把你的应用扩展为多个服务器。一旦你创建了一个镜像,用它来创建","也可以跑在","也能处理这个工作。","习惯上,接口以大写字母“i”开头,在","了。","了吗?它表示","了!","了:","事件。当一个复选框被点击,markcompleted()","二者常被混淆。验证","于镜像中重建这些包,docker","什么是","什么是依赖注入以及它的实用之处","从","从数据库中获取真实内容。","从数据库获取","从服务层获取","从构建伊始就注重安全。它已经自动处理了净化输入数据和跨域伪造请求(csrf),你就不需要操心这些了。你同时还享有","仓库管理,执行下列命令进行设置:","仓库:","代码","代码。","代码创建数据库查询语句,查询结果映射回","代码可以于具体的数据库实现无关,你可以根据底层以来的数据库技术更换不同的","代码块下编写新内容:","代码文件的方式,一般与存放该文件的目录名保持一致(services目录下的文件,命名空间是aspnetcoretodo.services,以此类推)。","代码的支持库。如果你看着这段已经像天书那么晦涩,直接跳到下一章吧。","代码的测试框架,可用于编写单元和集成测试。像其它组件一样,它也是一组nuget","代码补全","代码:","代表数据库里的","以","以下这些很棒的各国程序员,翻译了本书:","以下这些贡献者,提升了这本书的质量:","以交互模式运行这个容器(输出到终端,而不是在后台运行)。当你想要停止这个容器的时候,按","以便停止这个服务器。","以前的版本,直接看下一章去吧!","以及","以怎样的方式进行核验。","以检验你的","以检验结果。","以获取其中的值。","以获取当前用户,如同在","以获取说明。","以调试模式运行项目。这跟命令行的","任何有能力托管","会为该表单生成一个","会从表单里提取信息,并存放到那个","会以","会创建一个","会在","会处理","会将浏览器重定向到路由","会尝试将其解析为一个","会把这些","会自动执行一个称为","会被你创建的","会返回","会返回一个","会连带一个包含","传给它一个","位于","作为","作为主机名。)","作为前缀。","作为复用","作为对比,这里要指出,","作为幕后的实际服务。可能你觉得这是理所当然的,因为你的itodoitemservice仅有这一个实现,但你后面会为同一个接口提供多个实现,所以,有必要明确指定实现。","作为最后一步,你需要在服务层里添加一个方法。首先,在","作为练习,请在这个页面添加更多管理功能特性。例如,添加一个按钮,为管理员提供","作为附加练习,请尝试使用","你修改了","你创建了一个","你只需要执行这些步骤一次。现在开始,任何时候,你需要推送程序文件到","你可以在","你可以在直接在控制器里编写这段数据库相关的代码,但是作为更良好的实践,应该保持你的代码独立。为什么呢?在一个巨大的,现实世界的程序里,你不得不应付一些事情:","你可以在该应用程序第一次启动的时候,将这个","你可以把","你可以用","你可以用类似的规则完全自定义页面的外观和体验。","你可以运行以下指令来启动这个多容器程序:","你可能会纳闷,其余的","你可能有点疑惑,为什么在一个","你可能还会听说","你完全可以自己写一段代码,把一个日期转换成更人性化的字符串,不过幸运的是,还有个更便捷的方法。","你将要构建的这个应用,其完整源码位于","你已经创建了一个模型、一个视图、一个控制器。在你把模型和视图应用于控制器中之前,需要先写点代码,用它把用户的待办事项条目从数据库里取出来。","你应该注意到相同的依赖注入模式,如你在","你惯用的代码编辑器","你搭建项目的时候,应用了","你现在有了测试程序,覆盖了","你现在的目录结构看起来应该是这样:","你的","你的代码就是通过它与数据库交互,进行读写的。data/applicationdbcontext.c","你的目录结构看起来应该是这样:","你的第一个程序","你程序的构建和运行需要些什么。","你需要在","使控制器尽可能保持轻量化,是一个良好的习惯。在当前的情形里,这个控制器应该仅仅完成这些事情:从数据库取出待办事项的记录,把这些事项包装在一个可用于视图的模型中,并把这个视图发送到用户的浏览器。","使用","使用一个布局视图,用以定义容纳视图的基础结构的其余部分。布局视图被保存在","使用列表下面那个简易的表单,用户可以添加新的","使用复选框标记条目完成","使用它,通过","使用数据库","使用这个常量值。","例如,todocontrol","依赖于","依赖于被注入的","依赖图)。","依赖注入(depend","修改","修改、转换或以本作品为基础进行创作,在任何用途下,甚至商业目的。您必须给出适当的署名,提供指向本许可协议的链接。","修改了数据库和数据库上下文,你就可以修改","修改布局","修改数据库","修改数据库上下文","修改服务容器","修改服务类","修改该字段仅仅影响该条目的本地拷贝,savechangesasync()","修改过视图和控制器,剩下的就是要添加缺失的服务方法了。","修正了读者们发现的一些笔误。","倍是很正常的。","借助","偏移量表示的时区。把时期、时间和时区一起保存,有助于在不同时区的系统上准确地显示时间。","做这件事,但是因为某些技术原因,你无法在","像以往一样,asp.net","元素上那样。在本例中,asp","元素中。这意味着你不必硬编码这个指向","元素中的属性","元素包含。然后,添加一个隐藏元素,其中包含条目的","元素是为","元素里,添加一个","元素),改行包含条目的名字和截止日期。还会展示一个带有","元素,你能预见","全局(globally)","关于作者","关心“用户在登录","关心的是用户登录与否,而","关系","内置于","再检视一次","再通过","写一个服务测试","写到数据库里去。)","写的代码相比,执行速度高出","写过页面,那你就已经了解其基本概念了.)","冲突,在","准备好创建你的第一个","准备材料","几乎任何东西:日期、时间、时长、数字等等。它是个很好很有用的开源项目,根据","出于显而易见的安全因素,对于任何人来说,都不能自主的注册成为一个管理员账号。事实上,administr","出于某种原因无效,浏览器会被重定向到路由","出来的其它类,以便在一个时时刻专注在一个点上。","出现并把","函数就被执行。","函数的功能如下:","分别映射到如下的","列表里。因为这些条目存储在数据库里,就算你关闭程序后再重新运行,这些条目都还保存在那里。","列表里添加条目,这功能很棒,但无论如何,这些事项都得被处理掉。在","则不复存在了。整个处理管线由中间件驱动,mvc","创作共用署名4.0国际许可证","创建","创建一个","创建一个名为views/manageusers的文件夹和一个视图:","创建一个接口","创建一个新的","创建一个新项目,这一次添加几个选项:","创建一个测试用的管理员账号","创建一个测试项目","创建一个简单但实用的","创建一个虚拟机,在上面安装","创建一个镜像","创建变更","创建变更的最后一步,就是要应用它(们)到数据库中:","创建控制器","创建服务类","创建模型","创建的项目文件包含一条指向microsoft.aspnetcore.all软件包的引用,这是个便捷的“元软件包(metapackage)”,它引用了你在项目中所需的所有其它","创建视图","创建部署配置文件","初次发布。","删除","删除一个用户","删除文件","删除自动创建的文件","判断用户是否已经登录。如果没有登录,其余的代码就都被跳过。如果这","别担心,就算对","到","到上一层的","到了此","到剪切板,并把它在本地仓库里添加为一个","到屏幕上。这个程序由两个文件构成:一个项目文件(使用","到新目录里之后,就只需要运行这个项目了:","到要放置你项目的路径下,比如你的“我的文档”目录:","前它尚未被保存。如果保存操作成功,savechangesasync()","前端代码(html、css、javascript)怎样与后端代码交互","前缀,使方法名构成一个可读性良好的句子,不过你可以按自己的意愿选择命名风格。","前言","前面的","功能性","功能相同,但有一个额外好处——你可以在代码编辑器的左边栏上点击,以设置一个断点:","包","包。在添加其它代码","包含三个","包含在","包里带来的,它把这个方法标记为一个测试方法。","包,可以被安装在任何项目中(并且包括在默认的模板中了)。","包,可被安装在任意项目中","单元测试","单元测试是短小的测试,检查单个方法或类的行为。当你测试的代码依赖其它方法或类时,单元测试依赖于","单页面应用,例如","博客","即是包管理工具,也是官方的软件包仓库(位于","却已久经考验。在","去查找(并验证)那个隐藏的验证标记,就是由","去查看运行在容器中的程序。","去监听","参数了,修改","参数传给了","参数使用,","参数指示","参数的方式了吗?这是你在","参数缺失了,或者无法解析为一个","参数,表示你做出如下声明:要创建一个","又一个","又有什么可取之处呢?","又比","及以上的版本(免费的社区版就够用了)。visual","反向代理","反向代理配对工作。(下面有更详细的","反序列化、数据库连接、pdf生成,或者几乎你能想到的任何需求。","发布。您可以自由地:共享","发行版(例如","发起一个调用:","取决于该条目添加到数据库的结果成功与否,additemasync","取出所有过滤后的数据,并作为一个数组返回。toarrayasync","变更","变更(migration)。","变更按时间记录着数据库结构的变化。它们使以下的操作成为可能:撤销(回滚)一部分修改,或创建一个新的数据库——与原有数据库结构一致。有了变更,你有一个完整的数据库历史,记录着对数据库的修改,例如添加或删除字段(以及整个表)。","变更记录","变量里。","另一方面,当你写单元测试的时候,你需要自己处理这个依赖图。典刑的做法是,提供这些依赖的","只返回某个特定用户的条目","只需要简单几步。你可以通过","可以优化镜像生成过程并使它容量紧凑。","可以在","可以连接到","可用服务集合","可空(nullable),或者说是可选的。如果不加这个","可能初出茅庐,但","可读/可写(read/write)(或者,更确切地说,它有","后","后面会提示你保存解决方案文件,你应该把它保存在根目录(第一个","向","向用户展示待办事项列表的视图了。","向视图添加表单元素","吧。","听起来心动吗?那就整起来吧!你要是还没按上一章所讲,用","启动时读取的配置信息。你可以用它来保存数据库连接字符串,或者其它你不想硬编码的任何内容。","启动程序并导航至","启动程序(如果你用的是","启动程序,并以普通用户身份登录,尝试去访问一下","命令再次被用到,以选择一个较小的镜像,其中仅含有运行程序所需的依赖。env","命令列出你本地电脑上的全部镜像。要通过容器尝试一下,请执行:","命令创建一个新的项目:","命令创建一个镜像:","命令创建了一个基本的","命令创建的。","命令在当前的项目里查找测试方法(本例中,由","命令查看一个变更的列表。","命令用于容器中的设置环境变量,环境变量","命令确认它已经安装了)","命令给","命令编译项目,而","命令获取一个地点列表,并找出距离你比较近的一个。","命令行工具里实施。我会讲解后者。","命令行工具(command","命令重建在","命令,应该看到如下的内容:","和","和其它主题的博文。","和密码进行登录的功能。","和很多其它语言编程的支持非常丰富。只需要搜索“下载","和模型类。","唯一(unique)","嗨,我是","回到","回调函数,task","回顾","因为","因为initializeasync()返回一个","因为你的目录结构里存在多个项目(web项目和两个测试项目),azur","因为控制器使用了","因为这个文件(在命名空间aspnetcoretodo.services中)引用了","因为这是一个接口,所以不包含任何实现相关的代码,只有","因此,视图模型应该是一个独立的类,里面包含着一个","在","在initializeasync()方法下面再添加两个方法,第一个,ensurerolesasync()方法:","在任何媒介以任何形式复制、发行本作品,演绎","在命名空间","在哪儿?asp.net","在当前目录下查找","在控制器里添加","在控制器里添加一个新的","在数据库中创建","在数据库中按","在文件顶端,@model","在文件顶部添加这条","在服务层添加代码,对数据库进行修改","在本章开头,我提到过,你应该使用一个","在本章里,你将学习如何编写","在本项目里,asp.net","在构造函数的下方,为","在模型绑定流程中,模型里的任何属性,如果不能匹配到请求里的字段,都会被忽略掉。由于表单里仅包含一个","在此项目中,你将添加一个","在每次集成测试执行之前,需要进行一些配置。为免配置相关的代码把测试代码弄的乱七八糟,你可以把配置相关的内容提取到一个独立的类里。创建一个名为","在用户访问你程序中某些特定内容时,你通常都会要求他们登录。比如说,把主页向所有人展示是合理的(不管你有没有登录),但只在登录之后才向你展示待办事项列表。","在程序中使用身份","在程序根目录,也就是最外层的","在终端窗口运行","在终端窗口,运行以下命令(请确保你位于","在网络应用里,角色是用于处理","在视图中使用","在视图里查看认证状态","在视图里添加一个","在这一章,你将探究","在这个新的项目目录里,你会发现多出来几个文件。在你","在这里添加","在项目的","在项目的根目录创建一个新类,取名为","在项目的目录里,用","基于云的身份鉴别服务:这种服务既处理简单情况也处理复杂情况(多步验证、账号找回,),并且能极大地缩减你需要编写的代码量,和维护程序的工作量。另外,用户数据的敏感部分并不会保存在你的数据库里。","基础","填充(seeding)","增添了一些新工具,并复用(及简化)了你用过的那些东西。我将在后续章节指出部分差异。","处理和调整传入的请求、提供静态内容和错误页面。在这里,你还可以向依赖注入容器中添加你自己的服务(后面细说)。","处理用户账号的存储、散列并保存密码、还负责管理用户的角色。它支持","处理这个表单","复制这个","复选框被选中了,而无法知道是哪个。)","外加某种","多。","多数较大的项目使用一种","多级","多重身份认证流程","多,后者的","大幅度重写了","天”这样,不是更好吗?","头字段为一个已知的有效值(known","好了,前言就到这儿。开始学习","好了,当一个请求进来,将会被发送到","好了,现在模型也有了,是时候创建一个接收","如何添加","如何进行数据库的读写操作","如何部署该应用程序到网络上","如你所见,dotnet","如果","如果传入一个不存在的","如果你不使用","如果你不在意","如果你不想用","如果你从没用过","如果你使用","如果你使用完善的数据库,如","如果你使用的代码编辑器了解","如果你刚开始编程,本书将在“构建最新web应用”方面,使你了解其中的模式和概念。你将以从无到有、循序渐进的方式,学习构建一个","如果你在","如果你在老式","如果你在顶层目录里执行","如果你已经在使用诸如","如果你已经有一个现存的数据库,请在网络上搜索“scaffold","如果你已经被这些命名搞糊涂了,别发愁!咱们马上就要写代码进行实践了。","如果你当前在你项目目录里,向上","如果你想回滚数据库,你可以提供","如果你愿意,也可以修改之前创建的","如果你愿意,可以把单元测试和集成测试放置在同一个项目里。对大型项目而言,通常会把它们分开,以便于它们各自独立运行。","如果你打开","如果你打开一个变更文件,可以看到两个方法,名字分别是","如果你把程序托管在","如果你按原样执行变更,会遭遇","如果你是一个","如果你是初次使用","如果你更喜欢通过视频学习,在","如果你此刻位于项目目录,cd","如果你浏览项目文件","如果你现在立刻运行你的程序,复选框还是没什么作用,因为没有提交按钮通知浏览器,让它根据表单数据构建一个","如果你现在运行程序并注册或者登录,你将又一次见到一个空的","如果你用其它开发语言写过","如果你用的是","如果你用管理员账号登录,将在右上角见到一个新的导航项:","如果你的","如果你的网络浏览器没自动弹出来,打开它,浏览","如果你看到类似于上面的输出,就大步前进吧。","如果你看到这样的报错:","如果你还在","如果你还没在文件顶部添加","如果在","如果当前用户已经登录,","如果想使这个方法变简短一点,你可以删除中间变量","如果数据库里不存在一个用户名为","如果要深入学习,以下这些方式可供参考:","如果这种语法让你看上去感到困惑,就这么理解:“一个","如果需要与你自己的代码做对比,可任意下载。","字段","字段上的","字段服务的。","字段的对象,返回","字段,可以确保用户必须已经登录","字符串可以没有值,也可以是空白字符串或者包含任意文本。","存入和取出数据库中的数据。","安全和身份","安全性","安全性与身份","安全性是任何现代","安装软件包","完成事项","完成控制器","完成这种操作。","完整的","官方的","官网的提示内容。要检验是否安装成功,可以执行:","定制样式表","实体。","实体上添加一个新的属性,让每个条目都能够“记住”拥有它的用户:","实体模型上所做的修改:","实体,你需要修改数据库上下文,并对数据库进行变更。","实现了","容器的","容器的机器都能用来托管","容器监听","容器自己也需要一个","容器)里,你可以用","宿主。例如,你可以用亚马逊","宿主机上作为容器启动起来就行了。","密码重置","对","对当前这个项目而言,你将把程序分为两个层:一个由控制器和视图构成的","对表单也很有用(你会在后续章节明白原委)。要学习其它的","对象","对象(plain","对象。经由","将变更应用到数据库时","将幸福地对这个变化毫无察觉,但在底层,你将使用","将有能力缓存这些重建的包。然后,当你修改代码(而没修改项目文件中定义的包)时,重建这个","将用于在视图中改写日期,你可以直接在视图里使用它。首先在视图顶端添加一个","小贴士:","就像一个数据库上的大型接口。你的","就是常见的范例)以及","就是广为人知的","就被用于查找用户详细信息,并用","就让浏览器重定向到","尽管可以径直浏览","尽管属性的名字是授权(authorize),我们在这里检查的其实是认证(authorization),而非检查授权,很抱歉会有这样的混淆。","局部视图就这样创建好了。然后,要在","局部视图(partial","属性","属性。在本例中,会生成一个指向路由","属性中获取当前登录的用户——该属性在当前的","属性到该复选框,避免它再次被点击","属性告知","属性就持有一个轻量级的对象,包括了用户的一些(并非全部)信息。usermanag","属性就是小事一桩了:","属性应该被设置为用户的","属性是","属性是一个","属性是一个字符串,用于保存待办事项的名称或者简述。","属性标记出来),然后运行它找到的所有测试,你会看到类似这样的输出:","属性没有标记为可空,所以是必须的,并可以确保始终有值(或者是一个缺省值)。","属性添加可空标记。c#","属性确保了见到","属性让控制器里执行认证操作变得很方便,但是如果你需要在视图里进行认证操作呢?比如,在导航条上为登入的管理员用户显示一个“管理用户”的链接。","属性进行访问。","属性选择一个(可选的)日期。然后,用这个日期替换那个默认的“3天后到期”。","属性里加入","属性,currentus","属性,从而导致待办事项视图对所有人可见。","属性,可以让","属性,要求用户在访问指定的","属性:","工具的文档,以此对你的数据库进行逆向工程,自动地为数据库结构生成相应的","工具,原因请参考","已经从","已经保存好了,然后用","已经包括了你所需的一切。","已经在configureservic","已经由","已经被翻译成其它语言:","布尔值(值为","布局文件","带有你创建它时候的时间戳。","带来的身份系统,就像","帮助你添加诸如","并上传你的项目文件即可。下一节,我会介绍通过","并不具有负载均衡和其它更成熟的","并不知道该把哪个发布出去。为解决这个问题,在你的目录结构顶层创建一个名为","并且","并为其它字段设置缺省值。然后,这个新条目被加入到数据库上下文中。在调用","并以","并作为","并刷新页面。","并在导航条部分添加:","并处理接收的数据:你的控制器已经处理好了。","并执行","并把这个","并按照提示在你的电脑上登录,然后,为这个程序创建一个新的","并未关联到特定的用户。现在,[authorize]","并浏览","并添加这些行:","并监听","并非添加身份鉴别的唯一方式。另外一种选择是使用诸如","库。","应用、api、微服务","应用。","应用。你将学习如何通过前后端代码实现设计目标,如何与数据库交互,如何部署应用到真实环境。","应用了么?先做点“利其器”的事:","应用变更","应用或","应用的方法(以及合理组织各模块的方法)。对于你在编程方面所需的内容,本书不能事无巨细的涵盖,但它可以作为一个起点,引导你了解更高级的内容。","应用程序。当然,只要你愿意,你可以使用自己的","应用程序。这需要用到","应用程序服务器(有时也被称为“后端”),使用","应用程序的命令行工具。它可以安装在","应用程序的部分。","应用:","应该把服务绑定到哪个网卡和端口上(本例中时","底层以请求为单位管数据库连接。要避免这些问题,请在跟","开发服务器。你每次运行","开发者注意","开发者,将如鱼得水。","开启你的网络浏览器,浏览","开始之前","开始之前,需要在你的开发机上安装","异步(async)","异步的(asynchronous)","当一个有效的条目被标记为完成状态,","当你再次启动程序,admin@todo.loc","当你把程序部署到生产环境,你应该添加","当你编写代码访问数据库或者外部","当某个用户在你刚刚创建的表单里点击","当程序运转正常的时候,","当视图中的","彻底的重写,重点关注于:让该框架应用新的开发方法,并最终使其与","待办事项","待办事项:","待办事项。现在你有了数据库上下文,就可以创建一个新的服务类,从而借助","待办事项列表。糟糕的是,你尝试添加的任何条目也都会凭空消失,因为你还没修改","待办事项列表依然由所有用户共享,因为","待办事项条目","待办事项条目。为了能存储","待办事项条目,所以页面目前还是空白的。","待办事项视图","很快。因为","得到一个","循环运行并为每个待办事项条目显示一行,每一行都会包含此表单的一个副本。隐藏的输入框包含该","微服务","微软的","微软的开发团队很注重安全性,asp.net","快捷编译:使用快捷键","感谢你读完了这本简明","感谢你选择这本","感谢那些多语言的投稿者,简明","我们需要创建两个独立的模型类:一个模型表示保存在数据库里的条目(有时候也称为一个","我在自己的博客","我更喜欢用","我的待办事项","我的文档","或","或以上版本的","或整个控制器时,要事先登录过。要为","或者","或者任何你喜欢的编辑器。如果你还没有一个惯用的,请试试","或者其它语言里使用过","或者说","所有其它地方你都应该用","所覆盖的广度)。比如","手册","手册!如果这本书有点(或者没有)用处,我很乐于倾听您的想法。请在","手册!我写这本小书的目的,是帮助","手册,因为我热爱","才初次安装完成,运行:","打交道的服务上,始终采用","打交道,这一章将教你基础知识,带你上道。","打包和压缩静态资源","打开一个浏览器并导航至","打开文件夹。打开","打开项目的根文件夹","托管的","托管的程序。如果你用的是","执行","执行业务逻辑,或者说跟你程序的目标和“业务”相关联的代码与逻辑。在一个待办事项列表程序里,业务逻辑意味着“为新任务设置一个默认的截止时间”,或者“仅显示未完成的任务”这些决策。业务逻辑的其它例子,包括“基于产品价格和税率计算总价”,或者“在游戏里检查一个玩家是否有足够的经验值升级”。","扩展名。","扩展名。)","扩展名)和一个","扩展名),打开前面那个文件的话,可以看到以下内容:","找出页面上的所有复选框,将一些代码关联到其","技巧","把","把下面这行添加到configureservices中的任意位置:","把代码暂停在","把你的","把你的服务作为","把接到的请求转发到","把条目置于","把程序以这种方式分割,有时被称为","把程序文件推送到","把这个方法翻译成一个类似的语句","把项目文件部署到","拒绝访问","指令以反映最新的优秀实践。修正了笔误,添加了来自读者的建议。还弄了个新改良的封面得瑟了一下!","指令创建一个新的变更:","指令后的分号。修正中文版译者信息。修正其它笔误和读者反馈的问题。","指令告诉","指令复制","指令应用到数据库:","指令运行这个程序,在代码编译完成之后,你将看到输出在控制台里面的内容:","指令默认会用","指令,在项目的根目录下生成了小型的","指令,并验证及限定","指出了在被运行的时候去执行","指定","指定所用的","指定的模板带给你预先构建好的视图和控制器,用以处理这些常见情景,以便你快速上手和运行。","指示","按","按惯例,通常把局部视图的名字以","按提示创建密码。然后用","按角色进行授权","授权","接下来又依赖于","接下来是","接下来,为部署工作创建一个","接下来,你需要提醒你的程序,在它启动的时候,执行这个逻辑。修改program.cs,并更新main()去调用一个新的方法initializedatabase():","接下来,使用","接下来,创建一个","接下来,创建一个新目录以保存你的整个项目,然后进到该目录里:","接下来,创建一个视图模型:","接下来,在你刚刚创建的组里,创建一个","接下来,控制器调用到服务层,进行实际的数据库操作,保存这个新的待办事项条目:","接下来,控制器需要调用服务层去修改数据库。这个功能,将要由","接下来,添加这一行:","接受一个","接口中的一个新方法","接口了:","接口如此有用的原因就在于,因为它们有助于解耦(分离)你程序里的逻辑。既然这个控制器依赖于","接口的对象。","接口的那一行:","接口里添加它的定义:","接口(interface),在接口中,一个对象中方法和属性的定义与实际包含这些方法和属性的类分离开来。接口有助于解耦你的那些类,也有助于测试,如你接下来(以及在后续的","接口,也就同样需要修改","接口,但你还没告诉","接口,但总是返回这个包含两个","接口,而不是任何","控制器使用查找到的信息创建模型,并使之与一个视图绑定","控制器接收请求,到数据库查找所需资料","控制器里对这两个方法的修改:","控制器(mvc,model","控制器,model","控制器,而要改为指向","推向","提交该表单","提供了一个上佳的替代品:testserv","提示你安装缺失的文件,点击“是”以添加它们。","提示认证","提示:f1","搜索“下载","搞定!","搞定!请用两个不同的账号尝试一下。待办事项条目现在是每个账户的私密信息了。","搭建","操作","操作上,而后,在底层数据库或者网络请求结束时,从暂停的地方恢复执行。就是说,你的程序并没有卡住或者阻塞住,因为它可以处理其它的请求。如果现在想不通也别担心,跟着做下去就行!","支持多个不同类型的数据库,并允许你使用","改写","攻击。在你编写这个","数据传输对象(data","数据库(必须地呀)","数据库。","数据库上下文","数据库上下文(databas","数据库上下文、连接字符串","数据库上下文、连接字符串和数据库类型。感谢项目模板:","数据库上下文这边所需的工作不多:","数据库协作。在本项目的开发过程中,你将使用一个","数据库和上下文都已就绪。接下来,你将在服务层使用上下文。","数据库已经配置好待用了。但是还没有表用于保存","数据库引擎和一个被称为","数据库文件","数据库的","数据库的名字","数据库的局限性带来的问题,要修复它,可以这样绕开:","数据库,以简化安装和配置的工作。","数量,比","整体架构会包括两个容器:一个","文件","文件夹内执行,该文件夹是上一步的","文件夹里,创建一个名为","文件夹(根目录),不是内层的项目目录。如果","文件夹)。你也可以在","文件用以忽略","文件的底部添加以下这些","文件里为你设置好了:","文件里包含着","文件里,就保存着一个很基本的数据库上下文。","文件)并未复制到镜像里。你稍后即可弄清个中缘由。","文件,设置","文件:","文档","文档位于","文档(https://docs.asp.net)和","断言——arrang","断言一个日期时间值有点棘手,因为比较两个日期值的时候,就算是只有毫秒部分不同,两个值也是不等的。替代方案是,检查","新功能提交","新建","新条目应该总是从现在开始3天后过期","新条目应该总是未完成状态(isdon","新条目的标题应该复制自","方案。如果想在你的应用上使用自己指定的域名,请使用","方案里创建一个","方案:","方法。如果你需要完整的抹掉数据库并重新开始,运行","方法。换句话说,这个方法可能不会即时返回待办事项的列表,因为它需要先查询数据库。(详情见后续章节。)","方法。首先,该方法接受一个名为","方法中为","方法中使用","方法中的","方法以确保它在应用程序启动前完成。你一般是用","方法会返回","方法使用一个","方法刚好相反:当你需要撤销(回滚)变更时,item","方法取出存储的条目,然后断言其中的属性被设置了预期的值。","方法可以返回视图、json数据,或者","方法各一个)。","方法吩咐","方法和其中的","方法在数据库里查找该用户的详细信息。","方法将会被执行。因为你在数据库上下文里添加了一个","方法强制用户再次登录:","方法来自","方法的代码。首先,它用数据库上下文中的","方法的代码,使用","方法的定义(或者叫","方法的签名,以返回一个","方法的签名:","方法的顶部添加了新代码,这行代码用","方法签名(method","方法要么返回该条目(若存在),要么返回","方法负责的是把东西添加到","方法返回一个","方法里使用该服务(具体方法,稍后便知)。","方法里注释掉或删除","方法里的","方法里被添加到服务容器里,所以在这里可以直接使用。","方法里配置itodoitemservic","方法里,在当前情况里,应该这么写:","方法里,构造一个","方法里,(通过你声明的那个私有变量)使用","方法(index,about,和","方法,并遗漏了某些以上的业务逻辑。你程序的行为,会在你意识不到的情况下变掉!你有办法避免这个情况,方法是编写一个测试,用以复核这些业务逻辑并未发生变化(就算是该方法的内部实现已经发生了变化)。","方法:","方面:管理用户的账号(注册、登录),安全地验证用户(登录),并在验证后做出授权决策。","无论你连接本地文件数据库(sqlite)还是位于其它主机的数据库,都需要定义一个字符串,其中包含","既有现成的","既然","既然你修改了数据库上下文里的实体模型,就应该同步修改数据库。在终端窗口里用","既然你没使用","既然你现在把一个","既然测试项目要使用你主项目中的类,你需要添加一个引用指向主项目:","既然这个测试项目要用到主项目中的类,你需要添加一个引用指向主项目:","日期/时间","日期)将为空,或者包含着一个默认值。","时,asp.net","时,考虑到安全性的因素","映射(object","映射到","是","是一个仅关注数据库操作(不处理业务逻辑)的类。咱们眼下的程序里,为简化操作,我们将把这些混进一个服务层里,不过你尽可尝试采用不同的方式去架构你的代码。","是一个常用的针对","是一个平台无关的接口,它定义了特性和","是一个由微软创建的,用于构建","是一个轻量级数据库引擎,可以运行在你的机器上而不必安装任何额外工具,所以在开发环境下使用起来既方便又快捷。","是个帮助你创建并运行多容器程序的工具。这个配置文件定义了两个容器:","是什么?","是免费的","是另一个","是可在","是在问:“我知道这个用户是谁吗?”,而","是对","是异步的(返回一个","是最常见的选择,我在本书中也会采用它。你可以在","是现在的建议的方式,而不是使用","是编译运行的,执行速度远高于解释执行的语言,比如","是随机生产的,所以就你不必再担心这个","是随机的,并极少会有重复值,所以常被用作唯一标识。你也可以用数字(整形","更多的bug修正和一些小改进。添加译版的链接。","更容易(也更便宜),不过你要是愿意自己管理","更深入的学习","替换成真正的","最后一步,让我们来完成控制器的编码。控制器现在已经从","最后一行创建了一个新的名为","最后,toarrayasync","最后,为","最后,修改","最开始的地方进行。","最终,如果一切顺利,浏览器会被重定向到","最终,如果操作顺利完成,action","有三个组件:模型、视图、和控制器。控制器处理从客户端浏览器传入的请求,并选定相应的代码进行处理。视图就是模板(一般是","有两个依赖:","有助于实现这些功能。前两个(防止sql注入和跨域攻击)功能已经内置了,要开启","有很多不同的方法可以命名和组织测试,它们都有着各自的优缺点。我喜欢给测试类加上","有着优秀的","服务器","服务器和","服务器所具有的其它特性。","服务器接收从互联网上传入的请求,并派发到你用","服务器(这包括亚马逊的","服务器,并在端口","服务器,这也是个可行的方案。","服务容器","服务层","服务层。表示层已经有了,所以,接下来就应该构建一个服务,用来处理","服务的时候,task","服务,为此你可以搜索","本书的目标读者","本章总结","机器学习","条目","条目就更好了。要达成这个目的,你可以去编辑共享的布局文件。","条目:","来做。","来初始化你的","来实现,它会根据操作成功与否,返回","来配置内存数据库的","构建","构造函数(constructor)。构造函数是一个特殊的方法,它会在为(本例中是","架构:一个表示层,一个逻辑服务层,一个数据仓储层。仓储(repository)","某个","查找一个条目。singleordefaultasync()","查询子句也需要检查用户的","查询子句了:","查询字符串就是个糟糕的决定。一个","标准","标准中的","标准并不等同于任何实际的代码或者功能,仅仅是","标准现存多个不同的“版本”或者说级别,反映出提供","标签上,应用","标签,或者","标记,dueat","标识会将结果输出到一个名为","标识告诉","标识符(identifier).","样式规则:","框架。io","框架。它使用常见的模式,诸如","框架并移除了","框架选项已经很多了:node/express、spring、rubi","框架)的知识。我会偶尔提及","框架,需求何在?","模型","模型。当它在这里作为一个","模型一起使用。它促成了以下功能,在","模型代表单一的一个数据库里的条目,而视图则需要展示两个、十个,甚至是一百个待办事项(取决于用户拖延症的病情轻重)。","模型核验操作(model","模型的替代方案,还可以创建一个独立的模型(比如叫","模型绑定","模型绑定/核验","模型绑定流程会查看请求内的数据,并试图智能地把输入的字段和模型里的属性匹配起来。换句话说,当用户提交这个表单,并且浏览器","模型绑定流程,就没有用于有效性检查的","模型(poco)。","模式。移除","模式是很常见的,因为在数据库(或者网络)响应之前,它不可能给出实际的结果。如果你在","模式的基本内容","模板为你生成了多个文件和目录。在默认创建的基本内容里,这几个是最重要的:","模板仓库(https://github.com/github/gitignore)里的","模板创建了一个新的项目,并添加了一些额外的验证和安全性相关的内容。(关于安全性的内容,我会在","模板在布局文件中包含了","模板就很好用。","模板语言编写,这种模板语言混合了","正如你可能已经猜到的那样,你需要在","正如其名字所示,mvc","此方法查看数据库里是否存在一个","此方法获取seeddata.initializeasync()所需的服务集合,然后执行它以便初始化数据库。如果出现错误,将会记录一条错误日志。","每个属性后面都跟着","注意一下,这个文件的命名空间是","注意到","注释替换掉:","测试)较大,模拟实际的应用场景,并检验你程序里的多个层次或组件。","测试一下","测试专用","测试是个宽泛的话题,还有很多东西需要学习。本章节没有涉及","测试的编写在构建任何程序时都很重要。测试代码有助于发现及避免","测试,也没有对前端(javascript)代码进行测试——它本身可能就需要一整本书去讲述。不过,你应该已经掌握了一些基本的技能和知识,可用于实践并学习更多相关测试程序的编写。","深入钻研","添加","添加一个","添加一个日期选择框,并让用户为","添加一个服务类","添加一个服务类去跟","添加一个表单","添加你的条目,不要指向","添加到","添加到服务容器里,并通过配置(appsettings.json)中的","添加到表单里的那个标记。在处理","添加外来软件包","添加新特性","添加服务方法","添加服务方法(函数)","添加条目","添加用户管理页面","添加认证提示,在这个控制器的第一行上面添加这个属性:","添加这一功能。在本例中,你还要写一丁点","添加这个功能,需要几个步骤:","添加进服务容器。这意味着,只有一个faketodoitemservice的实例被创建,并在每次被请求的时候都被复用。在后面,当你写另一个服务去跟数据库交互时,你会采用一个不同的方式(叫做","清单创建","渲染视图","源文件(带有","潜在问题的小灯泡提示:如果你的代码里有红色波浪线(编译错误),把编辑的光标放在红线里,到左边栏里找那个小灯泡的图标,小灯泡的提示信息会给出常见问题的修改建议,比如在代码里添加一个","点击这个复选框(还)不会导致任何结果。像上一章节一样,你要通过表单和","然后运行","然后,where","然后,修改那行写着","然后,在","然后,在main()的下面添加这个新方法:","版本。这意味着你可以把正在测试的类或者方法的逻辑隔离出来。(这很重要!如果你在测试一个服务,显然不应该一失手","版的","特别致谢","特定的","现在上下文和数据库不同步了,因为数据库里实际上并不存在","现在你(真的)可以开始编写集成测试了。创建一个名为","现在接口已经定义好,你可开始创建具体的服务类了。在后续的","现在,你借助","现在,你终于可以在","现在,在这个","现在,就到了复制其余代码并编译程序的时候了:","现在,日期的可读性大大提高了:","现在,暂且不必关心底层数据库采用的是哪种实现。它可以是","现在,程序里包含一个单一、共享的待办事项列表。如果它为每个用户保存独立的列表,将会更有用。下一章,你将使用","现在,请在","现存的","生命周期。","生态","生态圈中的其它部分,它也是一组","生成的视图,需要从视图模型(一个待办事项的数组)获取数据,并用一个适当的表格展示给用户。按规定,视图要置于","用","用一个","用了一个模型作为参数,还进行了","用于","用于过滤出所有“未完成”的条目:","用于这种类型保存一个","用户名和密码,","用户点击一个按钮或者提交一个表单,从而发送一个新的请求给控制器,重复整个处理流程","用户管理","用来连接的数据库地址。","由","由于","由于你删除了","由控制器本身处理的路由叫","电脑的","登录、多重身份验证、集成以","登录、注册","登录、注册功能,以及如何提升安全性","登录以简化安全章节、流水线式的测试和部署。修改了","登录时的安全性","百度,试试","的","的一个变种。","的一部分)之上。安装后,默认添加了通过","的业务逻辑,并把待办事项条目保存到数据库里去。","的人一定登录过,在查询数据库的时候,你就可以按照登录者的身份进行过滤了。","的代码。(如果你在","的代码重构,且略优于","的代码:首个代码块检查","的传承,","的值将是","的值绝不应该是","的值距离期望值小于一秒。","的值,以判断它的有效性。如果出于某些原因,请求中的","的内存数据库","的内容组织成了一篇教程。你将从头开始,完整地构建一个应用程序,同时了解以下内容:","的列表,它应该把这些条目放进一个","的功能。","的包管理系统,类似","的参数,","的变更,它将给","的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。","的同时会在表单里添加一个隐藏字段,其中包含一个验证标记。该验证标记可用于防止","的名字加上一个","的处理。如果传入的请求中包括一个名为","的处理流程。","的处理管线。在","的复选框,可以在后续操作中把该条目标记为已完成。","的安装后,开启一个终端窗口(或者","的官方文档(位于","的定义。.net","的实现,它只能运行在","的小类以保存它的值:","的局限性","的属性获取","的布局文件里面存放着所有视图的“基础”html。其中就包括导航栏,它被显示在每个页面的顶端。","的常见方法。例如,通常会为管理员创建一个","的引用。这个变量可以让你在后面的","的形式创建这个表单。局部视图是较大视图的一个小片段,存放于一个独立的文件。","的待办事项,并通知服务将其存储到(内存)数据库里。","的快速轻量级的","的情况下。(如果你还不熟悉,别担心!我会在后面逐步介绍。)","的戳记和一个与","的指示进行安装)","的操作,并把用户信息存储到条目里:","的效果一样。","的数组”。","的数组。你可以用它去测试控制器和视图,然后在","的数组:","的数量(或者说","的文件:","的文档。","的文档非常适合用来学习这些特性。","的新","的方式进行贡献。","的方法把其他用户的事项标记为完成状态。","的方法里,使用","的时候创建并应用的。","的时候,会验证这个标记。","的时候,你会看到一系列的日志信息。","的时候,用的就是这个服务器。当你把程序部署到生产环境的时候,它仍会在幕后使用","的时候,设置","的时候,这是个重要的安全措施,你的用户可能被欺骗,以至于在一个恶意的网站上提交数据。这里的验证标记被用于确保呈现和提交表单的,是你的程序。","的替代品","的服务容器和依赖注入系统在","的框架。","的模型核验器,如果标题缺失或为空,则判定其无效。看一下","的模型绑定器设置,所以,这个方法仅需要分配","的模式,其应用几乎遍及所有的","的模式,还有","的测试范围。作为一个补充练习,请写出单元测试以确保:","的深度教程(请搜索“digitalocean","的特性,它受到函数式编程的启发,简化了在程序代码里数据库查询的写法。在底层,entiti","的生命周期把你的服务添加到容器里。这意味着每次","的用户,这个方法将创建它并给它一个临时的密码。在你初次登录之后,就应该改为一个更安全的密码。","的目录。进入到这个新目录里:","的目录里。","的真实地址取代:","的类(一种代码结构或模块)里。最上面的","的类,却产生了一个小问题:","的类:","的系统),编写代码与数据库进行交互。","的系统创建","的网上门户实施,也可以在","的能力”开始。","的表里保存","的解释器。有几种语言(c#,visual","的语法,你会在","的说法是服务的集合。","的路由。而是","的那些类,以便在你的这个类里使用它们。","的问题了。","的隐藏元素。","的页面,你将看到一个列表,列出了本程序的所有注册用户。","的默认)端口上进行监听,并把请求转发到由","目前的重点就是修改","目录。这个顶层或者说“根”目录可以容纳一个或多个项目目录。根目录有时候被称为","目录下新建一个文件:","目录下,创建一个名为","目录找到文件","目录里弄另一个","目录里放着","目录里,在一个与所属控制器同名的子目录下。视图文件的文件名就是","目录里,已经预置了几个控制器,其中有渲染默认欢迎页的","目录):","目录,你将会看到:","目录,使用以下命令搭建一个新项目:","目录:","直接注入到视图里来进行这些操作。为保持你视图整洁有序,创建一个新的局部视图(partial","相关信息的","相关内容。)","相匹配)。","看一下","看到","看到的那个页面。暂时不用管这些控制器。","看起来是这样的:","知晓该","知道,你需要在一个名为","确保","确保你把这个文件保存为","确保用户","示例的那个目录里,请退回到","社交账号登录、以及借助","社区,并希望以我的微薄之力付出回报。希望它帮助你学了一点儿新东西。","祝你代码敲得愉快!","程序。","程序。c#","程序。一般来说,部署到","程序。创建","程序。单元测试较小,用来确保单个方法或者逻辑块工作良好。集成测试(有时候也叫","程序上。","程序展示的","程序所需的全部!下一节,你将把同样的流程应用在一个","程序托管工作的细节,而只希望参考分步的指导,可以跳转到后续两小节的任一个继续阅读。","程序提供原生的支持。如果你有一个","程序根目录新建一个目录:","程序的入口点方法,按照惯例,会被置于一个叫","程序的根目录,创建","程序的默认欢迎页面,说明你的程序工作正常!看够了这个页面之后,在终端窗口内按下","程序能够运行在","程序部署到","程序部署到你自己服务器上的工作。不再需要浪费时间在一个服务器上配置你程序所需的依赖、复制文件、重启进程,你只需要创建一个","程序里常见的模式是:","程序,它输出文本","窗口,以便代码完成功能在新项目里生效。","章节,","章节中创建的那个,用于存储一个","章节中)所见。你将用一个接口来表示一个服务,该服务负责就待办事项条目事宜与数据库交互。","章节所见到的那样,只是这次被注入的服务是","端口上运行。","端口吗?这里的","端口映射到","端口的容器。","端口)。","端口,把请求转发到另一个运行着","笔误修正和一些读者建议的改进。","第一个变更文件(00_createidentityschema.cs),是在你执行","第一个验证步骤是个明智的检查:内存数据库里保存的条目绝不会超过一条。假设这个检查通过了,测试会使用","等协议连接到其它的服务。","等等。这是个良好的测试点,因为它确保你不会意外地弄丢了","等等,数不胜数。asp.net","简明","管理你的源码,眼下就是一个适合的时机,在项目目录下用","类","类。这个类能够在测试期间托管你的程序,并在测试完成之后自动关闭它。","类型参数。参数","类型后面那个问号","类型类似于一个","类成了起始和中心,application_start","类提供的数据库入口点。","类的","类的新实例就会被创建出来。这对于那些跟数据库打交道的类来说,是必要的。","类里的","类里,你可以添加中间件,它们用于","类(在命名空间","类,它就不知道也不必关心实际使用的是哪个具体的类。它可以是","类,就需要修改","类,这个类会基于","系统。","系统内部依赖的(你可以试试,把这行代码注释掉)。你在应用里所需的任何其它服务,也都要在这个地方添加到服务容器里。","练习内容","练习里的","经由","绑定模型(bind","绑定:","结束语","绕开","给了你足够的灵活性,以返回上面提到的任意一个。","给待办清单功能创建一个新的控制器,取名叫","绝大多数视图代码就是","继续编码这个控制器之前,你需要创建","编写集成测试","编程开发者以及爱好者了解","编程方面经验如何,本书都会倾囊相授,足够你借助","编程语言里有一个概念叫","编译出来的文件启动你的程序。(当你在开发时运行","编译器的静态类型检测的优势,它像个时刻警惕着,还有些强迫症的审校者。这样,在使用一个变量或者某些数据时,那些无意识的错误就插翅难逃了。","编译程序所需的工具和依赖。以这个预编译镜像为基础,docker","缺陷修复","网络应用。如果你本地目录尚未作为一个","网络服务器托管","而既然你修改了","胜利在望!你已经让","能否做某些事”。你可以认为","自动为你生成。","自动化测试","自增","自己处理安全性:不推荐,除非你是一个安全性方面的专家!","自身,在表象之下,也只不过是添加到你项目里的一个","获取","获取到一个","著","虚拟机(jvm)或者","虚拟机)上托管程序。通常把","虚拟机,也有关于搭建和运行","虚构","虚构(mocking)","表","表。","表单","表将会被丢弃。","表新添一个列,以反映你在","表示层,用来处理用户的交互,和一个包含了业务逻辑和数据库代码的","表(其列与","被一个构造函数(或其它什么地方)被请求,就用这个","被分配了","被创建时,把这些对象逐一地注入到依赖图里。","被称为","被调用之后才会把修改的内容持久化到数据库里。savechangesasync()","要在主布局中包含这个局部视图,编辑","要在代码里使用一个软件包,你通常需要在文件顶端添加一个","要声明(或者“关联”)具体的类到每个接口上,需要写在","要执行一个集成测试,你也可以启动程序,并手动向http://localhost:5000发起请求。不过,asp.net","要把它加入到你的项目里,在终端窗口运行这个命令:","要编写一个单元测试来检验","规则,改变该行的外观","视图","视图。","视图。文件顶部的","视图和前端代码就这样搞定了。是时候添加一个新","视图在用户的浏览器里渲染并呈现","视图模型","视图模型(view","视图里,为每个待办事项条目显示了一个复选框:","视图:","角色。如果没有,它就创建一个。为免反复地输入字符串","角色。请尝试用这个账号登录,并浏览位于","角色外加一个测试用的管理员账号添加到数据库中。向数据库添加初始数据的行为,被称为初始化,或者","角色才能查看这个页面。","角色,相对于普通用户,他们拥有更多的权限和能力。","解决了这种问题,它提供的方法可以“人性化(humanize)”","解决方案目录。后面,你将会在","解耦。你要是还记得","订阅(免费的订阅就可以了)","订阅,你只要创建一个","让我们仔细探究","让我们逐行分析这个","让用户通过她们的浏览器进行交互的网页和界面(也被称为“前端”),使用html、css、javascript创建","让项目使用了","记录(entity)),另一个模型将与视图结合(mvc里的","许可","许可证发布。","许可证开放源码,就是说,源代码可以自由获取,并且欢迎社区成员以","设想一下,如果你或者其他什么人重构了这个","设置","设计","译","译者注:二者都是其它语言中,与异步编程相关的概念,它们是用于指代某个尚未就绪的值的对象。而这个值,往往是某个计算过程的结果。要了解详细,请参考","译者注:如果你使用","试着运行程序并在未登录的情况下访问","试试看","该方法使用","该方法在把新条目真正存入数据库之前,做了多个判断与假设(换句话说,在新条目上执行了业务逻辑):","该视图要绑定到哪个模型。模型通过","详尽的设置指令超出了这本书的范畴,但是任何较新的","详情请访问:https://creativecommons.org/licenses/by/4.0/deed.zh","语句:","语句。","语句以符号","语句将遍历到每个代办事项,并渲染成一个表格的行(","语句引入了","语句添加到文件顶部:","语句,以导入该软件包的内容。","语句,你会看到这样的报错:","语句,引入那个命名空间。如果不写这个","语句,现在加上:","语句,用以从视图模型里抽取数据并转换为文本或者","语句:","请求。","请求。你可以在每个复选框下面添加一个提交按钮,但这样的用户体验太蠢了。理想的方法是,点击复选框的时候,能够自动地提交该表单。你可以添加一些","请求中,一个","请求到你应用程序的","请求数据绑定到模型后,asp.net","请确保你添加了一个","贯穿本书,你将学习有关","资源","资源组(resourc","跟","跟依附代码打交道要容易得多,这归功于神奇的关键字","跨站请求伪造(cross","跨站请求伪造(csrf)","路径。你会见到这样的","身份验证(identity)","软件包(一个叫","软件包。这样,你就不必在项目文件里添加数百个软件包的引用了。","软件包集合。","软件包,以获取协助,来完成几乎任何能想到的任务和难题。","软件包,并在自己的机器上使用终端(或者","辅助库),通过","输入密码","输出结束之后,浏览","达成这一点。","迁移的名称:dotnet","过滤器。","过滤输入数据,避免","运用依赖注入","运用数据库","运行","运行在微软的","运行时库。","运行时库。它在各个操作系统上,使用对应的平台相关代码,实现了定义于","运行时库上,类似于","运行时,这个用于运行","运行测试","运行程序并勾选列表中的某些条目完成掉。刷新页面,它们将自动消失掉,这归功于","运行程序,使用页面上的表单添加几个条目到","运行编译任务,这跟","运行(并调试断点):使你的项目处于打开状态,按下","返回","返回一个整数,表示在这次保存操作中被更新的条目的数量。在当前的情况下,它要么是1(条目更新了),要么是0(有错误发生)。","还可以通过","还是那句话,把所有这些东西写进一个单独的巨大的控制器是可行的,但这很快就会变得难以管理和测试。相反,常见的程序都把这些分割成两个、三个或更多的“层”或级,每个层级处理(且仅处理)一件事情。这有助于保持控制器尽量简单,并简化测试工作,以及后续的业务逻辑和数据库代码的修改。","还有很多值得研究的内容,让我们着手构建这个应用吧!","还有很多其它功能,例如密码重置以及社交账户登录。位于","还有很多功能,但是无法纳入到这本小册子里,包括:","还有更多功能,比如部分视图和后端渲染的视图组件,但你现在只需要一个简单的布局和视图。想要了解更多的内容,asp.net","还要在文件顶部加一个新的","还记得创建服务接口以解耦控制器和服务的实现类吗?entiti","还记得吗?","还记得环境变量","还进行了","还需要创建一个文件,回到","还需要添加","这一行告知","这一行的存在,此局部视图在被渲染的时候,期望被传入一个","这一行给类定义了一个","这一项已经在","这两个","这两个服务方法现在也必须接受","这个","这个可以在命令行下执行。首先开启一个终端窗口(或者","这个命令在美国西部(west","这个命令新建了一个名为","这个命令,使用","这个局部视图首先使用","这个应用的名称(上面的","这个测试发起一个匿名(未登录)的请求到路径","这个程序不再打印到控制台后直接退出,而是启动了一个","这个类定义了每个待办事项都要保存的内容:一个","这个类的第一行声明了一个私有变量,保存","这个类配置好了一个","这个表。(对数据库上下文代码的修改,并不会改变数据库本身。)","这个角色。","这个角色,在数据库中尚不存在。","这个账号会被创建并被赋予","这个路由。如果你现在去尝试,asp.net","这个配置文件告诉","这些也可以用在","这些命令必须在项目的根目录下执行(program.cs所在目录)。","这些安全及身份鉴别的特性到程序里。dotnet","这些目录。","这些编译好的文件,将会通过这最终的几条命令,运行起这个程序:","这些都默认包括在了所有","这些静态资源。wwwroot","这将运行所有迟于你指定变更的","这就是构建一个","这指示","这是个很适合集成测试的使用场景,因为它涵盖了程序的多个组件:路由系统、控制器、控制器被标记了","这是因为注册用户不会自动获得","这本","这本书本身也会由于修订和内容的增加而频繁更新。如果你阅读的是","这条","这条命令会导致","这样的前端","这样的容器化技术能极大地简化把","这样的平台,像","这段代码先使用","这段代码把","这种","这种云端的服务为你的程序处理身份验证。你可以把这些选项看作发展的各个环节:","这种关系型数据库,也可以与","这种情形——你意识不到自己改变了业务逻辑,虽然现在看起来好像不会发生,但是在一个更大更复杂的项目中,这会因为各种决策和假设而变得难以追踪。在越大的项目中,确保业务逻辑稳定的自动化检查就越重要。","这种成熟的生态系统,其最大的优势之一,就是第三方软件包和插件的量非常庞大。正如其它的软件包系统一样,你可以下载并安装","这行代码通过检查你在数据库上下文里所做的修改,创建了一个新的变更,名为","这行添加了一些服务,它们是","进行反向代理。","进行编程,但跟你熟知的内容相去不远。","进行认证检查。如果所有检查都通过了,并且该用户是一个管理员,导航条上就会加入一个","进行部署","连接到了数据库,就为“给程序添加更多新特性”做好准备了。首先是这个功能:使用一个表单,添加新的待办事项条目。","连接字符串","连接数据库","连接数据库,需要做一些准备工作。因为你通过","选定了编辑器,就该去获取","选择了一个命令行应用(一种向屏幕输出文本的程序)的模板。","选择你的语言阅读","选择诸如","选项指示","选项,移除","选项,获取你所在平台更详细的信息:","通常会部署到下列环境之一:","通常,你保存在数据库里的模型(实体),跟你在","通读本书,你将构建一个待办清单应用,允许用户添加待办项,并在事项完成之后勾掉它。具体来说,你将创建的是:","通过","通过社交媒体授权","速度","那一节,我会讲述如何配置","那个方式,依然可以在任意","那些内容,你就已经学会一半了:","那些行。","那章添加真正的代码去访问数据库。","那章,我会深入讲解有关数据库的代码,但目前你可以造个假,直接返回硬编码的值:","那行告知","邮箱地址/密码","部署到","部署方式","部署程序","都是用于了解更多知识以及遇到问题时查找答案的好资源。","都要重点关注的。确保用户或顾客的数据安全并免遭黑客染指,是非常重要的。这个话题所涉甚广,包括了:","里。你可以用它在","里使用","里使用模板直接创建","里包含一个名为","里定义的接口:","里将如鱼得水。如果你是初次跟","里应付过","里提交它们,然后运行:","里有一些待办事项条目,则","里有个占位符,代表","里查找并自动给出","里查找当前用户:","里添加一个","里用的模型(视图模型)非常相似,但又不尽相同。在现在的情形下,","里的","里的一个名为","里的一个等效查询。","里的图形界面)安装它们。","里的所有","里的文件将作为静态内容,自动被打包和压缩。","里的视图使用","里省略。如果你有需要,可以自定义这些行为,不过就目前的情况,让我们暂且遵循这些惯例。","里看起来是什么样的,所以你无须在代码层面担心数据库层面的东西。这种模型简单的风格被称为“朴实可爱的","里那样。","里面添加实现:","里面的","里面的实现方法。在","里面装着一个","里,你可以使用","里,你同样需要在文件顶部添加一个","里,或者","里,添加一个名为","里,选择","链接。","链接的时候,tag","错误。","镜像将会非常迅速。","镜像是个非常快捷的部署程序的方式,尤其是在你熟悉","镜像,里面包含你程序运行所需的一切,然后在任何","问的是:“这个用户有权限做某件事吗?”","防止利用表单(form)进行的跨域(csrf)攻击","附加资源","集合。创建一个名为","集合。既然现在数据库上下文里包括了一个集合(或者说表),而数据库里没有它,你就需要创建一个变更来修改数据库:","集成测试","需要一个","需要完整、详尽的变更记录,可以到:","非常简单,这跟","非常适合。对于更复杂的项目,我建议对各选项都作一些研究和尝试,以便找到你所需的最佳方案。","页脚","页面","页面,仅对管理员们可见。如果普通用户试图访问它,将会看到错误提示。","页面:","页首","项目","项目。","项目。参数","项目。那你应该现在就创建并运行那个项目,直到看见默认的欢迎页面为止。","项目中。","项目成了","项目文件到镜像里的路径","项目文件基于","项目文件所在的目录。","项目模板中的","项目模板,该模板中带有几个类,构建在","项目模板,这些准备已经就绪了:","项目的各部分","项目的根目录里要有一个部署配置文件","项目目录边上添加多个项目目录,它们全都在一个单一的根解决方案目录里。","项目,操作是","顺带","首先需要的就是一个","首先,修改视图,并用让每个复选框都被一个","首先,创建一个新控制器:","首先,在","首先,在接口定义中添加","验证","默认创建的文件","默认的","(http","(orm)在你的代码和数据库之间添加一个抽象层,并以此简化了与数据库交互代码的编写。java","(web","(及以上列表的内容)一无所知,也不妨碍你学下去。",",只需要在",",在控制器类里用方法表示。比如,homecontrol",",并添加如下代码:",",应用变更时",",这是个简写,表示该属性",":"],"pipeline":["stopWordFilter","stemmer"]},"store":{"./":{"url":"./","title":"Introduction","keywords":"","body":"简明 ASP.NET Core 手册\nNate Barbettini 著\nwindsting 、 yuyi 译\nCopyright © 2018. All rights reserved.\n以 创作共用署名4.0国际许可证 发布。您可以自由地:共享 — 在任何媒介以任何形式复制、发行本作品,演绎 — 修改、转换或以本作品为基础进行创作,在任何用途下,甚至商业目的。您必须给出适当的署名,提供指向本许可协议的链接。\n详情请访问:https://creativecommons.org/licenses/by/4.0/deed.zh\n前言\n感谢你选择这本 简明 ASP.NET Core 手册!我写这本小书的目的,是帮助 web 编程开发者以及爱好者了解 ASP.NET Core 2.0,一个用于创建 Web应用 和 API 的框架。\n这本 简明 ASP.NET Core 手册 的内容组织成了一篇教程。你将从头开始,完整地构建一个应用程序,同时了解以下内容:\n\nMVC (Model-View-Controller) 模式的基本内容\n前端代码(HTML、CSS、JavaScript)怎样与后端代码交互\n什么是依赖注入以及它的实用之处\n如何进行数据库的读写操作\n如何添加 登录、注册功能,以及如何提升安全性\n如何部署该应用程序到网络上\n\n别担心,就算对 ASP.NET Core (及以上列表的内容)一无所知,也不妨碍你学下去。\n开始之前\n你将要构建的这个应用,其完整源码位于 GitHub:\nhttps://www.github.com/nbarbettini/little-aspnetcore-todo\n如果需要与你自己的代码做对比,可任意下载。\n这本书本身也会由于修订和内容的增加而频繁更新。如果你阅读的是 PDF、电子书,或者打印版,请查阅官网(littleasp.net/book,中文版为 windsting.github.io/little-aspnetcore-book/book/)的版本更新。有关版本信息和更新内容,请查阅本书的最后一页。\n选择你的语言阅读\n感谢那些多语言的投稿者,简明 ASP.NET Core 手册 已经被翻译成其它语言:\n\nThe Little ASP.NET Core Book (English -- original version)\n\nASP.NET Core El Kitabı (Turkish)\n\n\n本书的目标读者\n如果你刚开始编程,本书将在“构建最新web应用”方面,使你了解其中的模式和概念。你将以从无到有、循序渐进的方式,学习构建一个 web 应用的方法(以及合理组织各模块的方法)。对于你在编程方面所需的内容,本书不能事无巨细的涵盖,但它可以作为一个起点,引导你了解更高级的内容。\n如果你已经在使用诸如 Node、Python、Ruby、Go 或者 Java 之类的后端语言写程序,你会注意到很多熟悉的概念,比如 MVC、视图模板和依赖注入。你将使用 C# 进行编程,但跟你熟知的内容相去不远。\n如果你是一个 ASP.NET MVC 开发者,将如鱼得水。 ASP.NET Core 增添了一些新工具,并复用(及简化)了你用过的那些东西。我将在后续章节指出部分差异。\n不论你此前在 web 编程方面经验如何,本书都会倾囊相授,足够你借助 ASP.NET Core 创建一个简单但实用的 web 应用。你将学习如何通过前后端代码实现设计目标,如何与数据库交互,如何部署应用到真实环境。\n什么是 ASP.NET Core?\nASP.NET Core 是一个由微软创建的,用于构建 web 应用、API、微服务 的 web 框架。它使用常见的模式,诸如 MVC(Model-View-Controller)、依赖注入,和一个由中间件构成的请求处理管线。它基于 Apache 2.0 许可证开放源码,就是说,源代码可以自由获取,并且欢迎社区成员以 缺陷修复 和 新功能提交 的方式进行贡献。\nASP.NET Core 运行在微软的 .NET 运行时库上,类似于 Java 的 虚拟机(JVM)或者 Ruby 的解释器。有几种语言(C#,Visual Basic,F#)可以用来编写 ASP.NET Core 程序。C# 是最常见的选择,我在本书中也会采用它。你可以在 Windows、Mac,和 Linux 上构建并运行 ASP.NET Core 应用。\n又一个 web 框架,需求何在?\n现存的 web 框架选项已经很多了:Node/Express、Spring、Ruby on Rails、Django、Laravel 等等,数不胜数。ASP.NET Core 又有什么可取之处呢?\n\n速度 ASP.NET Core 很快。因为 .NET Core 是编译运行的,执行速度远高于解释执行的语言,比如 JavaScript 或者 Ruby。ASP.NET Core 也为多线程和异步任务作了专门的优化。与使用 Node.js 写的代码相比,执行速度高出 5-10 倍是很正常的。\n\n生态 ASP.NET Core 可能初出茅庐,但 .NET 却已久经考验。在 NuGet(.NET 的包管理系统,类似 npm、Ruby gems,或者 Maven)上有成千上万的软件包。有现成的包可用来完成 JSON 反序列化、数据库连接、PDF生成,或者几乎你能想到的任何需求。\n\n安全性 微软的开发团队很注重安全性,ASP.NET Core 从构建伊始就注重安全。它已经自动处理了净化输入数据和跨域伪造请求(CSRF),你就不需要操心这些了。你同时还享有 .NET 编译器的静态类型检测的优势,它像个时刻警惕着,还有些强迫症的审校者。这样,在使用一个变量或者某些数据时,那些无意识的错误就插翅难逃了。\n\n\n.NET Core 和 .NET 标准\n贯穿本书,你将学习有关 ASP.NET Core (web 框架)的知识。我会偶尔提及 .NET 运行时,这个用于运行 .NET 代码的支持库。如果你看着这段已经像天书那么晦涩,直接跳到下一章吧。\n你可能还会听说 .NET Core 和 .NET标准,这些命名有些混乱,所以在此做一简短的释疑:\n.NET 标准 是一个平台无关的接口,它定义了特性和 API。值得指出的是,.NET 标准并不等同于任何实际的代码或者功能,仅仅是 API 的定义。.NET 标准现存多个不同的“版本”或者说级别,反映出提供 API 的数量(或者说 API 所覆盖的广度)。比如 .NET标准2.0 的 API 数量,比 .NET标准1.5 多,后者的 API 又比 .NET标准1.0 多。\n.NET Core 是可在 Windows、Mac或者Linux上安装的 .NET 运行时库。它在各个操作系统上,使用对应的平台相关代码,实现了定义于 .NET 标准中的 API。这是你将要安装到机器上,用来构建和运行 ASP.NET Core 应用程序的部分。\n作为对比,这里要指出, .NET Framework 是另一个 .NET标准 的实现,它只能运行在 Windows 上。在 .NET Core 出现并把 .NET 推向 Mac 和 Linux 之前,它是唯一的 .NET 运行时库。 ASP.NET Core 也可以跑在 Windows 专用的 .NET Framework 上,但我不会过多涉及这个主题。\n如果你已经被这些命名搞糊涂了,别发愁!咱们马上就要写代码进行实践了。\nASP.NET 4 开发者注意\n如果你从没用过 ASP.NET 以前的版本,直接看下一章去吧!\nASP.NET Core 是对 ASP.NET 彻底的重写,重点关注于:让该框架应用新的开发方法,并最终使其与 System.Web、IIS、和 Windows 解耦。你要是还记得 ASP.NET 4 的 OWIN/Katana 那些内容,你就已经学会一半了: Katana 项目成了 ASP.NET 5,而后者的名字最终被改成了 ASP.NET Core。\n作为 Katana 的传承, Startup 类成了起始和中心,Application_Start 和 Global.asax 则不复存在了。整个处理管线由中间件驱动,MVC 和 Web API 不再有区别:控制器可以方便的返回视图、状态码,或者数据。依赖注入功能已经内置了,所以,如果你不想费劲的话,完全可以不用再安装并配置一个服务容器了,比如 StructureMap 或者 Ninject。整个框架已经针对速度和运行时效率进行了优化。\n好了,前言就到这儿。开始学习 ASP.NET Core 吧。\n\nThe Little ASP.NET Core Book\nby Nate Barbettini\nCopyright © 2018. All rights reserved.\nISBN: 978-1-387-75615-5\nReleased under the Creative Commons Attribution 4.0 license. You are free to share, copy, and redistribute this book in any format, or remix and transform it for any purpose (even commercially). You must give appropriate credit and provide a link to the license.\nFor more information, visit https://creativecommons.org/licenses/by/4.0/\nIntroduction\nThanks for picking up The Little ASP.NET Core Book! I wrote this short book to help developers and people interested in web programming learn about ASP.NET Core 2.0, a framework for building web applications and APIs.\nThe Little ASP.NET Core Book is structured as a tutorial. You'll build an application from start to finish and learn:\n\nThe basics of the MVC (Model-View-Controller) pattern\nHow front-end code (HTML, CSS, JavaScript) works together with back-end code\nWhat dependency injection is and why it's useful\nHow to read and write data to a database\nHow to add log-in, registration, and security\nHow to deploy the application to the web\n\nDon't worry, you don't need to know anything about ASP.NET Core (or any of the above) to get started.\nBefore you begin\nThe code for the finished version of the application you'll build is available on GitHub:\nhttps://www.github.com/nbarbettini/little-aspnetcore-todo\nFeel free to download it if you want to see the finished product, or compare as you write your own code.\nThe book itself is updated frequently with bug fixes and new content. If you're reading a PDF, e-book, or print version, check the official website (littleasp.net/book) to see if there's an updated version available. The very last page of the book contains version information and a changelog.\nReading in your own language\nThanks to some fantastic multilingual contributors, the Little ASP.NET Core Book has been translated into other languages:\n\nASP.NET Core El Kitabı (Turkish)\n\n简明 ASP.NET Core 手册 (Chinese)\n\n\nWho this book is for\nIf you're new to programming, this book will introduce you to the patterns and concepts used to build modern web applications. You'll learn how to build a web app (and how the big pieces fit together) by building something from scratch! While this little book won't be able to cover absolutely everything you need to know about programming, it'll give you a starting point so you can learn more advanced topics.\nIf you already code in a backend language like Node, Python, Ruby, Go, or Java, you'll notice a lot of familiar ideas like MVC, view templates, and dependency injection. The code will be in C#, but it won't look too different from what you already know.\nIf you're an ASP.NET MVC developer, you'll feel right at home! ASP.NET Core adds some new tools and reuses (and simplifies) the things you already know. I'll point out some of the differences below.\nNo matter what your previous experience with web programming, this book will teach you everything you need to create a simple and useful web application in ASP.NET Core. You'll learn how to build functionality using backend and frontend code, how to interact with a database, and how to deploy the app to the world.\nWhat is ASP.NET Core?\nASP.NET Core is a web framework created by Microsoft for building web applications, APIs, and microservices. It uses common patterns like MVC (Model-View-Controller), dependency injection, and a request pipeline comprised of middleware. It's open-source under the Apache 2.0 license, which means the source code is freely available, and the community is encouraged to contribute bug fixes and new features.\nASP.NET Core runs on top of Microsoft's .NET runtime, similar to the Java Virtual Machine (JVM) or the Ruby interpreter. You can write ASP.NET Core applications in a number of languages (C#, Visual Basic, F#). C# is the most popular choice, and it's what I'll use in this book. You can build and run ASP.NET Core applications on Windows, Mac, and Linux.\nWhy do we need another web framework?\nThere are a lot of great web frameworks to choose from already: Node/Express, Spring, Ruby on Rails, Django, Laravel, and many more. What advantages does ASP.NET Core have?\n\nSpeed. ASP.NET Core is fast. Because .NET code is compiled, it executes much faster than code in interpreted languages like JavaScript or Ruby. ASP.NET Core is also optimized for multithreading and asynchronous tasks. It's common to see a 5-10x speed improvement over code written in Node.js.\n\nEcosystem. ASP.NET Core may be new, but .NET has been around for a long time. There are thousands of packages available on NuGet (the .NET package manager; think npm, Ruby gems, or Maven). There are already packages available for JSON deserialization, database connectors, PDF generation, or almost anything else you can think of.\n\nSecurity. The team at Microsoft takes security seriously, and ASP.NET Core is built to be secure from the ground up. It handles things like sanitizing input data and preventing cross-site request forgery (CSRF) attacks, so you don't have to. You also get the benefit of static typing with the .NET compiler, which is like having a very paranoid linter turned on at all times. This makes it harder to do something you didn't intend with a variable or chunk of data.\n\n\n.NET Core and .NET Standard\nThroughout this book, you'll be learning about ASP.NET Core (the web framework). I'll occasionally mention the .NET runtime, the supporting library that runs .NET code. If this already sounds like Greek to you, just skip to the next chapter!\nYou may also hear about .NET Core and .NET Standard. The naming gets confusing, so here's a simple explanation:\n.NET Standard is a platform-agnostic interface that defines features and APIs. It's important to note that .NET Standard doesn't represent any actual code or functionality, just the API definition. There are different \"versions\" or levels of .NET Standard that reflect how many APIs are available (or how wide the API surface area is). For example, .NET Standard 2.0 has more APIs available than .NET Standard 1.5, which has more APIs than .NET Standard 1.0.\n.NET Core is the .NET runtime that can be installed on Windows, Mac, or Linux. It implements the APIs defined in the .NET Standard interface with the appropriate platform-specific code on each operating system. This is what you'll install on your own machine to build and run ASP.NET Core applications.\nAnd just for good measure, .NET Framework is a different implementation of .NET Standard that is Windows-only. This was the only .NET runtime until .NET Core came along and brought .NET to Mac and Linux. ASP.NET Core can also run on Windows-only .NET Framework, but I won't touch on this too much.\nIf you're confused by all this naming, no worries! We'll get to some real code in a bit.\nA note to ASP.NET 4 developers\nIf you haven't used a previous version of ASP.NET, skip ahead to the next chapter.\nASP.NET Core is a complete ground-up rewrite of ASP.NET, with a focus on modernizing the framework and finally decoupling it from System.Web, IIS, and Windows. If you remember all the OWIN/Katana stuff from ASP.NET 4, you're already halfway there: the Katana project became ASP.NET 5 which was ultimately renamed to ASP.NET Core.\nBecause of the Katana legacy, the Startup class is front and center, and there's no more Application_Start or Global.asax. The entire pipeline is driven by middleware, and there's no longer a split between MVC and Web API: controllers can simply return views, status codes, or data. Dependency injection comes baked in, so you don't need to install and configure a container like StructureMap or Ninject if you don't want to. And the entire framework has been optimized for speed and runtime efficiency.\nAlright, enough introduction. Let's dive in to ASP.NET Core!\n"},"chapters/your-first-application/":{"url":"chapters/your-first-application/","title":"你的第一个程序","keywords":"","body":"你的第一个程序\n准备好创建你的第一个 ASP.NET Core web 应用了么?先做点“利其器”的事:\n你惯用的代码编辑器 你可以用 Atom、Sublime、Notepad 或者任何你喜欢的编辑器。如果你还没有一个惯用的,请试试 Visual Studio Code。这是个免费、跨平台的代码编辑器,对于 C#、JavaScript、HTML 和很多其它语言编程的支持非常丰富。只需要搜索“下载 visual studio code”再按指令操作即可。(译者的话:别用 百度,试试 bing.com)\n如果你在 Windows 下,也可以用 Visual Studio 构建 ASP.NET Core 应用程序。这需要用到 Visual Studio 2017 的 15.3 及以上的版本(免费的社区版就够用了)。Visual Studio 有着优秀的 代码补全 和 C# 的代码重构,且略优于 Visual Studio Code。\n.NET Core SDK 不论你用什么编辑器或者平台,都需要安装 .NET Core SDK,包括运行时,基础库以及用于构建 ASP.NET Core 应用程序的命令行工具。它可以安装在 Windows、Mac、Linux上。\n选定了编辑器,就该去获取 SDK 了。\n\nYour first application\nReady to build your first web app with ASP.NET Core? You'll need to gather a few things first:\nYour favorite code editor. You can use Atom, Sublime, Notepad, or whatever editor you prefer writing code in. If you don't have a favorite, give Visual Studio Code a try. It's a free, cross-platform code editor that has rich support for writing C#, JavaScript, HTML, and more. Just search for \"download visual studio code\" and follow the instructions.\nIf you're on Windows, you can also use Visual Studio to build ASP.NET Core applications. You'll need Visual Studio 2017 version 15.3 or later (the free Community Edition is fine). Visual Studio has great code completion and refactoring support for C#, although Visual Studio Code is close behind.\nThe .NET Core SDK. Regardless of the editor or platform you're using, you'll need to install the .NET Core SDK, which includes the runtime, base libraries, and command line tools you need for building ASP.NET Core applications. The SDK can be installed on Windows, Mac, or Linux.\nOnce you've decided on an editor, you'll need to get the SDK.\n"},"chapters/your-first-application/get-the-sdk.html":{"url":"chapters/your-first-application/get-the-sdk.html","title":"获取 SDK","keywords":"","body":"获取 SDK\n搜索“下载 .net core”,在微软为你所在平台提供的下载页面,获取 .NET Core 的 SDK。完成 SDK 的安装后,开启一个终端窗口(或者 Windows 上的 PowerShell),并使用 dotnet 命令行工具(command line tool,也叫 CLI)确保一切正常工作:\ndotnet --version\n\n2.1.104\n\n还可以通过 --info 选项,获取你所在平台更详细的信息:\ndotnet --info\n\n.NET Command Line Tools (2.1.104)\n\nProduct Information:\n Version: 2.1.104\n Commit SHA-1 hash: 48ec687460\n\nRuntime Environment:\n OS Name: Mac OS X\n OS Version: 10.13\n\n(more details...)\n\n如果你看到类似于上面的输出,就大步前进吧。\n\nGet the SDK\nSearch for \"download .net core\" and follow the instructions on Microsoft's download page to get the .NET Core SDK. After the SDK has finished installing, open up the Terminal (or PowerShell on Windows) and use the dotnet command line tool (also called a CLI) to make sure everything is working:\ndotnet --version\n\n2.1.104\nYou can get more information about your platform with the --info flag:\ndotnet --info\n\n.NET Command Line Tools (2.1.104)\n\nProduct Information:\n Version: 2.1.104\n Commit SHA-1 hash: 48ec687460\n\nRuntime Environment:\n OS Name: Mac OS X\n OS Version: 10.13\n\n(more details...)\nIf you see output like the above, you're ready to go!\n"},"chapters/your-first-application/hello-world-in-csharp.html":{"url":"chapters/your-first-application/hello-world-in-csharp.html","title":"C# 版的 Hello World","keywords":"","body":"C# 版的 Hello World\n深入钻研 ASP.NET Core 之前,先试着创建并运行一个简单的应用程序吧。\n这个可以在命令行下执行。首先开启一个终端窗口(或者 Windows 上的 PowerShell)。一路 cd 到要放置你项目的路径下,比如你的“我的文档”目录:\ncd Documents\n\n使用 dotnet 命令创建一个新的项目:\ndotnet new console -o CsharpHelloWorld\n\ndotnet new 指令默认会用 C# 创建一个 .NET 项目。参数 console 选择了一个命令行应用(一种向屏幕输出文本的程序)的模板。-o CsharpHelloWorld 参数指示 dotnet new 为项目的所有文件创建一个名为 CsharpHelloWorld 的目录。进入到这个新目录里:\ncd CsharpHelloWorld\n\ndotnet new console 命令创建了一个基本的 C# 程序,它输出文本 Hello World! 到屏幕上。这个程序由两个文件构成:一个项目文件(使用 .csproj 扩展名)和一个 C# 源文件(带有 .cs 扩展名),打开前面那个文件的话,可以看到以下内容:\nCsharpHelloWorld.csproj\n\n\n \n Exe\n netcoreapp2.0\n \n\n\n\n项目文件基于 XML,其中定义了一些关于项目的元数据。到后面,你引用其它包的时候,那些包将被记录在这里(类似于 npm 的 package.json),你不需要经常手动编辑这个文件。\nProgram.cs\nusing System;\n\nnamespace CsharpHelloWorld\n{\n class Program\n {\n static void Main(string[] args)\n {\n Console.WriteLine(\"Hello World!\");\n }\n }\n}\n\nstatic void Main 是 C# 程序的入口点方法,按照惯例,会被置于一个叫 Program 的类(一种代码结构或模块)里。最上面的 using 语句引入了 .NET 内置于 System 的那些类,以便在你的这个类里使用它们。\n在项目的目录里,用 dotnet run 指令运行这个程序,在代码编译完成之后,你将看到输出在控制台里面的内容:\ndotnet run\n\nHello World!\n\n这就是构建一个 .NET 程序所需的全部!下一节,你将把同样的流程应用在一个 ASP.NET Core 程序上。\n\nHello World in C#\nBefore you dive into ASP.NET Core, try creating and running a simple C# application.\nYou can do this all from the command line. First, open up the Terminal (or PowerShell on Windows). Navigate to the location you want to store your projects, such as your Documents directory:\ncd Documents\nUse the dotnet command to create a new project:\ndotnet new console -o CsharpHelloWorld\nThe dotnet new command creates a new .NET project in C# by default. The console parameter selects a template for a console application (a program that outputs text to the screen). The -o CsharpHelloWorld parameter tells dotnet new to create a new directory called CsharpHelloWorld for all the project files. Move into this new directory:\ncd CsharpHelloWorld\ndotnet new console creates a basic C# program that writes the text Hello World! to the screen. The program is comprised of two files: a project file (with a .csproj extension) and a C# code file (with a .cs extension). If you open the former in a text or code editor, you'll see this:\nCsharpHelloWorld.csproj\n\n\n \n Exe\n netcoreapp2.0\n \n\n\n\nThe project file is XML-based and defines some metadata about the project. Later, when you reference other packages, those will be listed here (similar to a package.json file for npm). You won't have to edit this file by hand very often.\nProgram.cs\nusing System;\n\nnamespace CsharpHelloWorld\n{\n class Program\n {\n static void Main(string[] args)\n {\n Console.WriteLine(\"Hello World!\");\n }\n }\n}\n\nstatic void Main is the entry point method of a C# program, and by convention it's placed in a class (a type of code structure or module) called Program. The using statement at the top imports the built-in System classes from .NET and makes them available to the code in your class.\nFrom inside the project directory, use dotnet run to run the program. You'll see the output written to the console after the code compiles:\ndotnet run\n\nHello World!\nThat's all it takes to scaffold and run a .NET program! Next, you'll do the same thing for an ASP.NET Core application.\n"},"chapters/your-first-application/create-aspnetcore-project.html":{"url":"chapters/your-first-application/create-aspnetcore-project.html","title":"创建一个 ASP.NET Core 项目","keywords":"","body":"创建一个 ASP.NET Core 项目\n如果你还在 Hello World 示例的那个目录里,请退回到 我的文档 或者 home 目录:\ncd ..\n\n接下来,创建一个新目录以保存你的整个项目,然后进到该目录里:\nmkdir AspNetCoreTodo\ncd AspNetCoreTodo\n\n接下来,使用 dotnet new 创建一个新项目,这一次添加几个选项:\ndotnet new mvc --auth Individual -o AspNetCoreTodo\ncd AspNetCoreTodo\n\n这个命令,使用 mvc 模板创建了一个新的项目,并添加了一些额外的验证和安全性相关的内容。(关于安全性的内容,我会在 安全性与身份 一章讲解。)\n\n你可能有点疑惑,为什么在一个 AspNetCoreTodo 目录里弄另一个 AspNetCoreTodo 目录。这个顶层或者说“根”目录可以容纳一个或多个项目目录。根目录有时候被称为 解决方案目录。后面,你将会在 AspNetCoreTodo 项目目录边上添加多个项目目录,它们全都在一个单一的根解决方案目录里。\n\n在这个新的项目目录里,你会发现多出来几个文件。在你 cd 到新目录里之后,就只需要运行这个项目了:\ndotnet run\n\nNow listening on: http://localhost:5000\nApplication started. Press Ctrl+C to shut down.\n\n这个程序不再打印到控制台后直接退出,而是启动了一个 web 服务器,并在端口 5000 上等待访问请求。\n开启你的网络浏览器,浏览 http://localhost:5000。你将看到 ASP.NET Core 程序的默认欢迎页面,说明你的程序工作正常!看够了这个页面之后,在终端窗口内按下 Ctrl-C 以便停止这个服务器。\n一个 ASP.NET Core 项目的各部分\ndotnet new mvc 模板为你生成了多个文件和目录。在默认创建的基本内容里,这几个是最重要的:\n\nProgram.cs 和 Startup.cs 文件,设置 web 服务器和 ASP.NET Core 的处理管线。在 Startup 类里,你可以添加中间件,它们用于 处理和调整传入的请求、提供静态内容和错误页面。在这里,你还可以向依赖注入容器中添加你自己的服务(后面细说)。\n\nModels、Views,和 Controllers目录里放置着 模型-视图-控制器(MVC,Model-View-Controller)架构的组件。下一章,你将一探他们三者的究竟。\n\nwwwroot 目录里放着 CSS、JavaScript、图片文件 这些静态资源。wwwroot 里的文件将作为静态内容,自动被打包和压缩。\n\nappsettings.json 文件里包含着 ASP.NET Core 启动时读取的配置信息。你可以用它来保存数据库连接字符串,或者其它你不想硬编码的任何内容。\n\n\nVisual Studio Code 技巧\n如果你是初次使用 Visual Studio Code(或者 Visual Studio),下面这几个有益的小技巧将帮你轻松上手:\n\n打开项目的根文件夹 : 在 Visual Studio Code 里,选择 文件 -> 打开文件夹。打开 AspNetCoreTodo 文件夹(根目录),不是内层的项目目录。如果 Visual Studio Code 提示你安装缺失的文件,点击“是”以添加它们。\n\n用 F5 运行(并调试断点):使你的项目处于打开状态,按下 F5 以调试模式运行项目。这跟命令行的 dotnet run 功能相同,但有一个额外好处——你可以在代码编辑器的左边栏上点击,以设置一个断点:\n \n\n潜在问题的小灯泡提示:如果你的代码里有红色波浪线(编译错误),把编辑的光标放在红线里,到左边栏里找那个小灯泡的图标,小灯泡的提示信息会给出常见问题的修改建议,比如在代码里添加一个 using 语句:\n \n\n快捷编译:使用快捷键 Command-Shift-B 或者 Control-Shift-B 运行编译任务,这跟 dotnet build 的效果一样。\n\n\n\n这些也可以用在 Widnows 版的 Visual Studio (不带 Code)。如果你用的是 Visual Studio,你需要直接打开 .csproj 项目文件所在的目录。 Visual Studio 后面会提示你保存解决方案文件,你应该把它保存在根目录(第一个 AspNetCoreTodo 文件夹)。你也可以在 Visual Studio 里使用模板直接创建 ASP.NET Core 项目,操作是 文件 > 新建 > 项目。\n\nGit 小贴士:\n如果你使用 Git 或者 GitHub 管理你的源码,眼下就是一个适合的时机,在项目目录下用 git init 来初始化你的 Git 仓库:\ncd ..\ngit init\n\n请确保你添加了一个 .gitignore 文件用以忽略 bin 和 obj 这些目录。 GitHub 上 gitignore 模板仓库(https://github.com/github/gitignore)里的 Visual Studio gitignore 模板就很好用。\n还有很多值得研究的内容,让我们着手构建这个应用吧!\n\nCreate an ASP.NET Core project\nIf you're still in the directory you created for the Hello World sample, move back up to your Documents or home directory:\ncd ..\nNext, create a new directory to store your entire project, and move into it:\nmkdir AspNetCoreTodo\ncd AspNetCoreTodo\nNext, create a new project with dotnet new, this time with some extra options:\ndotnet new mvc --auth Individual -o AspNetCoreTodo\ncd AspNetCoreTodo\nThis creates a new project from the mvc template, and adds some additional authentication and security bits to the project. (I'll cover security in the Security and identity chapter.)\n\nYou might be wondering why you have a directory called AspNetCoreTodo inside another directory called AspNetCoreTodo. The top-level or \"root\" directory can contain one or more project directories. The root directory is sometimes called a solution directory. Later, you'll add more project directories side-by-side with the AspNetCoreTodo project directory, all within a single root solution directory.\n\nYou'll see quite a few files show up in the new project directory. Once you cd into the new directory, all you have to do is run the project:\ndotnet run\n\nNow listening on: http://localhost:5000\nApplication started. Press Ctrl+C to shut down.\nInstead of printing to the console and exiting, this program starts a web server and waits for requests on port 5000.\nOpen your web browser and navigate to http://localhost:5000. You'll see the default ASP.NET Core splash page, which means your project is working! When you're done, press Ctrl-C in the terminal window to stop the server.\nThe parts of an ASP.NET Core project\nThe dotnet new mvc template generates a number of files and directories for you. Here are the most important things you get out of the box:\n\nThe Program.cs and Startup.cs files set up the web server and ASP.NET Core pipeline. The Startup class is where you can add middleware that handles and modifies incoming requests, and serves things like static content or error pages. It's also where you add your own services to the dependency injection container (more on this later).\n\nThe Models, Views, and Controllers directories contain the components of the Model-View-Controller (MVC) architecture. You'll explore all three in the next chapter.\n\nThe wwwroot directory contains static assets like CSS, JavaScript, and image files. Files in wwwroot will be served as static content, and can be bundled and minified automatically.\n\nThe appsettings.json file contains configuration settings ASP.NET Core will load on startup. You can use this to store database connection strings or other things that you don't want to hard-code.\n\n\nTips for Visual Studio Code\nIf you're using Visual Studio Code for the first time, here are a couple of helpful tips to get you started:\n\nOpen the project root folder: In Visual Studio Code, choose File - Open or File - Open Folder. Open the AspNetCoreTodo folder (the root directory), not the inner project directory. If Visual Studio Code prompts you to install missing files, click Yes to add them.\n\nF5 to run (and debug breakpoints): With your project open, press F5 to run the project in debug mode. This is the same as dotnet run on the command line, but you have the benefit of setting breakpoints in your code by clicking on the left margin:\n\n\n\n\nLightbulb to fix problems: If your code contains red squiggles (compiler errors), put your cursor on the code that's red and look for the lightbulb icon on the left margin. The lightbulb menu will suggest common fixes, like adding a missing using statement to your code:\n\n\n\nCompile quickly: Use the shortcut Command-Shift-B or Control-Shift-B to run the Build task, which does the same thing as dotnet build.\n\n\nThese tips apply to Visual Studio (not Code) on Windows too. If you're using Visual Studio, you'll need to open the .csproj project file directly. Visual Studio will later prompt you to save the Solution file, which you should save in the root directory (the first AspNetCoreTodo folder). You can also create an ASP.NET Core project directly within Visual Studio using the templates in File - New Project.\n\nA note about Git\nIf you use Git or GitHub to manage your source code, now is a good time to do git init and initialize a Git repository in the project root directory:\ncd ..\ngit init\nMake sure you add a .gitignore file that ignores the bin and obj directories. The Visual Studio template on GitHub's gitignore template repo (https://github.com/github/gitignore) works great.\nThere's plenty more to explore, so let's dive in and start building an application!\n"},"chapters/mvc-basics/":{"url":"chapters/mvc-basics/","title":"MVC 基础","keywords":"","body":"MVC 基础\n在这一章,你将探究 ASP.NET Core 中的 MVC 系统。 MVC(模型-视图-控制器,Model-View-Controller)是一个构建 web应用 的模式,其应用几乎遍及所有的 web框架(Ruby on Rails 和 Express 就是常见的范例)以及 Angular 这样的前端 JavaScript 框架。iOS 和 Android 上的移动应用也是 MVC 的一个变种。\n正如其名字所示,MVC 有三个组件:模型、视图、和控制器。控制器处理从客户端浏览器传入的请求,并选定相应的代码进行处理。视图就是模板(一般是 HTML 外加某种 Handlebars、Pug、Razor 之类的模板语言),它接收传入的数据并展示给用户。模型则保管着数据,要么是准备发送给视图的,要么是用户输入的。\nMVC 程序里常见的模式是:\n\n控制器接收请求,到数据库查找所需资料\n控制器使用查找到的信息创建模型,并使之与一个视图绑定\n视图在用户的浏览器里渲染并呈现\n用户点击一个按钮或者提交一个表单,从而发送一个新的请求给控制器,重复整个处理流程\n\n如果你用其它开发语言写过 MVC,那你在 ASP.NET Core 里将如鱼得水。如果你是初次跟 MVC 打交道,这一章将教你基础知识,带你上道。\n练习内容\nMVC 练习里的 “Hello World”,就是创建一个待办事项清单应用程序。这是个很棒的练习,麻雀小,五脏俱全,它将涉及 MVC 的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。\n通读本书,你将构建一个待办清单应用,允许用户添加待办项,并在事项完成之后勾掉它。具体来说,你将创建的是:\n\n一个 web 应用程序服务器(有时也被称为“后端”),使用 ASP.NET Core、C#和MVC模式\n一个用于存储用户待办事项条目的数据库,使用 SQLite 数据库引擎和一个被称为 Entity Framework Core 的系统创建\n让用户通过她们的浏览器进行交互的网页和界面(也被称为“前端”),使用HTML、CSS、JavaScript创建\n一个登录及安全检查表单,以便每个用户的待办事项列表都保持私密\n\n听起来心动吗?那就整起来吧!你要是还没按上一章所讲,用 dotnet new mvc 创建一个新的 ASP.NET Core 项目。那你应该现在就创建并运行那个项目,直到看见默认的欢迎页面为止。\n\nMVC basics\nIn this chapter, you'll explore the MVC system in ASP.NET Core. MVC (Model-View-Controller) is a pattern for building web applications that's used in almost every web framework (Ruby on Rails and Express are popular examples), plus frontend JavaScript frameworks like Angular. Mobile apps on iOS and Android use a variation of MVC as well.\nAs the name suggests, MVC has three components: models, views, and controllers. Controllers handle incoming requests from a client or web browser and make decisions about what code to run. Views are templates (usually HTML plus a templating language like Handlebars, Pug, or Razor) that get data added to them and then are displayed to the user. Models hold the data that is added to views, or data that is entered by the user.\nA common pattern for MVC code is:\n\nThe controller receives a request and looks up some information in a database\nThe controller creates a model with the information and attaches it to a view\nThe view is rendered and displayed in the user's browser\nThe user clicks a button or submits a form, which sends a new request to the controller, and the cycle repeats\n\nIf you've worked with MVC in other languages, you'll feel right at home in ASP.NET Core MVC. If you're new to MVC, this chapter will teach you the basics and will help get you started.\nWhat you'll build\nThe \"Hello World\" exercise of MVC is building a to-do list application. It's a great project since it's small and simple in scope, but it touches each part of MVC and covers many of the concepts you'd use in a larger application.\nIn this book, you'll build a to-do app that lets the user add items to their to-do list and check them off once complete. More specifically, you'll be creating:\n\nA web application server (sometimes called the \"backend\") using ASP.NET Core, C#, and the MVC pattern\nA database to store the user's to-do items using the SQLite database engine and a system called Entity Framework Core\nWeb pages and an interface that the user will interact with via their browser, using HTML, CSS, and JavaScript (called the \"frontend\")\nA login form and security checks so each user's to-do list is kept private\n\nSound good? Let's built it! If you haven't already created a new ASP.NET Core project using dotnet new mvc, follow the steps in the previous chapter. You should be able to build and run the project and see the default welcome screen.\n"},"chapters/mvc-basics/create-controller.html":{"url":"chapters/mvc-basics/create-controller.html","title":"创建控制器","keywords":"","body":"创建控制器\n在项目的 Controllers 目录里,已经预置了几个控制器,其中有渲染默认欢迎页的 HomeController,就是你访问 http://localhost:5000 看到的那个页面。暂时不用管这些控制器。\n给待办清单功能创建一个新的控制器,取名叫 TodoController ,并添加如下代码:\nControllers/TodoController.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace AspNetCoreTodo.Controllers\n{\n public class TodoController : Controller\n {\n // 在这里添加 Actions\n }\n}\n\n由控制器本身处理的路由叫 action ,在控制器类里用方法表示。比如,HomeController 包含三个 action 方法(Index,About,和 Contact),由 ASP.NET Core 分别映射到如下的 URL:\nlocalhost:5000/Home -> Index()\nlocalhost:5000/Home/About -> About()\nlocalhost:5000/Home/Contact -> Contact()\n\nASP.NET Core 中有几个惯例(常见的模式),比如这个 FooController 映射到 /Foo 的模式,还有 Index 的 action名 可以在 URL 里省略。如果你有需要,可以自定义这些行为,不过就目前的情况,让我们暂且遵循这些惯例。\n在 TodoController 里,添加一个名为 Index 的 action,把那句 // Actions go here 注释替换掉:\npublic class TodoController : Controller\n{\n public IActionResult Index()\n {\n // 从数据库获取 to-do 条目\n\n // 把条目置于 model 中\n\n // 使用 model 渲染视图\n }\n}\n\n一个 action 方法可以返回视图、JSON数据,或者 200 OK和404 Not Found 之类的状态码。返回类型 IActionResult 给了你足够的灵活性,以返回上面提到的任意一个。\n使控制器尽可能保持轻量化,是一个良好的习惯。在当前的情形里,这个控制器应该仅仅完成这些事情:从数据库取出待办事项的记录,把这些事项包装在一个可用于视图的模型中,并把这个视图发送到用户的浏览器。\n继续编码这个控制器之前,你需要创建 模型 和 视图。\n\nCreate a controller\nThere are already a few controllers in the project's Controllers directory, including the HomeController that renders the default welcome screen you see when you visit http://localhost:5000. You can ignore these controllers for now.\nCreate a new controller for the to-do list functionality, called TodoController, and add the following code:\nControllers/TodoController.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace AspNetCoreTodo.Controllers\n{\n public class TodoController : Controller\n {\n // Actions go here\n }\n}\n\nRoutes that are handled by controllers are called actions, and are represented by methods in the controller class. For example, the HomeController includes three action methods (Index, About, and Contact) which are mapped by ASP.NET Core to these route URLs:\nlocalhost:5000/Home -> Index()\nlocalhost:5000/Home/About -> About()\nlocalhost:5000/Home/Contact -> Contact()\nThere are a number of conventions (common patterns) used by ASP.NET Core, such as the pattern that FooController becomes /Foo, and the Index action name can be left out of the URL. You can customize this behavior if you'd like, but for now, we'll stick to the default conventions.\nAdd a new action called Index to the TodoController, replacing the // Actions go here comment:\npublic class TodoController : Controller\n{\n public IActionResult Index()\n {\n // Get to-do items from database\n\n // Put items into a model\n\n // Render view using the model\n }\n}\n\nAction methods can return views, JSON data, or HTTP status codes like 200 OK and 404 Not Found. The IActionResult return type gives you the flexibility to return any of these from the action.\nIt's a best practice to keep controllers as lightweight as possible. In this case, the controller will be responsible for getting the to-do items from the database, putting those items into a model the view can understand, and sending the view back to the user's browser.\nBefore you can write the rest of the controller code, you need to create a model and a view.\n"},"chapters/mvc-basics/create-models.html":{"url":"chapters/mvc-basics/create-models.html","title":"创建模型","keywords":"","body":"创建模型\n我们需要创建两个独立的模型类:一个模型表示保存在数据库里的条目(有时候也称为一个 记录(entity)),另一个模型将与视图结合(MVC里的 MV)发送到用户的浏览器。因为他们都可以被称为模型,我将称后者为 视图模型(view model)。\n首先,在 Models 目录下,创建一个名为 TodoItem 的类:\nModels/TodoItem.cs\nusing System;\n\nnamespace AspNetCoreTodo.Models\n{\n public class TodoItem\n {\n public Guid Id { get; set; }\n\n public bool IsDone { get; set; }\n\n [Required]\n public string Title { get; set; }\n\n public DateTimeOffset? DueAt { get; set; }\n }\n}\n\n这个类定义了每个待办事项都要保存的内容:一个 ID、一个标题或者名称、该事项是否已经完成,以及截至日期是什么时候。每行定义了这个类的一个属性:\n\nId 属性是一个 guid,或者说是 全局(globally) 唯一(unique) 标识符(identifier). Guid(或者GUID)是一个由字母和数字组成的长长的字符串,看起来是这样的 43ec09f2-7f70-4f4b-9559-65011d5781bb。因为 guid 是随机的,并极少会有重复值,所以常被用作唯一标识。你也可以用数字(整形 integer)作为数据库记录的标识,但你需要在数据库里配置,以便这个数字在添加新条目的时候始终增长。因为 Guid 是随机生产的,所以就你不必再担心这个 自增 的问题了。\n\nIsDone 属性是一个 布尔值(值为 true/false)。默认情况下,所有新建条目的该值为 false。你后面会编写代码,在用户在视图里点击某个条目的复选框时,修改这个属性为 true。\n\nTitle 属性是一个字符串,用于保存待办事项的名称或者简述。\n\nDueAt 属性是一个 DateTimeOffset,C# 用于这种类型保存一个 日期/时间 的戳记和一个与 UTC 偏移量表示的时区。把时期、时间和时区一起保存,有助于在不同时区的系统上准确地显示时间。\n\n\n看到 DateTimeOffset 类型后面那个问号 ? 了吗?它表示 DueAt 属性 可空(nullable),或者说是可选的。如果不加这个 ?,每个待办事项都必须带有一个截止日期。Id 和 IsDone 属性没有标记为可空,所以是必须的,并可以确保始终有值(或者是一个缺省值)。\n\nC#里的字符串总是可空的,所以没必要给 Title 属性添加可空标记。C# 字符串可以没有值,也可以是空白字符串或者包含任意文本。\n\n每个属性后面都跟着 get; set; ,这是个简写,表示该属性 可读/可写(read/write)(或者,更确切地说,它有 getter 和 setter 方法各一个)。\n现在,暂且不必关心底层数据库采用的是哪种实现。它可以是 SQL Server,MySQL,MongoDB,Redis,或者什么其它稀奇古怪的玩意儿。这个模型定义了数据库里的行或者记录在 C# 里看起来是什么样的,所以你无须在代码层面担心数据库层面的东西。这种模型简单的风格被称为“朴实可爱的 C# 对象(plain old C# object)” 或者 POCO。\n视图模型\n通常,你保存在数据库里的模型(实体),跟你在 MVC 里用的模型(视图模型)非常相似,但又不尽相同。在现在的情形下, TodoItem 模型代表单一的一个数据库里的条目,而视图则需要展示两个、十个,甚至是一百个待办事项(取决于用户拖延症的病情轻重)。\n因此,视图模型应该是一个独立的类,里面包含着一个 TodoItem 的数组:\nModels/TodoViewModel.cs\nnamespace AspNetCoreTodo.Models\n{\n public class TodoViewModel\n {\n public TodoItem[] Items { get; set; }\n }\n}\n\n好了,现在模型也有了,是时候创建一个接收 TodoViewModel 并以 HTML 向用户展示待办事项列表的视图了。\n\nCreate models\nThere are two separate model classes that need to be created: a model that represents a to-do item stored in the database (sometimes called an entity), and the model that will be combined with a view (the MV in MVC) and sent back to the user's browser. Because both of them can be referred to as \"models\", I'll refer to the latter as a view model.\nFirst, create a class called TodoItem in the Models directory:\nModels/TodoItem.cs\nusing System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace AspNetCoreTodo.Models\n{\n public class TodoItem\n {\n public Guid Id { get; set; }\n\n public bool IsDone { get; set; }\n\n [Required]\n public string Title { get; set; }\n\n public DateTimeOffset? DueAt { get; set; }\n }\n}\n\nThis class defines what the database will need to store for each to-do item: an ID, a title or name, whether the item is complete, and what the due date is. Each line defines a property of the class:\n\nThe Id property is a guid, or a globally unique identifier. Guids (or GUIDs) are long strings of letters and numbers, like 43ec09f2-7f70-4f4b-9559-65011d5781bb. Because guids are random and are extremely unlikely to be accidentally duplicated, they are commonly used as unique IDs. You could also use a number (integer) as a database entity ID, but you'd need to configure your database to always increment the number when new rows are added to the database. Guids are generated randomly, so you don't have to worry about auto-incrementing.\n\nThe IsDone property is a boolean (true/false value). By default, it will be false for all new items. Later you'll use write code to switch this property to true when the user clicks an item's checkbox in the view.\n\nThe Title property is a string (text value). This will hold the name or description of the to-do item. The [Required] attribute tells ASP.NET Core that this string can't be null or empty.\n\nThe DueAt property is a DateTimeOffset, which is a C# type that stores a date/time stamp along with a timezone offset from UTC. Storing the date, time, and timezone offset together makes it easy to render dates accurately on systems in different timezones.\n\n\nNotice the ? question mark after the DateTimeOffset type? That marks the DueAt property as nullable, or optional. If the ? wasn't included, every to-do item would need to have a due date. The Id and IsDone properties aren't marked as nullable, so they are required and will always have a value (or a default value).\n\nStrings in C# are always nullable, so there's no need to mark the Title property as nullable. C# strings can be null, empty, or contain text.\n\nEach property is followed by get; set;, which is a shorthand way of saying the property is read/write (or, more technically, it has a getter and setter methods).\nAt this point, it doesn't matter what the underlying database technology is. It could be SQL Server, MySQL, MongoDB, Redis, or something more exotic. This model defines what the database row or entry will look like in C# so you don't have to worry about the low-level database stuff in your code. This simple style of model is sometimes called a \"plain old C# object\" or POCO.\nThe view model\nOften, the model (entity) you store in the database is similar but not exactly the same as the model you want to use in MVC (the view model). In this case, the TodoItem model represents a single item in the database, but the view might need to display two, ten, or a hundred to-do items (depending on how badly the user is procrastinating).\nBecause of this, the view model should be a separate class that holds an array of TodoItems:\nModels/TodoViewModel.cs\nnamespace AspNetCoreTodo.Models\n{\n public class TodoViewModel\n {\n public TodoItem[] Items { get; set; }\n }\n}\n\nNow that you have some models, it's time to create a view that will take a TodoViewModel and render the right HTML to show the user their to-do list.\n"},"chapters/mvc-basics/create-view.html":{"url":"chapters/mvc-basics/create-view.html","title":"创建视图","keywords":"","body":"创建视图\nASP.NET Core 里的视图使用 Razor 模板语言编写,这种模板语言混合了 HTML 和 C# 的代码。(如果你在 JavaScript 下用 Jade、Pug 或者 Handlebars moustaches,在 Ruby on Rails 下用 ERB,在 Java 下用 Thymeleaf 写过页面,那你就已经了解其基本概念了.)\n绝大多数视图代码就是 HTML,偶尔掺杂一点 C# 语句,用以从视图模型里抽取数据并转换为文本或者 HTML。这些 C# 语句以符号 @ 作为前缀。\n由 TodoController 中的 action Index 生成的视图,需要从视图模型(一个待办事项的数组)获取数据,并用一个适当的表格展示给用户。按规定,视图要置于 Views 目录里,在一个与所属控制器同名的子目录下。视图文件的文件名就是 action 的名字加上一个 .cshtml 扩展名。\nViews/Todo/Index.cshtml\n@model TodoViewModel\n\n@{\n ViewData[\"Title\"] = \"Manage your todo list\";\n}\n\n\n @ViewData[\"Title\"]\n\n \n \n \n ✔\n Item\n Due\n \n \n\n @foreach (var item in Model.Items)\n {\n \n \n \n \n @item.Title\n @item.DueAt\n \n }\n \n\n \n \n \n\n\n在文件顶端,@model 指令告诉 Razor 该视图要绑定到哪个模型。模型通过 Model 属性进行访问。\n如果在 Model.Items 里有一些待办事项条目,则 foreach 语句将遍历到每个代办事项,并渲染成一个表格的行( 元素),改行包含条目的名字和截止日期。还会展示一个带有 ID 的复选框,可以在后续操作中把该条目标记为已完成。\n布局文件\n你可能会纳闷,其余的 HTML: 标签,或者 页首 和 页脚 在哪儿?ASP.NET Core 使用一个布局视图,用以定义容纳视图的基础结构的其余部分。布局视图被保存在 Views/Shared/_Layout.cshtml。\n默认的 ASP.NET Core 模板在布局文件中包含了 Bootstrap 和 jQuery,便于你快捷地创建一个 web 应用程序。当然,只要你愿意,你可以使用自己的 CSS 和 JavaScript 库。\n定制样式表\n现在,请在 site.css 文件的底部添加以下这些 CSS 样式规则:\nwwwroot/css/site.css\ndiv.todo-panel {\n margin-top: 15px;\n}\n\ntable tr.done {\n text-decoration: line-through;\n color: #888;\n}\n\n你可以用类似的规则完全自定义页面的外观和体验。\nASP.NET Core 和 Razor 还有更多功能,比如部分视图和后端渲染的视图组件,但你现在只需要一个简单的布局和视图。想要了解更多的内容,ASP.NET Core 的官方文档(位于 https://docs.asp.net)有几个示例可以参考。\n\nCreate a view\nViews in ASP.NET Core are built using the Razor templating language, which combines HTML and C# code. (If you've written pages using Handlebars moustaches, ERB in Ruby on Rails, or Thymeleaf in Java, you've already got the basic idea.)\nMost view code is just HTML, with the occasional C# statement added in to pull data out of the view model and turn it into text or HTML. The C# statements are prefixed with the @ symbol.\nThe view rendered by the Index action of the TodoController needs to take the data in the view model (a sequence of to-do items) and display it in a nice table for the user. By convention, views are placed in the Views directory, in a subdirectory corresponding to the controller name. The file name of the view is the name of the action with a .cshtml extension.\nCreate a Todo directory inside the Views directory, and add this file:\nViews/Todo/Index.cshtml\n@model TodoViewModel\n\n@{\n ViewData[\"Title\"] = \"Manage your todo list\";\n}\n\n\n @ViewData[\"Title\"]\n\n \n \n \n ✔\n Item\n Due\n \n \n\n @foreach (var item in Model.Items)\n {\n \n \n \n \n @item.Title\n @item.DueAt\n \n }\n \n\n \n \n \n\n\nAt the very top of the file, the @model directive tells Razor which model to expect this view to be bound to. The model is accessed through the Model property.\nAssuming there are any to-do items in Model.Items, the foreach statement will loop over each to-do item and render a table row ( element) containing the item's name and due date. A checkbox is also rendered that will let the user mark the item as complete.\nThe layout file\nYou might be wondering where the rest of the HTML is: what about the tag, or the header and footer of the page? ASP.NET Core uses a layout view that defines the base structure that every other view is rendered inside of. It's stored in Views/Shared/_Layout.cshtml.\nThe default ASP.NET Core template includes Bootstrap and jQuery in this layout file, so you can quickly create a web application. Of course, you can use your own CSS and JavaScript libraries if you'd like.\nCustomizing the stylesheet\nThe default template also includes a stylesheet with some basic CSS rules. The stylesheet is stored in the wwwroot/css directory. Add a few new CSS style rules to the bottom of the site.css file:\nwwwroot/css/site.css\ndiv.todo-panel {\n margin-top: 15px;\n}\n\ntable tr.done {\n text-decoration: line-through;\n color: #888;\n}\n\nYou can use CSS rules like these to completely customize how your pages look and feel.\nASP.NET Core and Razor can do much more, such as partial views and server-rendered view components, but a simple layout and view is all you need for now. The official ASP.NET Core documentation (at https://docs.asp.net) contains a number of examples if you'd like to learn more.\n"},"chapters/mvc-basics/add-service-class.html":{"url":"chapters/mvc-basics/add-service-class.html","title":"添加一个服务类","keywords":"","body":"添加一个服务类\n你已经创建了一个模型、一个视图、一个控制器。在你把模型和视图应用于控制器中之前,需要先写点代码,用它把用户的待办事项条目从数据库里取出来。\n你可以在直接在控制器里编写这段数据库相关的代码,但是作为更良好的实践,应该保持你的代码独立。为什么呢?在一个巨大的,现实世界的程序里,你不得不应付一些事情:\n\n渲染视图 并处理接收的数据:你的控制器已经处理好了。\n执行业务逻辑,或者说跟你程序的目标和“业务”相关联的代码与逻辑。在一个待办事项列表程序里,业务逻辑意味着“为新任务设置一个默认的截止时间”,或者“仅显示未完成的任务”这些决策。业务逻辑的其它例子,包括“基于产品价格和税率计算总价”,或者“在游戏里检查一个玩家是否有足够的经验值升级”。\n存入和取出数据库中的数据。\n\n还是那句话,把所有这些东西写进一个单独的巨大的控制器是可行的,但这很快就会变得难以管理和测试。相反,常见的程序都把这些分割成两个、三个或更多的“层”或级,每个层级处理(且仅处理)一件事情。这有助于保持控制器尽量简单,并简化测试工作,以及后续的业务逻辑和数据库代码的修改。\n把程序以这种方式分割,有时被称为 多级 或者 n级架构。在某些情况下,这些层级被隔离在完全分离的项目中,也有时候这仅仅意味着各个类之间组织和调用的方式。重点在于考量如何把你的程序分割成多个可管理的部分,以避免控制器或者某些臃肿的类试图去处理所有事情。\n对当前这个项目而言,你将把程序分为两个层:一个由控制器和视图构成的 表示层,用来处理用户的交互,和一个包含了业务逻辑和数据库代码的 服务层。表示层已经有了,所以,接下来就应该构建一个服务,用来处理 待办事项 的业务逻辑,并把待办事项条目保存到数据库里去。\n\n多数较大的项目使用一种 3级 架构:一个表示层,一个逻辑服务层,一个数据仓储层。仓储(repository) 是一个仅关注数据库操作(不处理业务逻辑)的类。咱们眼下的程序里,为简化操作,我们将把这些混进一个服务层里,不过你尽可尝试采用不同的方式去架构你的代码。\n\n创建一个接口\nC# 编程语言里有一个概念叫 接口(interface),在接口中,一个对象中方法和属性的定义与实际包含这些方法和属性的类分离开来。接口有助于解耦你的那些类,也有助于测试,如你接下来(以及在后续的 自动化测试 章节中)所见。你将用一个接口来表示一个服务,该服务负责就待办事项条目事宜与数据库交互。\n习惯上,接口以大写字母“I”开头,在 Services 目录下新建一个文件:\nServices/ITodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\n\nnamespace AspNetCoreTodo.Services\n{\n public interface ITodoItemService\n {\n Task GetIncompleteItemsAsync();\n }\n}\n\n注意一下,这个文件的命名空间是 AspNetCoreTodo.Services。命名空间是一种组织 .NET 代码文件的方式,一般与存放该文件的目录名保持一致(Services目录下的文件,命名空间是AspNetCoreTodo.Services,以此类推)。\n因为这个文件(在命名空间AspNetCoreTodo.Services中)引用了 TodoItem 类(在命名空间 AspNetCoreTodo.Models中),它需要在文件顶部包含一条 using 语句,引入那个命名空间。如果不写这个 using 语句,你会看到这样的报错:\nThe type or namespace name 'TodoItem' could not be found (are you missing a using directive or an assembly reference?)\n\n因为这是一个接口,所以不包含任何实现相关的代码,只有 GetIncompleteItemsAsync 方法的定义(或者叫 方法签名(method signature))。该方法不需要任何参数,并且返回一个 Task。\n\n如果这种语法让你看上去感到困惑,就这么理解:“一个 Task 里面装着一个 TodoItem 的数组”。\n\nTask 类型类似于一个 future 或者 promise1,这里使用它的原因是,这将是个 异步的(asynchronous) 方法。换句话说,这个方法可能不会即时返回待办事项的列表,因为它需要先查询数据库。(详情见后续章节。)\n创建服务类\n现在接口已经定义好,你可开始创建具体的服务类了。在后续的 使用数据库 那章,我会深入讲解有关数据库的代码,但目前你可以造个假,直接返回硬编码的值:\nServices/FakeTodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\n\nnamespace AspNetCoreTodo.Services\n{\n public class FakeTodoItemService : ITodoItemService\n {\n public Task GetIncompleteItemsAsync()\n {\n var item1 = new TodoItem\n {\n Title = \"Learn ASP.NET Core\",\n DueAt = DateTimeOffset.Now.AddDays(1)\n };\n\n var item2 = new TodoItem\n {\n Title = \"Build awesome apps\",\n DueAt = DateTimeOffset.Now.AddDays(2)\n };\n\n return Task.FromResult(new[] { item1, item2 });\n }\n }\n}\n\nFakeTodoItemService 实现了 ITodoItemService 接口,但总是返回这个包含两个 TodoItem 的数组。你可以用它去测试控制器和视图,然后在 使用数据库 那章添加真正的代码去访问数据库。\n\n1. 译者注:二者都是其它语言中,与异步编程相关的概念,它们是用于指代某个尚未就绪的值的对象。而这个值,往往是某个计算过程的结果。要了解详细,请参考 https://en.wikipedia.org/wiki/Futures_and_promises ↩\n\n\nAdd a service class\nYou've created a model, a view, and a controller. Before you use the model and view in the controller, you also need to write code that will get the user's to-do items from a database.\nYou could write this database code directly in the controller, but it's a better practice to keep your code separate. Why? In a big, real-world application, you'll have to juggle many concerns:\n\nRendering views and handling incoming data: this is what your controller already does.\nPerforming business logic, or code and logic that's related to the purpose and \"business\" of your application. In a to-do list application, business logic means decisions like setting a default due date on new tasks, or only displaying tasks that are incomplete. Other examples of business logic include calculating a total cost based on product prices and tax rates, or checking whether a player has enough points to level up in a game.\nSaving and retrieving items from a database.\n\nAgain, it's possible to do all of these things in a single, massive controller, but that quickly becomes too hard to manage and test. Instead, it's common to see applications split up into two, three, or more \"layers\" or tiers that each handle one (and only one) concern. This helps keep the controllers as simple as possible, and makes it easier to test and change the business logic and database code later.\nSeparating your application this way is sometimes called a multi-tier or n-tier architecture. In some cases, the tiers (layers) are isolated in completely separate projects, but other times it just refers to how the classes are organized and used. The important thing is thinking about how to split your application into manageable pieces, and avoid having controllers or bloated classes that try to do everything.\nFor this project, you'll use two application layers: a presentation layer made up of the controllers and views that interact with the user, and a service layer that contains business logic and database code. The presentation layer already exists, so the next step is to build a service that handles to-do business logic and saves to-do items to a database.\n\nMost larger projects use a 3-tier architecture: a presentation layer, a service logic layer, and a data repository layer. A repository is a class that's only focused on database code (no business logic). In this application, you'll combine these into a single service layer for simplicity, but feel free to experiment with different ways of architecting the code.\n\nCreate an interface\nThe C# language includes the concept of interfaces, where the definition of an object's methods and properties is separate from the class that actually contains the code for those methods and properties. Interfaces make it easy to keep your classes decoupled and easy to test, as you'll see here (and later in the Automated testing chapter). You'll use an interface to represent the service that can interact with to-do items in the database.\nBy convention, interfaces are prefixed with \"I\". Create a new file in the Services directory:\nServices/ITodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\n\nnamespace AspNetCoreTodo.Services\n{\n public interface ITodoItemService\n {\n Task GetIncompleteItemsAsync();\n }\n}\n\nNote that the namespace of this file is AspNetCoreTodo.Services. Namespaces are a way to organize .NET code files, and it's customary for the namespace to follow the directory the file is stored in (AspNetCoreTodo.Services for files in the Services directory, and so on).\nBecause this file (in the AspNetCoreTodo.Services namespace) references the TodoItem class (in the AspNetCoreTodo.Models namespace), it needs to include a using statement at the top of the file to import that namespace. Without the using statement, you'll see an error like:\nThe type or namespace name 'TodoItem' could not be found (are you missing a using directive or an assembly reference?)\nSince this is an interface, there isn't any actual code here, just the definition (or method signature) of the GetIncompleteItemsAsync method. This method requires no parameters and returns a Task.\n\nIf this syntax looks confusing, think: \"a Task that contains an array of TodoItems\".\n\nThe Task type is similar to a future or a promise, and it's used here because this method will be asynchronous. In other words, the method may not be able to return the list of to-do items right away because it needs to go talk to the database first. (More on this later.)\nCreate the service class\nNow that the interface is defined, you're ready to create the actual service class. I'll cover database code in depth in the Use a database chapter, so for now you'll just fake it and always return two hard-coded items:\nServices/FakeTodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\n\nnamespace AspNetCoreTodo.Services\n{\n public class FakeTodoItemService : ITodoItemService\n {\n public Task GetIncompleteItemsAsync()\n {\n var item1 = new TodoItem\n {\n Title = \"Learn ASP.NET Core\",\n DueAt = DateTimeOffset.Now.AddDays(1)\n };\n\n var item2 = new TodoItem\n {\n Title = \"Build awesome apps\",\n DueAt = DateTimeOffset.Now.AddDays(2)\n };\n\n return Task.FromResult(new[] { item1, item2 });\n }\n }\n}\n\nThis FakeTodoItemService implements the ITodoItemService interface but always returns the same array of two TodoItems. You'll use this to test the controller and view, and then add real database code in Use a database.\n"},"chapters/mvc-basics/use-dependency-injection.html":{"url":"chapters/mvc-basics/use-dependency-injection.html","title":"运用依赖注入","keywords":"","body":"运用依赖注入\n回到 TodoController,添加一些代码以使用 ITodoItemService:\npublic class TodoController : Controller\n{\n private readonly ITodoItemService _todoItemService;\n\n public TodoController(ITodoItemService todoItemService)\n {\n _todoItemService = todoItemService;\n }\n\n public IActionResult Index()\n {\n // Get to-do items from database\n\n // Put items into a model\n\n // Pass the view to a model and render\n }\n}\n\n既然 ITodoItemService 在命名空间 Services 里,你同样需要在文件顶部添加一个 using 语句:\nusing AspNetCoreTodo.Services;\n\n这个类的第一行声明了一个私有变量,保存 ITodoItemService 的引用。这个变量可以让你在后面的 Index 方法里使用该服务(具体方法,稍后便知)。\npublic TodoController(ITodoItemService todoItemService) 这一行给类定义了一个 构造函数(constructor)。构造函数是一个特殊的方法,它会在为(本例中是 TodoController)类创建一个新的实例的时候被调用。在构造函数中加入的 ITodoItemService 参数,表示你做出如下声明:要创建一个 TodoController,你必须提供一个能匹配 ITodoItemService 接口的对象。\n\n接口如此有用的原因就在于,因为它们有助于解耦(分离)你程序里的逻辑。既然这个控制器依赖于 ITodoItemService 接口,而不是任何 特定的 类,它就不知道也不必关心实际使用的是哪个具体的类。它可以是 FakeTodoItemService,或者是其它读写数据库的类,或者别的什么类。只要它符合该接口的要求,控制器就能工作。这使你可以轻而易举地,独立测试程序的各部分。(我会在 自动化测试 一章讲解测试相关的内容。)\n\n现在,你终于可以在 action 方法里,(通过你声明的那个私有变量)使用 ITodoItemService 从服务层获取 待办事项 了:\npublic IActionResult Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n // ...\n}\n\n还记得吗? GetIncompleteItemsAsync 方法返回一个 Task。“返回一个 Task”的意思是说,该方法不能立刻给出一个结果,但是你可以使用关键字 await,以确保你的代码暂停,直到结果就绪才继续执行。\n当你编写代码访问数据库或者外部 API 服务的时候,Task 模式是很常见的,因为在数据库(或者网络)响应之前,它不可能给出实际的结果。如果你在 JavaScript 或者其它语言里使用过 promise 或者 回调函数,Task 与之如出一辙:承诺你,肯定会给出一个结果——在未来的某个时候。\n\n如果你在老式 JavaScript 里应付过 “回调地狱”,那你现在走运了。在 .NET 里使用 Task 跟依附代码打交道要容易得多,这归功于神奇的关键字 await。 await 把代码暂停在 异步(async) 操作上,而后,在底层数据库或者网络请求结束时,从暂停的地方恢复执行。就是说,你的程序并没有卡住或者阻塞住,因为它可以处理其它的请求。如果现在想不通也别担心,跟着做下去就行!\n\n目前的重点就是修改 Index 方法的签名,以返回一个 Task,代替之前的 IActionResult,并标记为 async:\npublic async Task Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n // Put items into a model\n\n // Pass the view to a model and render\n}\n\n胜利在望!你已经让 TodoController 依赖于 ITodoItemService 接口,但你还没告诉 ASP.NET Core,你想把 FakeTodoItemService 作为幕后的实际服务。可能你觉得这是理所当然的,因为你的ITodoItemService仅有这一个实现,但你后面会为同一个接口提供多个实现,所以,有必要明确指定实现。\n要声明(或者“关联”)具体的类到每个接口上,需要写在 StartUp 类的 ConfigureServices 方法里,在当前情况里,应该这么写:\nStartup.cs\npublic void ConfigureServices(IServiceCollection services)\n{\n // (... some code)\n\n services.AddMvc();\n}\n\nConfigureServices 方法负责的是把东西添加到 服务容器 里,或者 ASP.NET Core 的说法是服务的集合。 services.AddMvc 这行添加了一些服务,它们是 ASP.NET Core 系统内部依赖的(你可以试试,把这行代码注释掉)。你在应用里所需的任何其它服务,也都要在这个地方添加到服务容器里。\n把下面这行添加到ConfigureServices中的任意位置:\nservices.AddSingleton();\n\n这一行告知 ASP.NET Core,在任何时候,只要 ITodoItemService 被一个构造函数(或其它什么地方)被请求,就用这个 FakeTodoItemService。\nAddSingleton 把你的服务作为 singleton 添加进服务容器。这意味着,只有一个FakeTodoItemService的实例被创建,并在每次被请求的时候都被复用。在后面,当你写另一个服务去跟数据库交互时,你会采用一个不同的方式(叫做 scoped)。我会在 运用数据库 一章里说明原因。\n好了,当一个请求进来,将会被发送到 TodoController,当控制器需要一个ITodoItemService 时,ASP.NET Core 会在 可用服务集合 里查找并自动给出 FakeTodoItemService。因为服务是从服务容器里“注入(injected)”的,这个模式被称为 依赖注入(dependency injection)。\n\nUse dependency injection\nBack in the TodoController, add some code to work with the ITodoItemService:\npublic class TodoController : Controller\n{\n private readonly ITodoItemService _todoItemService;\n\n public TodoController(ITodoItemService todoItemService)\n {\n _todoItemService = todoItemService;\n }\n\n public IActionResult Index()\n {\n // Get to-do items from database\n\n // Put items into a model\n\n // Pass the view to a model and render\n }\n}\n\nSince ITodoItemService is in the Services namespace, you'll also need to add a using statement at the top:\nusing AspNetCoreTodo.Services;\n\nThe first line of the class declares a private variable to hold a reference to the ITodoItemService. This variable lets you use the service from the Index action method later (you'll see how in a minute).\nThe public TodoController(ITodoItemService todoItemService) line defines a constructor for the class. The constructor is a special method that is called when you want to create a new instance of a class (the TodoController class, in this case). By adding an ITodoItemService parameter to the constructor, you've declared that in order to create the TodoController, you'll need to provide an object that matches the ITodoItemService interface.\n\nInterfaces are awesome because they help decouple (separate) the logic of your application. Since the controller depends on the ITodoItemService interface, and not on any specific class, it doesn't know or care which class it's actually given. It could be the FakeTodoItemService, a different one that talks to a live database, or something else! As long as it matches the interface, the controller can use it. This makes it really easy to test parts of your application separately. I'll cover testing in detail in the Automated testing chapter.\n\nNow you can finally use the ITodoItemService (via the private variable you declared) in your action method to get to-do items from the service layer:\npublic IActionResult Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n // ...\n}\n\nRemember that the GetIncompleteItemsAsync method returned a Task? Returning a Task means that the method won't necessarily have a result right away, but you can use the await keyword to make sure your code waits until the result is ready before continuing on.\nThe Task pattern is common when your code calls out to a database or an API service, because it won't be able to return a real result until the database (or network) responds. If you've used promises or callbacks in JavaScript or other languages, Task is the same idea: the promise that there will be a result - sometime in the future.\n\nIf you've had to deal with \"callback hell\" in older JavaScript code, you're in luck. Dealing with asynchronous code in .NET is much easier thanks to the magic of the await keyword! await lets your code pause on an async operation, and then pick up where it left off when the underlying database or network request finishes. In the meantime, your application isn't blocked, because it can process other requests as needed. This pattern is simple but takes a little getting used to, so don't worry if this doesn't make sense right away. Just keep following along!\n\nThe only catch is that you need to update the Index method signature to return a Task instead of just IActionResult, and mark it as async:\npublic async Task Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n // Put items into a model\n\n // Pass the view to a model and render\n}\n\nYou're almost there! You've made the TodoController depend on the ITodoItemService interface, but you haven't yet told ASP.NET Core that you want the FakeTodoItemService to be the actual service that's used under the hood. It might seem obvious right now since you only have one class that implements ITodoItemService, but later you'll have multiple classes that implement the same interface, so being explicit is necessary.\nDeclaring (or \"wiring up\") which concrete class to use for each interface is done in the ConfigureServices method of the Startup class. Right now, it looks something like this:\nStartup.cs\npublic void ConfigureServices(IServiceCollection services)\n{\n // (... some code)\n\n services.AddMvc();\n}\n\nThe job of the ConfigureServices method is adding things to the service container, or the collection of services that ASP.NET Core knows about. The services.AddMvc line adds the services that the internal ASP.NET Core systems need (as an experiment, try commenting out this line). Any other services you want to use in your application must be added to the service container here in ConfigureServices.\nAdd the following line anywhere inside the ConfigureServices method:\nservices.AddSingleton();\n\nThis line tells ASP.NET Core to use the FakeTodoItemService whenever the ITodoItemService interface is requested in a constructor (or anywhere else).\nAddSingleton adds your service to the service container as a singleton. This means that only one copy of the FakeTodoItemService is created, and it's reused whenever the service is requested. Later, when you write a different service class that talks to a database, you'll use a different approach (called scoped) instead. I'll explain why in the Use a database chapter.\nThat's it! When a request comes in and is routed to the TodoController, ASP.NET Core will look at the available services and automatically supply the FakeTodoItemService when the controller asks for an ITodoItemService. Because the services are \"injected\" from the service container, this pattern is called dependency injection.\n"},"chapters/mvc-basics/finish-controller.html":{"url":"chapters/mvc-basics/finish-controller.html","title":"完成控制器","keywords":"","body":"完成控制器\n最后一步,让我们来完成控制器的编码。控制器现在已经从 服务层 获取到一个 待办事项 的列表,它应该把这些条目放进一个 TodoViewModel,并把该 模型 与你先前创建的 视图 绑定:\nControllers/TodoController.cs\npublic async Task Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n var model = new TodoViewModel()\n {\n Items = items\n };\n\n return View(model);\n}\n\n如果你还没在文件顶部添加 using 语句,现在加上:\nusing AspNetCoreTodo.Services;\nusing AspNetCoreTodo.Models;\n\n如果你用的是 Visual Studio 或者 Visual Studio Code,当你鼠标指针指向一个红色波浪线时,编辑器会提示你添加这些 using 语句。\n测试一下\n按 F5 启动程序(如果你用的是 Visual Studio 或者 Visual Studio Code),或者在终端窗口里运行 dotnet run。如果代码通过编译而没有报错,服务器将在默认的 5000 端口上运行。\n如果你的网络浏览器没自动弹出来,打开它,浏览 http://localhost:5000/todo 。你会看到自己创建的视图,展示着(暂时)从伪数据库层提取的数据。\n尽管可以径直浏览 http://localhost:5000/todo,但如果导航栏上有一个 我的待办事项 条目就更好了。要达成这个目的,你可以去编辑共享的布局文件。\n\nFinish the controller\nThe last step is to finish the controller code. The controller now has a list of to-do items from the service layer, and it needs to put those items into a TodoViewModel and bind that model to the view you created earlier:\nControllers/TodoController.cs\npublic async Task Index()\n{\n var items = await _todoItemService.GetIncompleteItemsAsync();\n\n var model = new TodoViewModel()\n {\n Items = items\n };\n\n return View(model);\n}\n\nIf you haven't already, make sure these using statements are at the top of the file:\nusing AspNetCoreTodo.Services;\nusing AspNetCoreTodo.Models;\n\nIf you're using Visual Studio or Visual Studio Code, the editor will suggest these using statements when you put your cursor on a red squiggly line.\nTest it out\nTo start the application, press F5 (if you're using Visual Studio or Visual Studio Code), or just type dotnet run in the terminal. If the code compiles without errors, the server will start up on port 5000 by default.\nIf your web browser didn't open automatically, open it and navigate to http://localhost:5000/todo. You'll see the view you created, with the data pulled from your fake database (for now).\nAlthough it's possible to go directly to http://localhost:5000/todo, it would be nicer to add an item called My to-dos to the navbar. To do this, you can edit the shared layout file.\n"},"chapters/mvc-basics/update-the-layout.html":{"url":"chapters/mvc-basics/update-the-layout.html","title":"修改布局","keywords":"","body":"修改布局\n位于 Views/Shared/_Layout.cshtml 的布局文件里面存放着所有视图的“基础”HTML。其中就包括导航栏,它被显示在每个页面的顶端。\n为了向导航栏添加新条目,请先找到原有导航栏的 HTML 代码:\nViews/Shared/_Layout.cshtml\n\n \n Home\n \n \n About\n \n \n Contact\n \n\n\n添加你的条目,不要指向 Home 控制器,而要改为指向 Todo:\n\n My to-dos\n\n\n 元素中的属性 asp-controller 和 asp-action 被称为 tag helper。在视图被渲染之前,ASP.NET Core 会把这些 tag helper 替换成真正的 HTML 属性。在本例中,会生成一个指向路由 /Todo/Index 的 URL 并作为 href 添加到 元素中。这意味着你不必硬编码这个指向 TodoController 的路由。而是 ASP.NET Core 自动为你生成。\n\n如果你在 ASP.NET 4.x 中用过 Razor,应该会注意到一些语法的差异。生成一个指向 action 链接的时候,tag helper 是现在的建议的方式,而不是使用 @Html.ActionLink()。tag helper 对表单也很有用(你会在后续章节明白原委)。要学习其它的 tag helper,可以参考位于 https://docs.asp.net 的文档。\n\n\nUpdate the layout\nThe layout file at Views/Shared/_Layout.cshtml contains the \"base\" HTML for each view. This includes the navbar, which is rendered at the top of each page.\nTo add a new item to the navbar, find the HTML code for the existing navbar items:\nViews/Shared/_Layout.cshtml\n\n \n Home\n \n \n About\n \n \n Contact\n \n\n\nAdd your own item that points to the Todo controller instead of Home:\n\n My to-dos\n\n\nThe asp-controller and asp-action attributes on the element are called tag helpers. Before the view is rendered, ASP.NET Core replaces these tag helpers with real HTML attributes. In this case, a URL to the /Todo/Index route is generated and added to the element as an href attribute. This means you don't have to hard-code the route to the TodoController. Instead, ASP.NET Core generates it for you automatically.\n\nIf you've used Razor in ASP.NET 4.x, you'll notice some syntax changes. Instead of using @Html.ActionLink() to generate a link to an action, tag helpers are now the recommended way to create links in your views. Tag helpers are useful for forms, too (you'll see why in a later chapter). You can learn about other tag helpers in the documentation at https://docs.asp.net.\n\n"},"chapters/add-external-packages/":{"url":"chapters/add-external-packages/","title":"添加外来软件包","keywords":"","body":"添加外来软件包\n选择诸如 .NET 这种成熟的生态系统,其最大的优势之一,就是第三方软件包和插件的量非常庞大。正如其它的软件包系统一样,你可以下载并安装 .NET 软件包,以获取协助,来完成几乎任何能想到的任务和难题。\nNuGet 即是包管理工具,也是官方的软件包仓库(位于 https://www.nuget.org)。你可以在网页上检索 NuGet 软件包,并在自己的机器上使用终端(或者 Visual Studio 里的图形界面)安装它们。\n安装软件包 Humanizer\n上一章结尾处,待办事项 程序展示的 待办事项条目 看起来是这样的:\n\n“截止日期”一栏所展示的日期,这种格式(叫做 ISO 8601)对机器来说很方便,但是人类看着就不爽了。如果看到的是“还剩 X 天”这样,不是更好吗?\n你完全可以自己写一段代码,把一个日期转换成更人性化的字符串,不过幸运的是,还有个更便捷的方法。\nNuGet 上的软件包 Humanizer (https://www.nuget.org/packages/Humanizer) 解决了这种问题,它提供的方法可以“人性化(humanize)” 或者说 改写 几乎任何东西:日期、时间、时长、数字等等。它是个很好很有用的开源项目,根据 MIT 许可证发布。\n要把它加入到你的项目里,在终端窗口运行这个命令:\ndotnet add package Humanizer\n如果你浏览项目文件 AspNetCoreTodo.csproj,会看到新增了一行 PackageReference,引用了 Humanizer。\n在视图中使用 Humanizer\n要在代码里使用一个软件包,你通常需要在文件顶端添加一个 using 语句,以导入该软件包的内容。\n既然 Humanizer 将用于在视图中改写日期,你可以直接在视图里使用它。首先在视图顶端添加一个 @using 语句:\nViews/Todo/Index.cshtml\n@model TodoViewModel\n@using Humanizer\n\n// ...\n\n然后,修改那行写着 DueAt 方法的代码,使用 Humanizer 里的 Humanize 方法:\n@item.DueAt.Humanize()\n\n现在,日期的可读性大大提高了:\n\nNuGet 上有着大量的软件包,从 XML解析 到 机器学习 到 Twitter发帖,包罗万象。ASP.NET Core 自身,在表象之下,也只不过是添加到你项目里的一个 NuGet 软件包集合。\n\n使用 dotnet new mvc 创建的项目文件包含一条指向Microsoft.AspNetCore.All软件包的引用,这是个便捷的“元软件包(metapackage)”,它引用了你在项目中所需的所有其它 ASP.NET Core 软件包。这样,你就不必在项目文件里添加数百个软件包的引用了。\n\n下一章里,你将使用另一套 NuGet 软件包(一个叫 Entity Framework Core 的系统),编写代码与数据库进行交互。\n\nAdd external packages\nOne of the big advantages of using a mature ecosystem like .NET is that the number of third-party packages and plugins is huge. Just like other package systems, you can download and install .NET packages that help with almost any task or problem you can imagine.\nNuGet is both the package manager tool and the official package repository (at https://www.nuget.org). You can search for NuGet packages on the web, and install them from your local machine through the terminal (or the GUI, if you're using Visual Studio).\nInstall the Humanizer package\nAt the end of the last chapter, the to-do application displayed to-do items like this:\n\nThe due date column is displaying dates in a format that's good for machines (called ISO 8601), but clunky for humans. Wouldn't it be nicer if it simply read \"X days from now\"?\nYou could write code yourself that converted an ISO 8601 date into a human-friendly string, but fortunately, there's a faster way.\nThe Humanizer package on NuGet solves this problem by providing methods that can \"humanize\" or rewrite almost anything: dates, times, durations, numbers, and so on. It's a fantastic and useful open-source project that's published under the permissive MIT license.\nTo add it to your project, run this command in the terminal:\ndotnet add package Humanizer\nIf you peek at the AspNetCoreTodo.csproj project file, you'll see a new PackageReference line that references Humanizer.\nUse Humanizer in the view\nTo use a package in your code, you usually need to add a using statement that imports the package at the top of the file.\nSince Humanizer will be used to rewrite dates rendered in the view, you can use it directly in the view itself. First, add a @using statement at the top of the view:\nViews/Todo/Index.cshtml\n@model TodoViewModel\n@using Humanizer\n\n// ...\n\nThen, update the line that writes the DueAt property to use Humanizer's Humanize method:\n@item.DueAt.Humanize()\n\nNow the dates are much more readable:\n\nThere are packages available on NuGet for everything from parsing XML to machine learning to posting to Twitter. ASP.NET Core itself, under the hood, is nothing more than a collection of NuGet packages that are added to your project.\n\nThe project file created by dotnet new mvc includes a single reference to the Microsoft.AspNetCore.All package, which is a convenient \"metapackage\" that references all of the other ASP.NET Core packages you need for a typical project. That way, you don't need to have hundreds of package references in your project file.\n\nIn the next chapter, you'll use another set of NuGet packages (a system called Entity Framework Core) to write code that interacts with a database.\n"},"chapters/use-a-database/":{"url":"chapters/use-a-database/","title":"运用数据库","keywords":"","body":"运用数据库\n与数据库交互的代码写起来坑很多。除非你对其了如指掌,否则在程序代码里粘贴 SQL 查询字符串就是个糟糕的决定。一个 对象-关系 映射(object-relational mapper) (ORM)在你的代码和数据库之间添加一个抽象层,并以此简化了与数据库交互代码的编写。Java 中的 Hibernate 和 Ruby 中的 ActiveRecord 就是广为人知的 ORM。\n.NET 上有多个 ORM,其中有一个由微软开发,并默认包含在 ASP.NET Core 中,这就是 Entity Framework Core。Entity Framework Core 支持多个不同类型的数据库,并允许你使用 C# 代码创建数据库查询语句,查询结果映射回 C# 模型(POCO)。\n\n还记得创建服务接口以解耦控制器和服务的实现类吗?Entity Framework Core 就像一个数据库上的大型接口。你的 C# 代码可以于具体的数据库实现无关,你可以根据底层以来的数据库技术更换不同的 provider。\n\nEntity Framework Core 可以连接到 SQL Server、PostgreSQL 和 MySQL 这种关系型数据库,也可以与 Mongo 这种 NoSQL(文档) 数据库协作。在本项目的开发过程中,你将使用一个 SQLite 数据库,以简化安装和配置的工作。\n\nUse a database\nWriting database code can be tricky. Unless you really know what you're doing, it's a bad idea to paste raw SQL query strings into your application code. An object-relational mapper (ORM) makes it easier to write code that interacts with a database by adding a layer of abstraction between your code and the database itself. Hibernate in Java and ActiveRecord in Ruby are two well-known ORMs.\nThere are a number of ORMs for .NET, including one built by Microsoft and included in ASP.NET Core by default: Entity Framework Core. Entity Framework Core makes it easy to connect to a number of different database types, and lets you use C# code to create database queries that are mapped back into C# models (POCOs).\n\nRemember how creating a service interface decoupled the controller code from the actual service class? Entity Framework Core is like a big interface over your database. Your C# code can stay database-agnostic, and you can swap out different providers depending on the underlying database technology.\n\nEntity Framework Core can connect to relational databases like SQL Server, PostgreSQL, and MySQL, and also works with NoSQL (document) databases like Mongo. During development, you'll use SQLite in this project to make things easy to set up.\n"},"chapters/use-a-database/connect-to-a-database.html":{"url":"chapters/use-a-database/connect-to-a-database.html","title":"连接数据库","keywords":"","body":"连接数据库\n通过 Entity Framework Core 连接数据库,需要做一些准备工作。因为你通过 dotnet new 让项目使用了 MVC + Individual认证 项目模板,这些准备已经就绪了:\n\nEntity Framework Core包 这些都默认包括在了所有 ASP.NET Core 项目中。\n\n数据库(必须地呀) 经由 dotnet new 指令,在项目的根目录下生成了小型的 SQLite 数据库文件 app.db。 SQLite 是一个轻量级数据库引擎,可以运行在你的机器上而不必安装任何额外工具,所以在开发环境下使用起来既方便又快捷。\n\n数据库上下文 数据库上下文(database context)是一个 C# 类提供的数据库入口点。 你的代码就是通过它与数据库交互,进行读写的。Data/ApplicationDbContext.cs 文件里,就保存着一个很基本的数据库上下文。\n\n连接字符串 无论你连接本地文件数据库(SQLite)还是位于其它主机的数据库,都需要定义一个字符串,其中包含 数据库的名字 或 用来连接的数据库地址。 这一项已经在 appsettings.json 文件里为你设置好了: SQLite 数据库的 连接字符串 是 DataSource=app.db。\n\n\nEntity Framework Core 借助 数据库上下文、连接字符串 与数据库建立连接。你需要在 Startup 类里的 ConfigureServices 方法中为 Entity Framework Core 指定所用的 数据库上下文、连接字符串和数据库类型。感谢项目模板:\nservices.AddDbContext(options =>\n options.UseSqlite(\n Configuration.GetConnectionString(\"DefaultConnection\")));\n\n这段代码把 ApplicationDbContext 添加到服务容器里,并通过配置(appsettings.json)中的 连接字符串 指定 Entity Framework Core 使用 SQLite 数据库。\n如你所见,dotnet new 为你完成了很多工作! 数据库已经配置好待用了。但是还没有表用于保存 待办事项条目。为了能存储 TodoItem 实体,你需要修改数据库上下文,并对数据库进行变更。\n\nConnect to a database\nThere are a few things you need to use Entity Framework Core to connect to a database. Since you used dotnet new and the MVC + Individual Auth template to set your project, you've already got them:\n\nThe Entity Framework Core packages. These are included by default in all ASP.NET Core projects.\n\nA database (naturally). The app.db file in the project root directory is a small SQLite database created for you by dotnet new. SQLite is a lightweight database engine that can run without requiring you to install any extra tools on your machine, so it's easy and quick to use in development.\n\nA database context class. The database context is a C# class that provides an entry point into the database. It's how your code will interact with the database to read and save items. A basic context class already exists in the Data/ApplicationDbContext.cs file.\n\nA connection string. Whether you are connecting to a local file database (like SQLite) or a database hosted elsewhere, you'll define a string that contains the name or address of the database to connect to. This is already set up for you in the appsettings.json file: the connection string for the SQLite database is DataSource=app.db.\n\n\nEntity Framework Core uses the database context, together with the connection string, to establish a connection to the database. You need to tell Entity Framework Core which context, connection string, and database provider to use in the ConfigureServices method of the Startup class. Here's what's defined for you, thanks to the template:\nservices.AddDbContext(options =>\n options.UseSqlite(\n Configuration.GetConnectionString(\"DefaultConnection\")));\n\nThis code adds the ApplicationDbContext to the service container, and tells Entity Framework Core to use the SQLite database provider, with the connection string from configuration (appsettings.json).\nAs you can see, dotnet new creates a lot of stuff for you! The database is set up and ready to be used. However, it doesn't have any tables for storing to-do items. In order to store your TodoItem entities, you'll need to update the context and migrate the database.\n"},"chapters/use-a-database/update-context.html":{"url":"chapters/use-a-database/update-context.html","title":"修改数据库上下文","keywords":"","body":"修改数据库上下文\n数据库上下文这边所需的工作不多:\nData/ApplicationDbContext.cs\npublic class ApplicationDbContext \n : IdentityDbContext\n{\n public ApplicationDbContext(\n DbContextOptions options)\n : base(options)\n {\n }\n\n protected override void OnModelCreating(ModelBuilder builder)\n {\n base.OnModelCreating(builder);\n // ...\n }\n}\n\n在构造函数的下方,为 ApplicationDbContext 添加一个 DbSet 属性:\npublic ApplicationDbContext(\n DbContextOptions options)\n : base(options)\n{\n}\n\npublic DbSet Items { get; set; }\n\n// ...\n\nDbSet 代表数据库里的 表 或者 集合。创建一个名为 Items 的 DbSet 属性,可以让 Entity Framework Core 知道,你需要在一个名为 Items 的表里保存 TodoItem 实体。\n你修改了 数据库上下文 的类,却产生了一个小问题: 现在上下文和数据库不同步了,因为数据库里实际上并不存在 Items 这个表。(对数据库上下文代码的修改,并不会改变数据库本身。)\n为了把“数据库上下文中的改动”反映到数据库里,你需要创建一个 变更(migration)。\n\n如果你已经有一个现存的数据库,请在网络上搜索“scaffold-dbcontext existing database”相关的内容,并阅读微软的关于使用 Scaffold-DbContext 工具的文档,以此对你的数据库进行逆向工程,自动地为数据库结构生成相应的 DbContext 和模型类。\n\n\nUpdate the context\nThere's not a whole lot going on in the database context yet:\nData/ApplicationDbContext.cs\npublic class ApplicationDbContext \n : IdentityDbContext\n{\n public ApplicationDbContext(\n DbContextOptions options)\n : base(options)\n {\n }\n\n protected override void OnModelCreating(ModelBuilder builder)\n {\n base.OnModelCreating(builder);\n // ...\n }\n}\n\nAdd a DbSet property to the ApplicationDbContext, right below the constructor:\npublic ApplicationDbContext(\n DbContextOptions options)\n : base(options)\n{\n}\n\npublic DbSet Items { get; set; }\n\n// ...\n\nA DbSet represents a table or collection in the database. By creating a DbSet property called Items, you're telling Entity Framework Core that you want to store TodoItem entities in a table called Items.\nYou've updated the context class, but now there's one small problem: the context and database are now out of sync, because there isn't actually an Items table in the database. (Just updating the code of the context class doesn't change the database itself.)\nIn order to update the database to reflect the change you just made to the context, you need to create a migration.\n\nIf you already have an existing database, search the web for \"scaffold-dbcontext existing database\" and read Microsoft's documentation on using the Scaffold-DbContext tool to reverse-engineer your database structure into the proper DbContext and model classes automatically.\n\n"},"chapters/use-a-database/create-migration.html":{"url":"chapters/use-a-database/create-migration.html","title":"创建变更","keywords":"","body":"创建变更\n变更按时间记录着数据库结构的变化。它们使以下的操作成为可能:撤销(回滚)一部分修改,或创建一个新的数据库——与原有数据库结构一致。有了变更,你有一个完整的数据库历史,记录着对数据库的修改,例如添加或删除字段(以及整个表)。\n上一章节里,你在数据库上下文里添加了一个 Items 集合。既然现在数据库上下文里包括了一个集合(或者说表),而数据库里没有它,你就需要创建一个变更来修改数据库:\ndotnet ef migrations add AddItems\n这行代码通过检查你在数据库上下文里所做的修改,创建了一个新的变更,名为 AddItems。\n\n如果你看到这样的报错: No executable found matching command \"dotnet-ef\",请确保在正确的目录下。 这些命令必须在项目的根目录下执行(Program.cs所在目录)。\n译者注:如果你使用 3.0 或以上版本的 SDK,需要手动安装 dotnet-ef 工具,原因请参考 dotnet ef not found in .NET Core 3,使用如下命令进行安装。\n\ndotnet tool install --global dotnet-ef\n\n如果你打开 Data/Migrations 目录,你将会看到:\n\n第一个变更文件(00_CreateIdentitySchema.cs),是在你执行 dotnet new 的时候创建并应用的。 变更 AddItem 带有你创建它时候的时间戳。\n\n你可以用 dotnet ef migrations list 命令查看一个变更的列表。\n\n如果你打开一个变更文件,可以看到两个方法,名字分别是 Up 和 Down:\nData/Migrations/_AddItems.cs\nprotected override void Up(MigrationBuilder migrationBuilder)\n{\n // (... some code)\n\n migrationBuilder.CreateTable(\n name: \"Items\",\n columns: table => new\n {\n Id = table.Column(nullable: false),\n DueAt = table.Column(nullable: true),\n IsDone = table.Column(nullable: false),\n Title = table.Column(nullable: true)\n },\n constraints: table =>\n {\n table.PrimaryKey(\"PK_Items\", x => x.Id);\n });\n\n // (some code...)\n}\n\nprotected override void Down(MigrationBuilder migrationBuilder)\n{\n // (... some code)\n\n migrationBuilder.DropTable(\n name: \"Items\");\n\n // (some code...)\n}\n\n将变更应用到数据库时 Up 方法将会被执行。因为你在数据库上下文里添加了一个 DbSet ,应用变更时 Entity Framework Core 会创建一个 Items 表(其列与 TodoItem 相匹配)。\n Down 方法刚好相反:当你需要撤销(回滚)变更时,Items 表将会被丢弃。\n绕开 SQLite 的局限性\n如果你按原样执行变更,会遭遇 SQLite 数据库的局限性带来的问题,要修复它,可以这样绕开:\n\n在 Up 方法里注释掉或删除 migrationBuilder.AddForeignKey 那些行。\n在 Down 方法里注释掉或删除 migrationBuilder.DropForeignKey 那些行。\n\n如果你使用完善的数据库,如 SQL Server 或者 MySQL,就不需要这样(有点旁门左道的)绕弯了。\n应用变更\n创建变更的最后一步,就是要应用它(们)到数据库中:\ndotnet ef database update\n这条命令会导致 Entity Framework Core 在数据库中创建 Items 表。\n\n如果你想回滚数据库,你可以提供 上一个 迁移的名称:dotnet ef database update CreateIdentitySchema 这将运行所有迟于你指定变更的 Down 方法。如果你需要完整的抹掉数据库并重新开始,运行 dotnet ef database drop 然后运行 dotnet ef database update,重新搭建数据库并应用到到当前的变更。\n\n搞定! 数据库和上下文都已就绪。接下来,你将在服务层使用上下文。\n\nCreate a migration\nMigrations keep track of changes to the database structure over time. They make it possible to undo (roll back) a set of changes, or create a second database with the same structure as the first. With migrations, you have a full history of modifications like adding or removing columns (and entire tables).\nIn the previous chapter, you added an Items set to the context. Since the context now includes a set (or table) that doesn't exist in the database, you need to create a migration to update the database:\ndotnet ef migrations add AddItems\nThis creates a new migration called AddItems by examining any changes you've made to the context.\n\nIf you get an error like No executable found matching command \"dotnet-ef\", make sure you're in the right directory. These commands must be run from the project root directory (where the Program.cs file is).\n\nIf you open up the Data/Migrations directory, you'll see a few files:\n\nThe first migration file (with a name like 00_CreateIdentitySchema.cs) was created and applied for you way back when you ran dotnet new. Your new AddItem migration is prefixed with a timestamp when you create it.\n\nYou can see a list of migrations with dotnet ef migrations list.\n\nIf you open your migration file, you'll see two methods called Up and Down:\nData/Migrations/_AddItems.cs\nprotected override void Up(MigrationBuilder migrationBuilder)\n{\n // (... some code)\n\n migrationBuilder.CreateTable(\n name: \"Items\",\n columns: table => new\n {\n Id = table.Column(nullable: false),\n DueAt = table.Column(nullable: true),\n IsDone = table.Column(nullable: false),\n Title = table.Column(nullable: true)\n },\n constraints: table =>\n {\n table.PrimaryKey(\"PK_Items\", x => x.Id);\n });\n\n // (some code...)\n}\n\nprotected override void Down(MigrationBuilder migrationBuilder)\n{\n // (... some code)\n\n migrationBuilder.DropTable(\n name: \"Items\");\n\n // (some code...)\n}\n\nThe Up method runs when you apply the migration to the database. Since you added a DbSet to the database context, Entity Framework Core will create an Items table (with columns that match a TodoItem) when you apply the migration.\nThe Down method does the opposite: if you need to undo (roll back) the migration, the Items table will be dropped.\nWorkaround for SQLite limitations\nThere are some limitations of SQLite that get in the way if you try to run the migration as-is. Until this problem is fixed, use this workaround:\n\nComment out or remove the migrationBuilder.AddForeignKey lines in the Up method.\nComment out or remove any migrationBuilder.DropForeignKey lines in the Down method.\n\nIf you use a full-fledged SQL database, like SQL Server or MySQL, this won't be an issue and you won't need to do this (admittedly hackish) workaround.\nApply the migration\nThe final step after creating one (or more) migrations is to actually apply them to the database:\ndotnet ef database update\nThis command will cause Entity Framework Core to create the Items table in the database.\n\nIf you want to roll back the database, you can provide the name of the previous migration:\ndotnet ef database update CreateIdentitySchema\nThis will run the Down methods of any migrations newer than the migration you specify.\nIf you need to completely erase the database and start over, run dotnet ef database drop followed by dotnet ef database update to re-scaffold the database and bring it up to the current migration.\n\nThat's it! Both the database and the context are ready to go. Next, you'll use the context in your service layer.\n"},"chapters/use-a-database/create-service-class.html":{"url":"chapters/use-a-database/create-service-class.html","title":"创建服务类","keywords":"","body":"创建服务类\n回顾 MVC基础 章节, 你创建了一个 FakeTodoItemService,其中包含硬编码的 待办事项。现在你有了数据库上下文,就可以创建一个新的服务类,从而借助 Entity Framework Core 从数据库中获取真实内容。\n删除文件 FakeTodoItemService.cs,并创建一个新文件:\nServices/TodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Data;\nusing AspNetCoreTodo.Models;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace AspNetCoreTodo.Services\n{\n public class TodoItemService : ITodoItemService\n {\n private readonly ApplicationDbContext _context;\n\n public TodoItemService(ApplicationDbContext context)\n {\n _context = context;\n }\n\n public async Task GetIncompleteItemsAsync()\n {\n var items = await _context.Items\n .Where(x => x.IsDone == false)\n .ToArrayAsync();\n return items;\n }\n }\n}\n\n你应该注意到相同的依赖注入模式,如你在 MVC基础 章节所见到的那样,只是这次被注入的服务是 ApplicationDbContext。ApplicationDbContext 已经在ConfigureServices 方法里被添加到服务容器里,所以在这里可以直接使用。\n让我们仔细探究 GetIncompleteItemsAsync 方法的代码。首先,它用数据库上下文中的 Items 的属性获取 DbSet 中所有的 待办事项:\nvar items = await _context.Items\n\n然后,Where 用于过滤出所有“未完成”的条目:\n.Where(x => x.IsDone == false)\n\nWhere 方法来自 C# 里的一个名为 LINQ(language integrated query) 的特性,它受到函数式编程的启发,简化了在程序代码里数据库查询的写法。在底层,Entity Framework Core 把这个方法翻译成一个类似的语句 SELECT * FROM Items WHERE IsDone = 0,或在 NoSQL数据库 里的一个等效查询。\n最后,ToArrayAsync 方法吩咐 Entity Framework Core 取出所有过滤后的数据,并作为一个数组返回。ToArrayAsync 是异步的(返回一个 Task),所以必须执行一次 await(等待) 以获取其中的值。\n如果想使这个方法变简短一点,你可以删除中间变量 items,直接返回查询结果(跟原来功能一样):\npublic async Task GetIncompleteItemsAsync()\n{\n return await _context.Items\n .Where(x => x.IsDone == false)\n .ToArrayAsync();\n}\n\n修改服务容器\n由于你删除了 FakeTodoItemService 类,就需要修改 ConfigureServices 方法里配置ITodoItemService 接口的那一行:\nservices.AddScoped();\n\nAddScoped 会以 scoped 的生命周期把你的服务添加到容器里。这意味着每次 web 请求中,一个 TodoItemService 类的新实例就会被创建出来。这对于那些跟数据库打交道的类来说,是必要的。\n\n添加一个服务类去跟 Entity Framework Core(以及你的数据库)打交道,如果用单件(或其它)生命周期会引发麻烦,原因在于 Entity Framework Core 底层以请求为单位管数据库连接。要避免这些问题,请在跟 Entity Framework Core 打交道的服务上,始终采用 scoped 生命周期。\n\n依赖于被注入的 ITodoItemService 的 TodoController 将幸福地对这个变化毫无察觉,但在底层,你将使用 Entity Framework Core 与真实的数据库进行交互!\n试试看\n启动程序并导航至 http://localhost:5000/todo。硬编码的那些条目不见了,你的程序对数据库发起了真正的查询。数据库里刚好还没有任何已存的 待办事项条目,所以页面目前还是空白的。\n下一章,你将在程序中添加更多的功能,从“创建新 待办事项 的能力”开始。\n\nCreate a new service class\nBack in the MVC basics chapter, you created a FakeTodoItemService that contained hard-coded to-do items. Now that you have a database context, you can create a new service class that will use Entity Framework Core to get the real items from the database.\nDelete the FakeTodoItemService.cs file, and create a new file:\nServices/TodoItemService.cs\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Data;\nusing AspNetCoreTodo.Models;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace AspNetCoreTodo.Services\n{\n public class TodoItemService : ITodoItemService\n {\n private readonly ApplicationDbContext _context;\n\n public TodoItemService(ApplicationDbContext context)\n {\n _context = context;\n }\n\n public async Task GetIncompleteItemsAsync()\n {\n var items = await _context.Items\n .Where(x => x.IsDone == false)\n .ToArrayAsync();\n return items;\n }\n }\n}\n\nYou'll notice the same dependency injection pattern here that you saw in the MVC basics chapter, except this time it's the ApplicationDbContext that's getting injected. The ApplicationDbContext is already being added to the service container in the ConfigureServices method, so it's available for injection here.\nLet's take a closer look at the code of the GetIncompleteItemsAsync method. First, it uses the Items property of the context to access all the to-do items in the DbSet:\nvar items = await _context.Items\n\nThen, the Where method is used to filter only the items that are not complete:\n.Where(x => x.IsDone == false)\n\nThe Where method is a feature of C# called LINQ (language integrated query), which takes inspiration from functional programming and makes it easy to express database queries in code. Under the hood, Entity Framework Core translates the Where method into a statement like SELECT * FROM Items WHERE IsDone = 0, or an equivalent query document in a NoSQL database.\nFinally, the ToArrayAsync method tells Entity Framework Core to get all the entities that matched the filter and return them as an array. The ToArrayAsync method is asynchronous (it returns a Task), so it must be awaited to get its value.\nTo make the method a little shorter, you can remove the intermediate items variable and just return the result of the query directly (which does the same thing):\npublic async Task GetIncompleteItemsAsync()\n{\n return await _context.Items\n .Where(x => x.IsDone == false)\n .ToArrayAsync();\n}\n\nUpdate the service container\nBecause you deleted the FakeTodoItemService class, you'll need to update the line in ConfigureServices that is wiring up the ITodoItemService interface:\nservices.AddScoped();\n\nAddScoped adds your service to the service container using the scoped lifecycle. This means that a new instance of the TodoItemService class will be created during each web request. This is required for service classes that interact with a database.\n\nAdding a service class that interacts with Entity Framework Core (and your database) with the singleton lifecycle (or other lifecycles) can cause problems, because of how Entity Framework Core manages database connections per request under the hood. To avoid that, always use the scoped lifecycle for services that interact with Entity Framework Core.\n\nThe TodoController that depends on an injected ITodoItemService will be blissfully unaware of the change in services classes, but under the hood it'll be using Entity Framework Core and talking to a real database!\nTest it out\nStart up the application and navigate to http://localhost:5000/todo. The fake items are gone, and your application is making real queries to the database. There doesn't happen to be any saved to-do items, so it's blank for now.\nIn the next chapter, you'll add more features to the application, starting with the ability to create new to-do items.\n"},"chapters/add-more-features/":{"url":"chapters/add-more-features/","title":"添加新特性","keywords":"","body":"添加新特性\n现在,你借助 Entity Framework Core 连接到了数据库,就为“给程序添加更多新特性”做好准备了。首先是这个功能:使用一个表单,添加新的待办事项条目。\n\nAdd more features\nNow that you've connected to a database using Entity Framework Core, you're ready to add some more features to the application. First, you'll make it possible to add new to-do items using a form.\n"},"chapters/add-more-features/add-todo-items.html":{"url":"chapters/add-more-features/add-todo-items.html","title":"添加 待办事项 条目","keywords":"","body":"添加 待办事项 条目\n使用列表下面那个简易的表单,用户可以添加新的 待办事项 条目:\n\n添加这个功能,需要几个步骤:\n\n在视图里添加一个 表单\n在控制器里添加一个新的 action 处理这个表单\n在服务层添加代码,对数据库进行修改\n\n添加一个表单\n视图 Todo/Index.cshtml 里有个占位符,代表 Add Item form:\n\n \n\n\n为保持各部分独立且组织良好,你应该以 局部视图(partial view) 的形式创建这个表单。局部视图是较大视图的一个小片段,存放于一个独立的文件。\n创建一个 AddItemPartial.cshtml 视图:\nViews/Todo/AddItemPartial.cshtml\n@model TodoItem\n\n\n Add a new item:\n \n Add\n\n\nasp-action 这个 tag helper 会为该表单生成一个 URL,就像你将其应用在一个 元素上那样。在本例中,asp-action 会被你创建的 AddItem 的真实地址取代:\n\n\n在 元素里,添加一个 asp- tag helper 的同时会在表单里添加一个隐藏字段,其中包含一个验证标记。该验证标记可用于防止 跨站请求伪造(cross-site request forgery -- CSRF) 攻击。在你编写这个 action 的时候,会验证这个标记。\n局部视图就这样创建好了。然后,要在 Todo 主视图里引用它:\nViews/Todo/Index.cshtml\n\n @await Html.PartialAsync(\"AddItemPartial\", new TodoItem())\n\n\n添加 action\n当某个用户在你刚刚创建的表单里点击 Add,其浏览器会构建一个 POST 请求到你应用程序的 /Todo/AddItem。眼下这不会有效果,因为还没有任何 action 会处理 /Todo/AddItem 这个路由。如果你现在去尝试,ASP.NET Core 会返回一个 404 Not Found 错误。\n你需要在 TodoConteoller 中添加一个名为 AddItem 的新 action:\n[ValidateAntiForgeryToken]\npublic async Task AddItem(TodoItem newItem)\n{\n if (!ModelState.IsValid)\n {\n return RedirectToAction(\"Index\");\n }\n\n var successful = await _todoItemService.AddItemAsync(newItem);\n if (!successful)\n {\n return BadRequest(\"Could not add item.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\n注意到 AddItem action 接受一个 TodoItem 参数的方式了吗?这是你在 MVC basics 章节中创建的那个,用于存储一个 待办事项条目 相关信息的 TodoItem 模型。当它在这里作为一个 action 参数使用, ASP.NET Core 会自动执行一个称为 模型绑定 的处理流程。\n模型绑定流程会查看请求内的数据,并试图智能地把输入的字段和模型里的属性匹配起来。换句话说,当用户提交这个表单,并且浏览器 POST 到了此 action,ASP.NET Core 会从表单里提取信息,并存放到那个 newItem 变量里。\n位于 action 前面的 [ValidateAntiForgeryToken] 属性告知 ASP.NET Core 去查找(并验证)那个隐藏的验证标记,就是由 asp-action tag helper 添加到表单里的那个标记。在处理 跨站请求伪造(CSRF) 的时候,这是个重要的安全措施,你的用户可能被欺骗,以至于在一个恶意的网站上提交数据。这里的验证标记被用于确保呈现和提交表单的,是你的程序。\n再检视一次 AddItemPartial.cshtml 视图。文件顶部的 @model TodoItem 那行告知 ASP.NET Core,该视图需要配合 TodoItem 模型一起使用。它促成了以下功能,在 标签上,应用 asp-for=\"Title\",让 ASP.NET Core 知晓该 input 元素是为 Title 字段服务的。\n由于 @model 这一行的存在,此局部视图在被渲染的时候,期望被传入一个 TodoItem 对象。经由 Html.PartialAsync 传给它一个 new TodoItem,以一个空条目初始化该表单。(请尝试添加{ Title = \"hello\" },看看会发生什么!)\n在模型绑定流程中,模型里的任何属性,如果不能匹配到请求里的字段,都会被忽略掉。由于表单里仅包含一个 Title 元素,你能预见 TodoItem 上的其它属性(IsDone 标记,DueAt 日期)将为空,或者包含着一个默认值。\n\n作为复用 TodoItem 模型的替代方案,还可以创建一个独立的模型(比如叫 NewTodoItem),仅用于这个 action 中,并仅具有特定的字段(Title),用于添加新的待办事项条目。模型绑定流程依然要用到,但现在,你分离了两个模型,一个用于在数据库中存储待办事项条目,另一个用于绑定传入的请求数据。这个方案,也被称作 绑定模型(binding model) 或者 数据传输对象(data transfer object)(DTO)。这个模式常见于更大更复杂的项目。\n\n请求数据绑定到模型后,ASP.NET Core 还进行了 模型核验操作(model validation)。核验操作检查从传入请求绑定到模型的数据,鉴别其合理性和有效性。你可以在模型中添加属性,告知 ASP.NET Core 以怎样的方式进行核验。\nTitle 字段上的 [Required] 属性告知 ASP.NET Core 的模型核验器,如果标题缺失或为空,则判定其无效。看一下 action AddItem 的代码:首个代码块检查 ModelState(模型核验的结果)是否有效。习惯上,这种核验都在 action 最开始的地方进行。\nif (!ModelState.IsValid)\n{\n return RedirectToAction(\"Index\");\n}\n\n如果 ModelState 出于某种原因无效,浏览器会被重定向到路由 /Todo/Index,后者会刷新页面。\n接下来,控制器调用到服务层,进行实际的数据库操作,保存这个新的待办事项条目:\nvar successful = await _todoItemService.AddItemAsync(newItem);\nif (!successful)\n{\n return BadRequest(new { error = \"Could not add item.\" });\n}\n\n取决于该条目添加到数据库的结果成功与否,AddItemAsync 方法会返回 true 或者 false。如果该操作因为某些原因失败了,action 会连带一个包含 error 字段的对象,返回 400 Bad Request。\n最终,如果操作顺利完成,action 会将浏览器重定向到路由 /Todo/Index,后者会刷新页面并向用户显示新的待办事项列表。\n添加服务方法(函数)\n如果你使用的代码编辑器了解 C# 的语法,你会在 AddItemAsync 下面看到红色的波浪线,因为该方法尚未定义。\n作为最后一步,你需要在服务层里添加一个方法。首先,在 ITodoItemService 接口里添加它的定义:\npublic interface ITodoItemService\n{\n Task GetIncompleteItemsAsync();\n\n Task AddItemAsync(TodoItem newItem);\n}\n\n然后,在 TodoItemService 里面添加实现:\npublic async Task AddItemAsync(TodoItem newItem)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n\n _context.Items.Add(newItem);\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1;\n}\n\n字段 newItem.Title 已经由 ASP.NET Core 的模型绑定器设置,所以,这个方法仅需要分配 ID 并为其它字段设置缺省值。然后,这个新条目被加入到数据库上下文中。在调用 SaveChangesAsync() 前它尚未被保存。如果保存操作成功,SaveChangesAsync() 会返回 1。\n试试看\n运行程序,使用页面上的表单添加几个条目到 待办事项 列表里。因为这些条目存储在数据库里,就算你关闭程序后再重新运行,这些条目都还保存在那里。\n\n作为附加练习,请尝试使用 HTML 和 JavaScript 添加一个日期选择框,并让用户为 DueAt 属性选择一个(可选的)日期。然后,用这个日期替换那个默认的“3天后到期”。\n\n\nAdd new to-do items\nThe user will add new to-do items with a simple form below the list:\n\nAdding this feature requires a few steps:\n\nAdding a form to the view\nCreating a new action on the controller to handle the form\nAdding code to the service layer to update the database\n\nAdd a form\nThe Views/Todo/Index.cshtml view has a placeholder for the Add Item form:\n\n \n\n\nTo keep things separate and organized, you'll create the form as a partial view. A partial view is a small piece of a larger view that lives in a separate file.\nCreate an AddItemPartial.cshtml view:\nViews/Todo/AddItemPartial.cshtml\n@model TodoItem\n\n\n Add a new item:\n \n Add\n\n\nThe asp-action tag helper can generate a URL for the form, just like when you use it on an element. In this case, the asp-action helper gets replaced with the real path to the AddItem route you'll create:\n\n\nAdding an asp- tag helper to the element also adds a hidden field to the form containing a verification token. This verification token can be used to prevent cross-site request forgery (CSRF) attacks. You'll verify the token when you write the action.\nThat takes care of creating the partial view. Now, reference it from the main Todo view:\nViews/Todo/Index.cshtml\n\n @await Html.PartialAsync(\"AddItemPartial\", new TodoItem())\n\n\nAdd an action\nWhen a user clicks Add on the form you just created, their browser will construct a POST request to /Todo/AddItem on your application. That won't work right now, because there isn't any action that can handle the /Todo/AddItem route. If you try it now, ASP.NET Core will return a 404 Not Found error.\nYou'll need to create a new action called AddItem on the TodoController:\n[ValidateAntiForgeryToken]\npublic async Task AddItem(TodoItem newItem)\n{\n if (!ModelState.IsValid)\n {\n return RedirectToAction(\"Index\");\n }\n\n var successful = await _todoItemService.AddItemAsync(newItem);\n if (!successful)\n {\n return BadRequest(\"Could not add item.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\nNotice how the new AddItem action accepts a TodoItem parameter? This is the same TodoItem model you created in the MVC basics chapter to store information about a to-do item. When it's used here as an action parameter, ASP.NET Core will automatically perform a process called model binding.\nModel binding looks at the data in a request and tries to intelligently match the incoming fields with properties on the model. In other words, when the user submits this form and their browser POSTs to this action, ASP.NET Core will grab the information from the form and place it in the newItem variable.\nThe [ValidateAntiForgeryToken] attribute before the action tells ASP.NET Core that it should look for (and verify) the hidden verification token that was added to the form by the asp-action tag helper. This is an important security measure to prevent cross-site request forgery (CSRF) attacks, where your users could be tricked into submitting data from a malicious site. The verification token ensures that your application is actually the one that rendered and submitted the form.\nTake a look at the AddItemPartial.cshtml view once more. The @model TodoItem line at the top of the file tells ASP.NET Core that the view should expect to be paired with the TodoItem model. This makes it possible to use asp-for=\"Title\" on the tag to let ASP.NET Core know that this input element is for the Title property.\nBecause of the @model line, the partial view will expect to be passed a TodoItem object when it's rendered. Passing it a new TodoItem via Html.PartialAsync initializes the form with an empty item. (Try appending { Title = \"hello\" } and see what happens!)\nDuring model binding, any model properties that can't be matched up with fields in the request are ignored. Since the form only includes a Title input element, you can expect that the other properties on TodoItem (the IsDone flag, the DueAt date) will be empty or contain default values.\n\nInstead of reusing the TodoItem model, another approach would be to create a separate model (like NewTodoItem) that's only used for this action and only has the specific properties (Title) you need for adding a new to-do item. Model binding is still used, but this way you've separated the model that's used for storing a to-do item in the database from the model that's used for binding incoming request data. This is sometimes called a binding model or a data transfer object (DTO). This pattern is common in larger, more complex projects.\n\nAfter binding the request data to the model, ASP.NET Core also performs model validation. Validation checks whether the data bound to the model from the incoming request makes sense or is valid. You can add attributes to the model to tell ASP.NET Core how it should be validated.\nThe [Required] attribute on the Title property tells ASP.NET Core's model validator to consider the title invalid if it is missing or blank. Take a look at the code of the AddItem action: the first block checks whether the ModelState (the model validation result) is valid. It's customary to do this validation check right at the beginning of the action:\nif (!ModelState.IsValid)\n{\n return RedirectToAction(\"Index\");\n}\n\nIf the ModelState is invalid for any reason, the browser will be redirected to the /Todo/Index route, which refreshes the page.\nNext, the controller calls into the service layer to do the actual database operation of saving the new to-do item:\nvar successful = await _todoItemService.AddItemAsync(newItem);\nif (!successful)\n{\n return BadRequest(new { error = \"Could not add item.\" });\n}\n\nThe AddItemAsync method will return true or false depending on whether the item was successfully added to the database. If it fails for some reason, the action will return an HTTP 400 Bad Request error along with an object that contains an error message.\nFinally, if everything completed without errors, the action redirects the browser to the /Todo/Index route, which refreshes the page and displays the new, updated list of to-do items to the user.\nAdd a service method\nIf you're using a code editor that understands C#, you'll see red squiggely lines under AddItemAsync because the method doesn't exist yet.\nAs a last step, you need to add a method to the service layer. First, add it to the interface definition in ITodoItemService:\npublic interface ITodoItemService\n{\n Task GetIncompleteItemsAsync();\n\n Task AddItemAsync(TodoItem newItem);\n}\n\nThen, the actual implementation in TodoItemService:\npublic async Task AddItemAsync(TodoItem newItem)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n\n _context.Items.Add(newItem);\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1;\n}\n\nThe newItem.Title property has already been set by ASP.NET Core's model binder, so this method only needs to assign an ID and set the default values for the other properties. Then, the new item is added to the database context. It isn't actually saved until you call SaveChangesAsync(). If the save operation was successful, SaveChangesAsync() will return 1.\nTry it out\nRun the application and add some items to your to-do list with the form. Since the items are being stored in the database, they'll still be there even after you stop and start the application again.\n\nAs an extra challenge, try adding a date picker using HTML and JavaScript, and let the user choose an (optional) date for the DueAt property. Then, use that date instead of always making new tasks that are due in 3 days.\n\n"},"chapters/add-more-features/complete-with-checkbox.html":{"url":"chapters/add-more-features/complete-with-checkbox.html","title":"使用复选框标记条目完成","keywords":"","body":"使用复选框标记条目完成\n向 待办事项 列表里添加条目,这功能很棒,但无论如何,这些事项都得被处理掉。在 Views/Todo/Index.cshtml 视图里,为每个待办事项条目显示了一个复选框:\n\n\n点击这个复选框(还)不会导致任何结果。像上一章节一样,你要通过表单和 action 添加这一功能。在本例中,你还要写一丁点 JavaScript 代码。\n向视图添加表单元素\n首先,修改视图,并用让每个复选框都被一个 元素包含。然后,添加一个隐藏元素,其中包含条目的 ID:\nViews/Todo/Index.cshtml\n\n \n \n \n \n\n\n当视图中的 foreach 循环运行并为每个待办事项条目显示一行,每一行都会包含此表单的一个副本。隐藏的输入框包含该 待办事项条目 的 ID,以便你的控制器代码辨别是哪个复选框被选中了。(如果没有它,你只能知道 某个 复选框被选中了,而无法知道是哪个。)\n如果你现在立刻运行你的程序,复选框还是没什么作用,因为没有提交按钮通知浏览器,让它根据表单数据构建一个 POST 请求。你可以在每个复选框下面添加一个提交按钮,但这样的用户体验太蠢了。理想的方法是,点击复选框的时候,能够自动地提交该表单。你可以添加一些 JavaScript 达成这一点。\n添加 JavaScript 代码\n到 wwwroot/js 目录找到文件 site.js ,并添加如下代码:\nwwwroot/js/site.js\n$(document).ready(function() {\n\n // Wire up all of the checkboxes to run markCompleted()\n $('.done-checkbox').on('click', function(e) {\n markCompleted(e.target);\n });\n});\n\nfunction markCompleted(checkbox) {\n checkbox.disabled = true;\n\n var row = checkbox.closest('tr');\n $(row).addClass('done');\n\n var form = checkbox.closest('form');\n form.submit();\n}\n\n这段代码先使用 jQuery(一个 JavaScript 辅助库),通过 CSS 类 done-checkbox 找出页面上的所有复选框,将一些代码关联到其 click 事件。当一个复选框被点击,markCompleted() 函数就被执行。\nmarkCompleted() 函数的功能如下:\n\n添加 disabled 属性到该复选框,避免它再次被点击\n为包含该复选框的行添加 done CSS 类,这个类会基于 style.css 中的 CSS 规则,改变该行的外观\n提交该表单\n\n视图和前端代码就这样搞定了。是时候添加一个新 action 了!\n在控制器里添加 action\n正如你可能已经猜到的那样,你需要在 TodoController 里添加一个 action MarkDone:\n[ValidateAntiForgeryToken]\npublic async Task MarkDone(Guid id)\n{\n if (id == Guid.Empty)\n {\n return RedirectToAction(\"Index\");\n }\n\n var successful = await _todoItemService.MarkDoneAsync(id);\n if (!successful)\n {\n return BadRequest(\"Could not mark item as done.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\n让我们逐行分析这个 action 方法。首先,该方法接受一个名为 id 的 Guid 类型参数。参数 id 非常简单,这跟 AddItem 不同,那个 action 用了一个模型作为参数,还进行了 模型绑定/核验 的处理。如果传入的请求中包括一个名为 id 的参数, ASP.NET Core 会尝试将其解析为一个 guid。这项功能得益于你在表单里加入的那个名为 id 的隐藏元素。\n既然你没使用 模型绑定流程,就没有用于有效性检查的 ModelState。取而代之,你可以直接检查 guid 的值,以判断它的有效性。如果出于某些原因,请求中的 id 参数缺失了,或者无法解析为一个 guid,则 id 的值将是 GUID.Empty。如果这种情况发生,action 就让浏览器重定向到 /Todo/Index 并刷新页面。\n接下来,控制器需要调用服务层去修改数据库。这个功能,将要由 ITodoItemService 接口中的一个新方法 MarkDoneAsync 来实现,它会根据操作成功与否,返回 true 或者 false:\nvar successful = await _todoItemService.MarkDoneAsync(id);\nif (!successful)\n{\n return BadRequest(\"Could not mark item as done.\");\n}\n\n最终,如果一切顺利,浏览器会被重定向到 /Todo/Index,并刷新页面。\n修改过视图和控制器,剩下的就是要添加缺失的服务方法了。\n添加服务方法\n首先,在接口定义中添加 MarkDoneAsync:\nServices/ITodoItemService.cs\nTask MarkDoneAsync(Guid id);\n\n然后,在 TodoItemService 中添加具体的实现:\nServices/TodoItemService.cs\npublic async Task MarkDoneAsync(Guid id)\n{\n var item = await _context.Items\n .Where(x => x.Id == id)\n .SingleOrDefaultAsync();\n\n if (item == null) return false;\n\n item.IsDone = true;\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1; // One entity should have been updated\n}\n\n该方法使用 Entity Framework Core 和 Where() 在数据库中按 ID 查找一个条目。SingleOrDefaultAsync() 方法要么返回该条目(若存在),要么返回 null——如果找不到。\n一旦你确定 item 不是 null,设置 IsDone 属性就是小事一桩了:\nitem.IsDone = true;\n\n修改该字段仅仅影响该条目的本地拷贝,SaveChangesAsync() 被调用之后才会把修改的内容持久化到数据库里。SaveChangesAsync() 返回一个整数,表示在这次保存操作中被更新的条目的数量。在当前的情况下,它要么是1(条目更新了),要么是0(有错误发生)。\n试试看\n运行程序并勾选列表中的某些条目完成掉。刷新页面,它们将自动消失掉,这归功于 GetIncompleteItemsAsync() 方法中的 Where() 过滤器。\n现在,程序里包含一个单一、共享的待办事项列表。如果它为每个用户保存独立的列表,将会更有用。下一章,你将使用 ASP.NET Core Identity,为项目添加安全及认证等特性。\n\nComplete items with a checkbox\nAdding items to your to-do list is great, but eventually you'll need to get things done, too. In the Views/Todo/Index.cshtml view, a checkbox is rendered for each to-do item:\n\n\nClicking the checkbox doesn't do anything (yet). Just like the last chapter, you'll add this behavior using forms and actions. In this case, you'll also need a tiny bit of JavaScript code.\nAdd form elements to the view\nFirst, update the view and wrap each checkbox with a element. Then, add a hidden element containing the item's ID:\nViews/Todo/Index.cshtml\n\n \n \n \n \n\n\nWhen the foreach loop runs in the view and prints a row for each to-do item, a copy of this form will exist in each row. The hidden input containing the to-do item's ID makes it possible for your controller code to tell which box was checked. (Without it, you'd be able to tell that some box was checked, but not which one.)\nIf you run your application right now, the checkboxes still won't do anything, because there's no submit button to tell the browser to create a POST request with the form's data. You could add a submit button under each checkbox, but that would be a silly user experience. Ideally, clicking the checkbox should automatically submit the form. You can achieve that by adding some JavaScript.\nAdd JavaScript code\nFind the site.js file in the wwwroot/js directory and add this code: \nwwwroot/js/site.js\n$(document).ready(function() {\n\n // Wire up all of the checkboxes to run markCompleted()\n $('.done-checkbox').on('click', function(e) {\n markCompleted(e.target);\n });\n});\n\nfunction markCompleted(checkbox) {\n checkbox.disabled = true;\n\n var row = checkbox.closest('tr');\n $(row).addClass('done');\n\n var form = checkbox.closest('form');\n form.submit();\n}\n\nThis code first uses jQuery (a JavaScript helper library) to attach some code to the click even of all the checkboxes on the page with the CSS class done-checkbox. When a checkbox is clicked, the markCompleted() function is run.\nThe markCompleted() function does a few things:\n\nAdds the disabled attribute to the checkbox so it can't be clicked again\nAdds the done CSS class to the parent row that contains the checkbox, which changes the way the row looks based on the CSS rules in style.css\nSubmits the form\n\nThat takes care of the view and frontend code. Now it's time to add a new action!\nAdd an action to the controller\nAs you've probably guessed, you need to add an action called MarkDone in the TodoController:\n[ValidateAntiForgeryToken]\npublic async Task MarkDone(Guid id)\n{\n if (id == Guid.Empty)\n {\n return RedirectToAction(\"Index\");\n }\n\n var successful = await _todoItemService.MarkDoneAsync(id);\n if (!successful)\n {\n return BadRequest(\"Could not mark item as done.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\nLet's step through each line of this action method. First, the method accepts a Guid parameter called id in the method signature. Unlike the AddItem action, which used a model and model binding/validation, the id parameter is very simple. If the incoming request data includes a field called id, ASP.NET Core will try to parse it as a guid. This works because the hidden element you added to the checkbox form is named id.\nSince you aren't using model binding, there's no ModelState to check for validity. Instead, you can check the guid value directly to make sure it's valid. If for some reason the id parameter in the request was missing or couldn't be parsed as a guid, id will have a value of Guid.Empty. If that's the case, the action tells the browser to redirect to /Todo/Index and refresh the page.\nNext, the controller needs to call the service layer to update the database. This will be handled by a new method called MarkDoneAsync on the ITodoItemService interface, which will return true or false depending on whether the update succeeded:\nvar successful = await _todoItemService.MarkDoneAsync(id);\nif (!successful)\n{\n return BadRequest(\"Could not mark item as done.\");\n}\n\nFinally, if everything looks good, the browser is redirected to the /Todo/Index action and the page is refreshed.\nWith the view and controller updated, all that's left is adding the missing service method.\nAdd a service method\nFirst, add MarkDoneAsync to the interface definition:\nServices/ITodoItemService.cs\nTask MarkDoneAsync(Guid id);\n\nThen, add the concrete implementation to the TodoItemService:\nServices/TodoItemService.cs\npublic async Task MarkDoneAsync(Guid id)\n{\n var item = await _context.Items\n .Where(x => x.Id == id)\n .SingleOrDefaultAsync();\n\n if (item == null) return false;\n\n item.IsDone = true;\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1; // One entity should have been updated\n}\n\nThis method uses Entity Framework Core and Where() to find an item by ID in the database. The SingleOrDefaultAsync() method will either return the item or null if it couldn't be found.\nOnce you're sure that item isn't null, it's a simple matter of setting the IsDone property:\nitem.IsDone = true;\n\nChanging the property only affects the local copy of the item until SaveChangesAsync() is called to persist the change back to the database. SaveChangesAsync() returns a number that indicates how many entities were updated during the save operation. In this case, it'll either be 1 (the item was updated) or 0 (something went wrong).\nTry it out\nRun the application and try checking some items off the list. Refresh the page and they'll disappear completely, because of the Where() filter in the GetIncompleteItemsAsync() method.\nRight now, the application contains a single, shared to-do list. It'd be even more useful if it kept track of individual to-do lists for each user. In the next chapter, you'll add login and security features to the project.\n"},"chapters/security-and-identity/":{"url":"chapters/security-and-identity/","title":"安全和身份","keywords":"","body":"安全和身份\n安全性是任何现代 Web 应用或 API 都要重点关注的。确保用户或顾客的数据安全并免遭黑客染指,是非常重要的。这个话题所涉甚广,包括了:\n\n过滤输入数据,避免 SQL注入\n防止利用表单(form)进行的跨域(CSRF)攻击\n使用 HTTPS(TLS),避免在 Internet 上传输的数据被窃取\n确保用户 输入密码 或者 通过社交媒体授权 登录时的安全性\n设计 密码重置 或 多重身份认证流程 时,考虑到安全性的因素\n\nASP.NET Core 有助于实现这些功能。前两个(防止SQL注入和跨域攻击)功能已经内置了,要开启 HTTPS,只需寥寥数行代码即可。本章主要关注安全性的 身份验证(identity) 方面:管理用户的账号(注册、登录),安全地验证用户(登录),并在验证后做出授权决策。\n\n验证 和 授权 二者常被混淆。验证 关心的是用户登录与否,而 授权 关心“用户在登录 后 能否做某些事”。你可以认为 验证 是在问:“我知道这个用户是谁吗?”,而 授权 问的是:“这个用户有权限做某件事吗?”\n\n你搭建项目的时候,应用了 MVC + Individual验证 项目模板,该模板中带有几个类,构建在 ASP.NET Core Identity(一个验证和身份系统,属于 ASP.NET Core 的一部分)之上。安装后,默认添加了通过 email 和密码进行登录的功能。\nASP.NET Core Identity 是什么?\nASP.NET Core Identity 是 ASP.NET Core 带来的身份系统,就像 ASP.NET Core 生态圈中的其它部分,它也是一组 NuGet 包,可以被安装在任何项目中(并且包括在默认的模板中了)。\nASP.NET Core Identity 处理用户账号的存储、散列并保存密码、还负责管理用户的角色。它支持 邮箱地址/密码 登录、多重身份验证、集成以 Google 和 Facebook 之类的身份提供者的 社交账号登录、以及借助 OAuth 2.0 和 OpenID Connect 等协议连接到其它的服务。\n MVC + Individual验证 项目模板中的 Register 和 Login 视图 已经从 ASP.NET Core Identity 中受益,而且已经正常工作了,请试着注册一个账号并用它登录。\n\nSecurity and identity\nSecurity is a major concern of any modern web application or API. It's important to keep your user or customer data safe and out of the hands of attackers. This is a very broad topic, involving things like:\n\nSanitizing data input to prevent SQL injection attacks\nPreventing cross-domain (CSRF) attacks in forms\nUsing HTTPS (connection encryption) so data can't be intercepted as it travels over the Internet\nGiving users a way to securely sign in with a password or other credentials\nDesigning password reset, account recovery, and multi-factor authentication flows\n\nASP.NET Core can help make all of this easier to implement. The first two (protection against SQL injection and cross-domain attacks) are already built-in, and you can add a few lines of code to enable HTTPS support. This chapter will mainly focus on the identity aspects of security: handling user accounts, authenticating (logging in) your users securely, and making authorization decisions once they are authenticated.\n\nAuthentication and authorization are distinct ideas that are often confused. Authentication deals with whether a user is logged in, while authorization deals with what they are allowed to do after they log in. You can think of authentication as asking the question, \"Do I know who this user is?\" While authorization asks, \"Does this user have permission to do X?\"\n\nThe MVC + Individual Authentication template you used to scaffold the project includes a number of classes built on top of ASP.NET Core Identity, an authentication and identity system that's part of ASP.NET Core. Out of the box, this adds the ability to log in with an email and password.\nWhat is ASP.NET Core Identity?\nASP.NET Core Identity is the identity system that ships with ASP.NET Core. Like everything else in the ASP.NET Core ecosystem, it's a set of NuGet packages that can be installed in any project (and are already included if you use the default template).\nASP.NET Core Identity takes care of storing user accounts, hashing and storing passwords, and managing roles for users. It supports email/password login, multi-factor authentication, social login with providers like Google and Facebook, as well as connecting to other services using protocols like OAuth 2.0 and OpenID Connect.\nThe Register and Login views that ship with the MVC + Individual Authentication template already take advantage of ASP.NET Core Identity, and they already work! Try registering for an account and logging in.\n"},"chapters/security-and-identity/require-authentication.html":{"url":"chapters/security-and-identity/require-authentication.html","title":"提示认证","keywords":"","body":"提示认证\n在用户访问你程序中某些特定内容时,你通常都会要求他们登录。比如说,把主页向所有人展示是合理的(不管你有没有登录),但只在登录之后才向你展示待办事项列表。\nASP.NET Core 里,你可以使用 [Authorize] 属性,要求用户在访问指定的 action 或整个控制器时,要事先登录过。要为 TodoController 里的所有 action 添加认证提示,在这个控制器的第一行上面添加这个属性:\n[Authorize]\npublic class TodoController : Controller\n{\n // ...\n}\n\n在文件顶部添加这条 using 语句:\nusing Microsoft.AspNetCore.Authorization;\n\n试着运行程序并在未登录的情况下访问 /todo。你会被自动重定向到登录页面:\n\n尽管属性的名字是授权(Authorize),我们在这里检查的其实是认证(authorization),而非检查授权,很抱歉会有这样的混淆。\n\n\nRequire authentication\nOften you'll want to require the user to log in before they can access certain parts of your application. For example, it makes sense to show the home page to everyone (whether you're logged in or not), but only show your to-do list after you've logged in.\nYou can use the [Authorize] attribute in ASP.NET Core to require a logged-in user for a particular action, or an entire controller. To require authentication for all actions of the TodoController, add the attribute above the first line of the controller:\nControllers/TodoController.cs\n[Authorize]\npublic class TodoController : Controller\n{\n // ...\n}\n\nAdd this using statement at the top of the file:\nusing Microsoft.AspNetCore.Authorization;\n\nTry running the application and accessing /todo without being logged in. You'll be redirected to the login page automatically.\n\nThe [Authorize] attribute is actually doing an authentication check here, not an authorization check (despite the name of the attribute). Later, you'll use the attribute to check both authentication and authorization.\n\n"},"chapters/security-and-identity/using-identity-in-the-application.html":{"url":"chapters/security-and-identity/using-identity-in-the-application.html","title":"在程序中使用身份","keywords":"","body":"在程序中使用身份\n待办事项列表依然由所有用户共享,因为 待办事项条目 并未关联到特定的用户。现在,[Authorize] 属性确保了见到 待办事项视图 的人一定登录过,在查询数据库的时候,你就可以按照登录者的身份进行过滤了。\n首先,在 TodoController 中注入一个 UserManager:\nControllers/TodoController.cs\n[Authorize]\npublic class TodoController : Controller\n{\n private readonly ITodoItemService _todoItemService;\n private readonly UserManager _userManager;\n\n public TodoController(ITodoItemService todoItemService,\n UserManager userManager)\n {\n _todoItemService = todoItemService;\n _userManager = userManager;\n }\n\n // ...\n}\n\n还要在文件顶部加一个新的 using 语句:\nusing Microsoft.AspNetCore.Identity;\n\nUserManager 包含在 ASP.NET Core Identity 里。你可以用它在 Index action 里查找当前用户:\npublic async Task Index()\n{\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var items = await _todoItemService\n .GetIncompleteItemsAsync(currentUser);\n\n var model = new TodoViewModel()\n {\n Items = items\n };\n\n return View(model);\n}\n\n这个 action 方法的顶部添加了新代码,这行代码用 UserManager 从 User 属性中获取当前登录的用户——该属性在当前的 action 中有效:\nvar currentUser = await _userManager.GetUserAsync(User);\n\n如果当前用户已经登录, User 属性就持有一个轻量级的对象,包括了用户的一些(并非全部)信息。UserManager 使用它,通过 GetUserAsync() 方法在数据库里查找该用户的详细信息。\n因为控制器使用了 [Authorize] 属性,currentUser 的值绝不应该是 null。无论如何,做个明智的检查都没错,以防万一嘛。如果用户信息没找到,你可以用 Challenge() 方法强制用户再次登录:\nif (currentUser == null) return Challenge();\n\n既然你现在把一个 ApplicationUser 参数传给了 GetIncompleteItemsAsync(),就该修改 ITodoItemService 接口了:\nServices/ITodoItemService.cs\npublic interface ITodoItemService\n{\n Task GetIncompleteItemsAsync(\n ApplicationUser user);\n\n // ...\n}\n\n而既然你修改了 ITodoItemService 接口,也就同样需要修改 TodoItemService 中 GetIncompleteItemsAsync() 方法的签名:\nServices/TodoItemService\npublic async Task GetIncompleteItemsAsync(\n ApplicationUser user)\n\n下一步是修改数据库查询,并添加一层过滤,仅显示当前用户创建的条目。但在做这些之前,你需要在数据库里添加一个新的字段。\n修改数据库\n你需要在 TodoItem 实体上添加一个新的属性,让每个条目都能够“记住”拥有它的用户:\nModels/TodoItem.cs\npublic string UserId { get; set; }\n\n既然你修改了数据库上下文里的实体模型,就应该同步修改数据库。在终端窗口里用 dotnet ef 指令创建一个新的变更:\ndotnet ef migrations add AddItemUserId\n这个命令新建了一个名为 AddItemUserId 的变更,它将给 Items 表新添一个列,以反映你在 TodoItem 实体模型上所做的修改:\n再通过 dotnet ef 指令应用到数据库:\ndotnet ef database update\n修改服务类\n修改了数据库和数据库上下文,你就可以修改 TodoItemService 里的 GetIncompleteItemsAsync() 方法和其中的 Where 查询子句了:\nServices/TodoItemService.cs\npublic async Task GetIncompleteItemsAsync(\n ApplicationUser user)\n{\n return await _context.Items\n .Where(x => x.IsDone == false && x.UserId == user.Id)\n .ToArrayAsync();\n}\n\n如果你现在运行程序并注册或者登录,你将又一次见到一个空的 待办事项列表。糟糕的是,你尝试添加的任何条目也都会凭空消失,因为你还没修改 添加条目 的操作,并把用户信息存储到条目里:\n修改 添加条目 和 完成事项 操作\n你需要在 AddItem 和 MarkDone 这两个 action 的方法里,使用 UserManager 以获取当前用户,如同在 Index 里那样。\n下面是 TodoController 控制器里对这两个方法的修改:\nControllers/TodoController.cs\n[ValidateAntiForgeryToken]\npublic async Task AddItem(TodoItem newItem)\n{\n if (!ModelState.IsValid)\n {\n return RedirectToAction(\"Index\");\n }\n\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var successful = await _todoItemService\n .AddItemAsync(newItem, currentUser);\n\n if (!successful)\n {\n return BadRequest(\"Could not add item.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\n[ValidateAntiForgeryToken]\npublic async Task MarkDone(Guid id)\n{\n if (id == Guid.Empty)\n {\n return RedirectToAction(\"Index\");\n }\n\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var successful = await _todoItemService\n .MarkDoneAsync(id, currentUser);\n\n if (!successful)\n {\n return BadRequest(\"Could not mark item as done.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\n这两个服务方法现在也必须接受 ApplicationUser 参数了,修改 ITodoItemService 里定义的接口:\nTask AddItemAsync(NewTodoItem newItem, ApplicationUser user);\n\nTask MarkDoneAsync(Guid id, ApplicationUser user);\n\n最后,修改 TodoItemService 里面的实现方法。在 AddItemAsync 方法里,构造一个 new TodoItem 的时候,设置 UserId 属性:\npublic async Task AddItemAsync(\n TodoItem newItem, ApplicationUser user)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n newItem.UserId = user.Id;\n\n // ...\n}\n\nMarkDoneAsync 方法里的 Where 查询子句也需要检查用户的 ID,以防止恶意的用户通过猜测 ID 的方法把其他用户的事项标记为完成状态。\npublic async Task MarkDoneAsync(\n Guid id, ApplicationUser user)\n{\n var item = await _context.Items\n .Where(x => x.Id == id && x.UserId == user.Id)\n .SingleOrDefaultAsync();\n\n // ...\n}\n\n搞定!请用两个不同的账号尝试一下。待办事项条目现在是每个账户的私密信息了。\n\nUsing identity in the application\nThe to-do list items themselves are still shared between all users, because the stored to-do entities aren't tied to a particular user. Now that the [Authorize] attribute ensures that you must be logged in to see the to-do view, you can filter the database query based on who is logged in.\nFirst, inject a UserManager into the TodoController:\nControllers/TodoController.cs\n[Authorize]\npublic class TodoController : Controller\n{\n private readonly ITodoItemService _todoItemService;\n private readonly UserManager _userManager;\n\n public TodoController(ITodoItemService todoItemService,\n UserManager userManager)\n {\n _todoItemService = todoItemService;\n _userManager = userManager;\n }\n\n // ...\n}\n\nYou'll need to add a new using statement at the top:\nusing Microsoft.AspNetCore.Identity;\n\nThe UserManager class is part of ASP.NET Core Identity. You can use it to get the current user in the Index action:\npublic async Task Index()\n{\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var items = await _todoItemService\n .GetIncompleteItemsAsync(currentUser);\n\n var model = new TodoViewModel()\n {\n Items = items\n };\n\n return View(model);\n}\n\nThe new code at the top of the action method uses the UserManager to look up the current user from the User property available in the action:\nvar currentUser = await _userManager.GetUserAsync(User);\n\nIf there is a logged-in user, the User property contains a lightweight object with some (but not all) of the user's information. The UserManager uses this to look up the full user details in the database via the GetUserAsync() method.\nThe value of currentUser should never be null, because the [Authorize] attribute is present on the controller. However, it's a good idea to do a sanity check, just in case. You can use the Challenge() method to force the user to log in again if their information is missing:\nif (currentUser == null) return Challenge();\n\nSince you're now passing an ApplicationUser parameter to GetIncompleteItemsAsync(), you'll need to update the ITodoItemService interface:\nServices/ITodoItemService.cs\npublic interface ITodoItemService\n{\n Task GetIncompleteItemsAsync(\n ApplicationUser user);\n\n // ...\n}\n\nSince you changed the ITodoItemService interface, you also need to update the signature of the GetIncompleteItemsAsync() method in the TodoItemService:\nServices/TodoItemService\npublic async Task GetIncompleteItemsAsync(\n ApplicationUser user)\n\nThe next step is to update the database query and add a filter to show only the items created by the current user. Before you can do that, you need to add a new property to the database.\nUpdate the database\nYou'll need to add a new property to the TodoItem entity model so each item can \"remember\" the user that owns it:\nModels/TodoItem.cs\npublic string UserId { get; set; }\n\nSince you updated the entity model used by the database context, you also need to migrate the database. Create a new migration using dotnet ef in the terminal:\ndotnet ef migrations add AddItemUserId\nThis creates a new migration called AddItemUserId which will add a new column to the Items table, mirroring the change you made to the TodoItem model.\nUse dotnet ef again to apply it to the database:\ndotnet ef database update\nUpdate the service class\nWith the database and the database context updated, you can now update the GetIncompleteItemsAsync() method in the TodoItemService and add another clause to the Where statement:\nServices/TodoItemService.cs\npublic async Task GetIncompleteItemsAsync(\n ApplicationUser user)\n{\n return await _context.Items\n .Where(x => x.IsDone == false && x.UserId == user.Id)\n .ToArrayAsync();\n}\n\nIf you run the application and register or log in, you'll see an empty to-do list once again. Unfortunately, any items you try to add disappear into the ether, because you haven't updated the AddItem action to be user-aware yet.\nUpdate the AddItem and MarkDone actions\nYou'll need to use the UserManager to get the current user in the AddItem and MarkDone action methods, just like you did in Index.\nHere are both updated methods:\nControllers/TodoController.cs\n[ValidateAntiForgeryToken]\npublic async Task AddItem(TodoItem newItem)\n{\n if (!ModelState.IsValid)\n {\n return RedirectToAction(\"Index\");\n }\n\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var successful = await _todoItemService\n .AddItemAsync(newItem, currentUser);\n\n if (!successful)\n {\n return BadRequest(\"Could not add item.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\n[ValidateAntiForgeryToken]\npublic async Task MarkDone(Guid id)\n{\n if (id == Guid.Empty)\n {\n return RedirectToAction(\"Index\");\n }\n\n var currentUser = await _userManager.GetUserAsync(User);\n if (currentUser == null) return Challenge();\n\n var successful = await _todoItemService\n .MarkDoneAsync(id, currentUser);\n\n if (!successful)\n {\n return BadRequest(\"Could not mark item as done.\");\n }\n\n return RedirectToAction(\"Index\");\n}\n\nBoth service methods must now accept an ApplicationUser parameter. Update the interface definition in ITodoItemService:\nTask AddItemAsync(TodoItem newItem, ApplicationUser user);\n\nTask MarkDoneAsync(Guid id, ApplicationUser user);\n\nAnd finally, update the service method implementations in the TodoItemService. In AddItemAsync method, set the UserId property when you construct a new TodoItem:\npublic async Task AddItemAsync(\n TodoItem newItem, ApplicationUser user)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n newItem.UserId = user.Id;\n\n // ...\n}\n\nThe Where clause in the MarkDoneAsync method also needs to check for the user's ID, so a rogue user can't complete someone else's items by guessing their IDs:\npublic async Task MarkDoneAsync(\n Guid id, ApplicationUser user)\n{\n var item = await _context.Items\n .Where(x => x.Id == id && x.UserId == user.Id)\n .SingleOrDefaultAsync();\n\n // ...\n}\n\nAll done! Try using the application with two different user accounts. The to-do items stay private for each account.\n"},"chapters/security-and-identity/authorization-with-roles.html":{"url":"chapters/security-and-identity/authorization-with-roles.html","title":"按角色进行授权","keywords":"","body":"按角色进行授权\n在网络应用里,角色是用于处理 授权 和 许可 的常见方法。例如,通常会为管理员创建一个 Administrator 角色,相对于普通用户,他们拥有更多的权限和能力。\n在此项目中,你将添加一个 用户管理 页面,仅对管理员们可见。如果普通用户试图访问它,将会看到错误提示。\n添加用户管理页面\n首先,创建一个新控制器:\nControllers/ManageUsersController.cs\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Identity;\nusing AspNetCoreTodo.Models;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace AspNetCoreTodo.Controllers\n{\n [Authorize(Roles = \"Administrator\")]\n public class ManageUsersController : Controller\n {\n private readonly UserManager\n _userManager;\n\n public ManageUsersController(\n UserManager userManager)\n {\n _userManager = userManager;\n }\n\n public async Task Index()\n {\n var admins = (await _userManager\n .GetUsersInRoleAsync(\"Administrator\"))\n .ToArray();\n\n var everyone = await _userManager.Users\n .ToArrayAsync();\n\n var model = new ManageUsersViewModel\n {\n Administrators = admins,\n Everyone = everyone\n };\n\n return View(model);\n }\n }\n}\n\n在 [Authorize] 属性里加入 Roles 字段,可以确保用户必须已经登录 并且 被分配了 Administrator 角色才能查看这个页面。\n接下来,创建一个视图模型:\nModels/ManageUsersViewModel.cs\nusing System.Collections.Generic;\n\nnamespace AspNetCoreTodo.Models\n{\n public class ManageUsersViewModel\n {\n public ApplicationUser[] Administrators { get; set; }\n\n public ApplicationUser[] Everyone { get; set;}\n }\n}\n\n最后,为 action Index 创建一个名为Views/ManageUsers的文件夹和一个视图:\nViews/ManageUsers/Index.cshtml\n@model ManageUsersViewModel\n\n@{\n ViewData[\"Title\"] = \"Manage users\";\n}\n\n@ViewData[\"Title\"]\n\nAdministrators\n\n\n \n \n Id\n Email\n \n \n\n @foreach (var user in Model.Administrators)\n {\n \n @user.Id\n @user.Email\n \n }\n\n\nEveryone\n\n\n \n \n Id\n Email\n \n \n\n @foreach (var user in Model.Everyone)\n {\n \n @user.Id\n @user.Email\n \n }\n\n\n启动程序,并以普通用户身份登录,尝试去访问一下 /ManageUsers 路径。你会见到这样的 拒绝访问 页面:\n\n这是因为注册用户不会自动获得 Administrator 这个角色。\n创建一个测试用的管理员账号\n出于显而易见的安全因素,对于任何人来说,都不能自主的注册成为一个管理员账号。事实上,Administrator 这个角色,在数据库中尚不存在。\n你可以在该应用程序第一次启动的时候,将这个 Administrator 角色外加一个测试用的管理员账号添加到数据库中。向数据库添加初始数据的行为,被称为初始化,或者 填充(seeding) 数据库。\n在项目的根目录创建一个新类,取名为 SeedData:\nSeedData.cs\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace AspNetCoreTodo\n{\n public static class SeedData\n {\n public static async Task InitializeAsync(\n IServiceProvider services)\n {\n var roleManager = services\n .GetRequiredService>();\n await EnsureRolesAsync(roleManager);\n\n var userManager = services\n .GetRequiredService>();\n await EnsureTestAdminAsync(userManager);\n }\n }\n}\n\nInitializeAsync() 方法使用一个 IServiceProvider(在Startup.ConfigureServices()方法中设置过的服务集合)从 ASP.NET Core Identity 中获取RoleManager和UserManager。\n在InitializeAsync()方法下面再添加两个方法,第一个,EnsureRolesAsync()方法:\nprivate static async Task EnsureRolesAsync(\n RoleManager roleManager)\n{\n var alreadyExists = await roleManager\n .RoleExistsAsync(Constants.AdministratorRole);\n\n if (alreadyExists) return;\n\n await roleManager.CreateAsync(\n new IdentityRole(Constants.AdministratorRole));\n}\n\n此方法查看数据库里是否存在一个 Administrator 角色。如果没有,它就创建一个。为免反复地输入字符串 \"Administrator\",创建一个名为 Constants 的小类以保存它的值:\nConstants.cs\nnamespace AspNetCoreTodo\n{\n public static class Constants\n {\n public const string AdministratorRole = \"Administrator\";\n }\n}\n\n\n如果你愿意,也可以修改之前创建的 ManageUsersController 使用这个常量值。\n\n接下来是 EnsureTestAdminAsync() 方法:\nSeedData.cs\nprivate static async Task EnsureTestAdminAsync(\n UserManager userManager)\n{\n var testAdmin = await userManager.Users\n .Where(x => x.UserName == \"admin@todo.local\")\n .SingleOrDefaultAsync();\n\n if (testAdmin != null) return;\n\n testAdmin = new ApplicationUser\n {\n UserName = \"admin@todo.local\",\n Email = \"admin@todo.local\"\n };\n await userManager.CreateAsync(\n testAdmin, \"NotSecure123!!\");\n await userManager.AddToRoleAsync(\n testAdmin, Constants.AdministratorRole);\n}\n\n如果数据库里不存在一个用户名为 admin@todo.local 的用户,这个方法将创建它并给它一个临时的密码。在你初次登录之后,就应该改为一个更安全的密码。\n接下来,你需要提醒你的程序,在它启动的时候,执行这个逻辑。修改Program.cs,并更新Main()去调用一个新的方法InitializeDatabase():\nProgram.cs\npublic static void Main(string[] args)\n{\n var host = BuildWebHost(args);\n InitializeDatabase(host);\n host.Run();\n}\n\n然后,在Main()的下面添加这个新方法:\nprivate static void InitializeDatabase(IWebHost host)\n{\n using (var scope = host.Services.CreateScope())\n {\n var services = scope.ServiceProvider;\n\n try\n {\n SeedData.InitializeAsync(services).Wait();\n }\n catch (Exception ex)\n {\n var logger = services\n .GetRequiredService>();\n logger.LogError(ex, \"Error occurred seeding the DB.\");\n }\n }\n}\n\n并把这个 using 语句添加到文件顶部:\nusing Microsoft.Extensions.DependencyInjection;\n\n此方法获取SeedData.InitializeAsync()所需的服务集合,然后执行它以便初始化数据库。如果出现错误,将会记录一条错误日志。\n\n因为InitializeAsync()返回一个 Task,就必须使用 Wait() 方法以确保它在应用程序启动前完成。你一般是用 await 做这件事,但是因为某些技术原因,你无法在 Program 方法中使用 await。这是个罕见的例外 —— 所有其它地方你都应该用 await!\n\n当你再次启动程序,admin@todo.local 这个账号会被创建并被赋予 Administrator 角色。请尝试用这个账号登录,并浏览位于 http://localhost:5000/ManageUsers 的页面,你将看到一个列表,列出了本程序的所有注册用户。\n\n作为练习,请在这个页面添加更多管理功能特性。例如,添加一个按钮,为管理员提供 删除一个用户 的功能。\n\n在视图里查看认证状态\n[Authorize] 属性让控制器里执行认证操作变得很方便,但是如果你需要在视图里进行认证操作呢?比如,在导航条上为登入的管理员用户显示一个“管理用户”的链接。\n你可以把 UserManager 直接注入到视图里来进行这些操作。为保持你视图整洁有序,创建一个新的局部视图(partial view),以便在布局中的导航条里添加一个项目:\nViews/Shared/_AdminActionsPartial.cshtml\n@using Microsoft.AspNetCore.Identity\n@using AspNetCoreTodo.Models\n\n@inject SignInManager signInManager\n@inject UserManager userManager\n\n@if (signInManager.IsSignedIn(User))\n{\n var currentUser = await userManager.GetUserAsync(User);\n\n var isAdmin = currentUser != null\n && await userManager.IsInRoleAsync(\n currentUser,\n Constants.AdministratorRole);\n\n if (isAdmin)\n {\n \n \n \n Manage Users\n \n \n \n }\n}\n\n\n按惯例,通常把局部视图的名字以 _ 下划线开始,但这不是强制性的。\n\n这个局部视图首先使用 SignInManager 判断用户是否已经登录。如果没有登录,其余的代码就都被跳过。如果这 是 个已登录用户,UserManager 就被用于查找用户详细信息,并用 IsInRoleAsync() 进行认证检查。如果所有检查都通过了,并且该用户是一个管理员,导航条上就会加入一个 Manage Users 链接。\n要在主布局中包含这个局部视图,编辑 _Layout.cshtml 并在导航条部分添加:\nViews/Shared/_Layout.cshtml\n\n \n \n \n @await Html.PartialAsync(\"_LoginPartial\")\n @await Html.PartialAsync(\"_AdminActionsPartial\")\n\n\n如果你用管理员账号登录,将在右上角见到一个新的导航项:\n\n\nAuthorization with roles\nRoles are a common approach to handling authorization and permissions in a web application. For example, it's common to create an Administrator role that gives admin users more permissions or power than normal users.\nIn this project, you'll add a Manage Users page that only administrators can see. If normal users try to access it, they'll see an error.\nAdd a Manage Users page\nFirst, create a new controller:\nControllers/ManageUsersController.cs\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Identity;\nusing AspNetCoreTodo.Models;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace AspNetCoreTodo.Controllers\n{\n [Authorize(Roles = \"Administrator\")]\n public class ManageUsersController : Controller\n {\n private readonly UserManager\n _userManager;\n\n public ManageUsersController(\n UserManager userManager)\n {\n _userManager = userManager;\n }\n\n public async Task Index()\n {\n var admins = (await _userManager\n .GetUsersInRoleAsync(\"Administrator\"))\n .ToArray();\n\n var everyone = await _userManager.Users\n .ToArrayAsync();\n\n var model = new ManageUsersViewModel\n {\n Administrators = admins,\n Everyone = everyone\n };\n\n return View(model);\n }\n }\n}\n\nSetting the Roles property on the [Authorize] attribute will ensure that the user must be logged in and assigned the Administrator role in order to view the page.\nNext, create a view model:\nModels/ManageUsersViewModel.cs\nusing System.Collections.Generic;\n\nnamespace AspNetCoreTodo.Models\n{\n public class ManageUsersViewModel\n {\n public ApplicationUser[] Administrators { get; set; }\n\n public ApplicationUser[] Everyone { get; set;}\n }\n}\n\nFinally, create a Views/ManageUsers folder and a view for the Index action:\nViews/ManageUsers/Index.cshtml\n@model ManageUsersViewModel\n\n@{\n ViewData[\"Title\"] = \"Manage users\";\n}\n\n@ViewData[\"Title\"]\n\nAdministrators\n\n\n \n \n Id\n Email\n \n \n\n @foreach (var user in Model.Administrators)\n {\n \n @user.Id\n @user.Email\n \n }\n\n\nEveryone\n\n\n \n \n Id\n Email\n \n \n\n @foreach (var user in Model.Everyone)\n {\n \n @user.Id\n @user.Email\n \n }\n\n\nStart up the application and try to access the /ManageUsers route while logged in as a normal user. You'll see this access denied page:\n\nThat's because users aren't assigned the Administrator role automatically.\nCreate a test administrator account\nFor obvious security reasons, it isn't possible for anyone to register a new administrator account themselves. In fact, the Administrator role doesn't even exist in the database yet!\nYou can add the Administrator role plus a test administrator account to the database the first time the application starts up. Adding first-time data to the database is called initializing or seeding the database.\nCreate a new class in the root of the project called SeedData:\nSeedData.cs\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Models;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace AspNetCoreTodo\n{\n public static class SeedData\n {\n public static async Task InitializeAsync(\n IServiceProvider services)\n {\n var roleManager = services\n .GetRequiredService>();\n await EnsureRolesAsync(roleManager);\n\n var userManager = services\n .GetRequiredService>();\n await EnsureTestAdminAsync(userManager);\n }\n }\n}\n\nThe InitializeAsync() method uses an IServiceProvider (the collection of services that is set up in the Startup.ConfigureServices() method) to get the RoleManager and UserManager from ASP.NET Core Identity.\nAdd two more methods below the InitializeAsync() method. First, the EnsureRolesAsync() method:\nprivate static async Task EnsureRolesAsync(\n RoleManager roleManager)\n{\n var alreadyExists = await roleManager\n .RoleExistsAsync(Constants.AdministratorRole);\n\n if (alreadyExists) return;\n\n await roleManager.CreateAsync(\n new IdentityRole(Constants.AdministratorRole));\n}\n\nThis method checks to see if an Administrator role exists in the database. If not, it creates one. Instead of repeatedly typing the string \"Administrator\", create a small class called Constants to hold the value:\nConstants.cs\nnamespace AspNetCoreTodo\n{\n public static class Constants\n {\n public const string AdministratorRole = \"Administrator\";\n }\n}\n\n\nIf you want, you can update the ManageUsersController to use this constant value as well.\n\nNext, write the EnsureTestAdminAsync() method:\nSeedData.cs\nprivate static async Task EnsureTestAdminAsync(\n UserManager userManager)\n{\n var testAdmin = await userManager.Users\n .Where(x => x.UserName == \"admin@todo.local\")\n .SingleOrDefaultAsync();\n\n if (testAdmin != null) return;\n\n testAdmin = new ApplicationUser\n {\n UserName = \"admin@todo.local\",\n Email = \"admin@todo.local\"\n };\n await userManager.CreateAsync(\n testAdmin, \"NotSecure123!!\");\n await userManager.AddToRoleAsync(\n testAdmin, Constants.AdministratorRole);\n}\n\nIf there isn't already a user with the username admin@todo.local in the database, this method will create one and assign a temporary password. After you log in for the first time, you should change the account's password to something secure!\nNext, you need to tell your application to run this logic when it starts up. Modify Program.cs and update Main() to call a new method, InitializeDatabase():\nProgram.cs\npublic static void Main(string[] args)\n{\n var host = BuildWebHost(args);\n InitializeDatabase(host);\n host.Run();\n}\n\nThen, add the new method to the class below Main():\nprivate static void InitializeDatabase(IWebHost host)\n{\n using (var scope = host.Services.CreateScope())\n {\n var services = scope.ServiceProvider;\n\n try\n {\n SeedData.InitializeAsync(services).Wait();\n }\n catch (Exception ex)\n {\n var logger = services\n .GetRequiredService>();\n logger.LogError(ex, \"Error occurred seeding the DB.\");\n }\n }\n}\n\nAdd this using statement to the top of the file:\nusing Microsoft.Extensions.DependencyInjection;\n\nThis method gets the service collection that SeedData.InitializeAsync() needs and then runs the method to seed the database. If something goes wrong, an error is logged.\n\nBecause InitializeAsync() returns a Task, the Wait() method must be used to make sure it finishes before the application starts up. You'd normally use await for this, but for technical reasons you can't use await in the Program class. This is a rare exception. You should use await everywhere else!\n\nWhen you start the application next, the admin@todo.local account will be created and assigned the Administrator role. Try logging in with this account, and navigating to http://localhost:5000/ManageUsers. You'll see a list of all users registered for the application.\n\nAs an extra challenge, try adding more administration features to this page. For example, you could add a button that gives an administrator the ability to delete a user account.\n\nCheck for authorization in a view\nThe [Authorize] attribute makes it easy to perform an authorization check in a controller or action method, but what if you need to check authorization in a view? For example, it would be nice to display a \"Manage users\" link in the navigation bar if the logged-in user is an administrator.\nYou can inject the UserManager directly into a view to do these types of authorization checks. To keep your views clean and organized, create a new partial view that will add an item to the navbar in the layout:\nViews/Shared/_AdminActionsPartial.cshtml\n@using Microsoft.AspNetCore.Identity\n@using AspNetCoreTodo.Models\n\n@inject SignInManager signInManager\n@inject UserManager userManager\n\n@if (signInManager.IsSignedIn(User))\n{\n var currentUser = await userManager.GetUserAsync(User);\n\n var isAdmin = currentUser != null\n && await userManager.IsInRoleAsync(\n currentUser,\n Constants.AdministratorRole);\n\n if (isAdmin)\n {\n \n \n \n Manage Users\n \n \n \n }\n}\n\n\nIt's conventional to name shared partial views starting with an _ underscore, but it's not required.\n\nThis partial view first uses the SignInManager to quickly determine whether the user is logged in. If they aren't, the rest of the view code can be skipped. If there is a logged-in user, the UserManager is used to look up their details and perform an authorization check with IsInRoleAsync(). If all checks succeed and the user is an adminstrator, a Manage users link is added to the navbar.\nTo include this partial in the main layout, edit _Layout.cshtml and add it in the navbar section:\nViews/Shared/_Layout.cshtml\n\n \n \n \n @await Html.PartialAsync(\"_LoginPartial\")\n @await Html.PartialAsync(\"_AdminActionsPartial\")\n\n\nWhen you log in with an administrator account, you'll now see a new item on the top right:\n\n"},"chapters/security-and-identity/more-resources.html":{"url":"chapters/security-and-identity/more-resources.html","title":"附加资源","keywords":"","body":"附加资源\nASP.NET Core Identity 帮助你添加诸如 登录、注册 这些安全及身份鉴别的特性到程序里。dotnet new 指定的模板带给你预先构建好的视图和控制器,用以处理这些常见情景,以便你快速上手和运行。\nASP.NET Core Identity 还有很多其它功能,例如密码重置以及社交账户登录。位于 http://docs.asp.net 的文档非常适合用来学习这些特性。\nASP.NET Core Identity 的替代品\nASP.NET Core Identity 并非添加身份鉴别的唯一方式。另外一种选择是使用诸如 Azure Active Directory 以及 Okta 这种云端的服务为你的程序处理身份验证。你可以把这些选项看作发展的各个环节:\n\n自己处理安全性:不推荐,除非你是一个安全性方面的专家!\nASP.NET Core Identity:你免费获得随模板而来的大量代码,易于上手。对于进阶的情形,你依然需要写一部分代码,并维护一个数据库以存储用户信息。\n基于云的身份鉴别服务:这种服务既处理简单情况也处理复杂情况(多步验证、账号找回,),并且能极大地缩减你需要编写的代码量,和维护程序的工作量。另外,用户数据的敏感部分并不会保存在你的数据库里。\n\n在本项目里,ASP.NET Core Identity 非常适合。对于更复杂的项目,我建议对各选项都作一些研究和尝试,以便找到你所需的最佳方案。\n\nMore resources\nASP.NET Core Identity helps you add security and identity features like login and registration to your application. The dotnet new templates give you pre-built views and controllers that handle these common scenarios so you can get up and running quickly.\nThere's much more that ASP.NET Core Identity can do, such as password reset and social login. The documentation available at http://docs.asp.net is a fantastic resource for learning how to add these features.\nAlternatives to ASP.NET Core Identity\nASP.NET Core Identity isn't the only way to add identity functionality. Another approach is to use a cloud-hosted identity service like Azure Active Directory B2C or Okta to handle identity for your application. You can think of these options as part of a progression:\n\nDo-it-yourself security: Not recommended, unless you are a security expert!\nASP.NET Core Identity: You get a lot of code for free with the templates, which makes it pretty easy to get started. You'll still need to write some code for more advanced scenarios, and maintain a database to store user information.\nCloud-hosted identity services. The service handles both simple and advanced scenarios (multi-factor authentication, account recovery, federation), and significantly reduces the amount of code you need to write and maintain in your application. Plus, sensitive user data isn't stored in your own database.\n\nFor this project, ASP.NET Core Identity is a great fit. For more complex projects, I'd recommend doing some research and experimenting with both options to understand which is best for your use case.\n"},"chapters/automated-testing/":{"url":"chapters/automated-testing/","title":"自动化测试","keywords":"","body":"自动化测试\n测试的编写在构建任何程序时都很重要。测试代码有助于发现及避免 bug,并使你后续重构代码的工作轻松些,以免破坏现有功能或引入新的问题。\n在本章里,你将学习如何编写 单元测试 和 集成测试 以检验你的 ASP.NET Core 程序。单元测试较小,用来确保单个方法或者逻辑块工作良好。集成测试(有时候也叫 功能性 测试)较大,模拟实际的应用场景,并检验你程序里的多个层次或组件。\n\nAutomated testing\nWriting tests is an important part of building any application. Testing your code helps you find and avoid bugs, and makes it easier to refactor your code later without breaking functionality or introducing new problems.\nIn this chapter you'll learn how to write both unit tests and integration tests that exercise your ASP.NET Core application. Unit tests are small tests that make sure a single method or chunk of logic works properly. Integration tests (sometimes called functional tests) are larger tests that simulate real-world scenarios and test multiple layers or parts of your application.\n"},"chapters/automated-testing/unit-testing.html":{"url":"chapters/automated-testing/unit-testing.html","title":"单元测试","keywords":"","body":"单元测试\n单元测试是短小的测试,检查单个方法或类的行为。当你测试的代码依赖其它方法或类时,单元测试依赖于 虚构(mocking) 出来的其它类,以便在一个时时刻专注在一个点上。\n例如,TodoController 有两个依赖: ITodoItemService 和 UserManager。TodoItemService 接下来又依赖于 ApplicationDbContext。(你可以画一条线表示 TodoController > TodoItemService > ApplicationDbContext,这种方式被称为 依赖图)。\n当程序运转正常的时候, ASP.NET Core 的服务容器和依赖注入系统在 TodoController 或者 TodoItemService 被创建时,把这些对象逐一地注入到依赖图里。\n另一方面,当你写单元测试的时候,你需要自己处理这个依赖图。典刑的做法是,提供这些依赖的 虚构 或者 测试专用 版本。这意味着你可以把正在测试的类或者方法的逻辑隔离出来。(这很重要!如果你在测试一个服务,显然不应该一失手 顺带 写到数据库里去。)\n创建一个测试项目\n为测试创建独立的项目是一个良好的实践,以便把它们和你的程序代码分离开。新的测试项目应该被置于你主项目的同级目录(而非在主项目目录内)。\n如果你当前在你项目目录里,向上 cd 一层。(这个目录也叫做 AspNetCoreTodo)。然后使用以下命令搭建出一个新的测试项目:\ndotnet new xunit -o AspNetCoreTodo.UnitTests\nxUnit.NET 是一个常用的针对 .NET 代码的测试框架,可用于编写单元和集成测试。像其它组件一样,它也是一组NuGet 包,可被安装在任意项目中 。dotnet new xunit 已经包括了你所需的一切。\n你的目录结构看起来应该是这样:\nAspNetCoreTodo/\n AspNetCoreTodo/\n AspNetCoreTodo.csproj\n Controllers/\n (etc...)\n\n AspNetCoreTodo.UnitTests/\n AspNetCoreTodo.UnitTests.csproj\n既然测试项目要使用你主项目中的类,你需要添加一个引用指向主项目:\ndotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj\n删除自动创建的文件 UnitTest1.cs。你已经为第一个测试的编写准备就绪了。\n\n如果你用的是 Visual Studio Code,你可能需要关闭并重新打开 Visual Studio Code 窗口,以便代码完成功能在新项目里生效。\n\n写一个服务测试\n看一下 TodoItemService 里面的 AddItemAsync() 方法:\npublic async Task AddItemAsync(\n TodoItem newItem, ApplicationUser user)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n newItem.UserId = user.Id;\n\n _context.Items.Add(newItem);\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1;\n}\n\n该方法在把新条目真正存入数据库之前,做了多个判断与假设(换句话说,在新条目上执行了业务逻辑):\n\nUserId 属性应该被设置为用户的 ID\n新条目应该总是未完成状态(IsDone = false)\n新条目的标题应该复制自 newItem.Title\n新条目应该总是从现在开始3天后过期\n\n设想一下,如果你或者其他什么人重构了这个 AddItemAsync() 方法,并遗漏了某些以上的业务逻辑。你程序的行为,会在你意识不到的情况下变掉!你有办法避免这个情况,方法是编写一个测试,用以复核这些业务逻辑并未发生变化(就算是该方法的内部实现已经发生了变化)。\n\n这种情形——你意识不到自己改变了业务逻辑,虽然现在看起来好像不会发生,但是在一个更大更复杂的项目中,这会因为各种决策和假设而变得难以追踪。在越大的项目中,确保业务逻辑稳定的自动化检查就越重要。\n\n要编写一个单元测试来检验 TodoItemService 中的逻辑,在你的测试项目中创建一个新类:\nAspNetCoreTodo.UnitTests/TodoItemServiceShould.cs\nusing System;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Data;\nusing AspNetCoreTodo.Models;\nusing AspNetCoreTodo.Services;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\n\nnamespace AspNetCoreTodo.UnitTests\n{\n public class TodoItemServiceShould\n {\n [Fact]\n public async Task AddNewItemAsIncompleteWithDueDate()\n {\n // ...\n }\n }\n}\n\n\n有很多不同的方法可以命名和组织测试,它们都有着各自的优缺点。我喜欢给测试类加上 Should 前缀,使方法名构成一个可读性良好的句子,不过你可以按自己的意愿选择命名风格。\n\n[Fact] 属性是 xUnit.NET 包里带来的,它把这个方法标记为一个测试方法。\nTodoItemService 需要一个 ApplicationDbContext,后者通常连接到你的开发或生产环境里的数据库。你不该把这些数据库用于测试。相反,你可以在测试代码里使用 Entity Framework Core 的内存数据库 provider。因为整个数据库都存在于内存里,每次测试重新开始的时候,他就会被清空。并且,因为这是个合乎规格的 Entity Framework Core 的 provider,TodoItemService 不会察觉有什么异样。\n用一个 DbContextOptionsBuilder 来配置内存数据库的 provider,然后对 AddItemAsync() 发起一个调用:\nvar options = new DbContextOptionsBuilder()\n .UseInMemoryDatabase(databaseName: \"Test_AddNewItem\").Options;\n\n// Set up a context (connection to the \"DB\") for writing\nusing (var context = new ApplicationDbContext(options))\n{\n var service = new TodoItemService(context);\n\n var fakeUser = new ApplicationUser\n {\n Id = \"fake-000\",\n UserName = \"fake@example.com\"\n };\n\n await service.AddItemAsync(new TodoItem\n {\n Title = \"Testing?\"\n }, fakeUser);\n}\n\n最后一行创建了一个新的名为 Testing? 的待办事项,并通知服务将其存储到(内存)数据库里。\n为验证业务逻辑执行的正确性,请在原有的 using 代码块下编写新内容:\n// Use a separate context to read data back from the \"DB\"\nusing (var context = new ApplicationDbContext(options))\n{\n var itemsInDatabase = await context\n .Items.CountAsync();\n Assert.Equal(1, itemsInDatabase);\n\n var item = await context.Items.FirstAsync();\n Assert.Equal(\"Testing?\", item.Title);\n Assert.Equal(false, item.IsDone);\n\n // Item should be due 3 days from now (give or take a second)\n var difference = DateTimeOffset.Now.AddDays(3) - item.DueAt;\n Assert.True(difference \n第一个验证步骤是个明智的检查:内存数据库里保存的条目绝不会超过一条。假设这个检查通过了,测试会使用 FirstAsync 方法取出存储的条目,然后断言其中的属性被设置了预期的值。\n\n不论是单元测试还是集成测试,都遵循 AAA(布置-执行-断言——Arrange-Act-Assert)模式:对象和数据首先被建立出来,然后执行一些动作,最后测试程序检查(断言)预期表现的存在。\n\n断言一个日期时间值有点棘手,因为比较两个日期值的时候,就算是只有毫秒部分不同,两个值也是不等的。替代方案是,检查 DueAt 的值距离期望值小于一秒。\n运行测试\n在终端窗口,运行以下命令(请确保你位于 AspNetCoreTodo.UnitTests 目录):\ndotnet test\ntest 命令在当前的项目里查找测试方法(本例中,由 [Fact] 属性标记出来),然后运行它找到的所有测试,你会看到类似这样的输出:\nStarting test execution, please wait...\n Discovering: AspNetCoreTodo.UnitTests\n Discovered: AspNetCoreTodo.UnitTests\n Starting: AspNetCoreTodo.UnitTests\n Finished: AspNetCoreTodo.UnitTests\n\nTotal tests: 1. Passed: 1. Failed: 0. Skipped: 0.\nTest Run Successful.\nTest execution time: 1.9074 Seconds\n你现在有了测试程序,覆盖了 TodoItemService 的测试范围。作为一个补充练习,请写出单元测试以确保:\n\n如果传入一个不存在的 ID, MarkDoneAsync() 返回 false\n当一个有效的条目被标记为完成状态, MarkDoneAsync() 返回 true\nGetIncompleteItemsAsync() 只返回某个特定用户的条目\n\n\nUnit testing\nUnit tests are small, short tests that check the behavior of a single method or class. When the code you're testing relies on other methods or classes, unit tests rely on mocking those other classes so that the test only focuses on one thing at a time.\nFor example, the TodoController class has two dependencies: an ITodoItemService and the UserManager. The TodoItemService, in turn, depends on the ApplicationDbContext. (The idea that you can draw a line from TodoController > TodoItemService > ApplicationDbContext is called a dependency graph).\nWhen the application runs normally, the ASP.NET Core service container and dependency injection system injects each of those objects into the dependency graph when the TodoController or the TodoItemService is created.\nWhen you write a unit test, on the other hand, you have to handle the dependency graph yourself. It's typical to provide test-only or \"mocked\" versions of those dependencies. This means you can isolate just the logic in the class or method you are testing. (This is important! If you're testing a service, you don't want to also be accidentally writing to your database.)\nCreate a test project\nIt's a best practice to create a separate project for your tests, so they are kept separate from your application code. The new test project should live in a directory that's next to (not inside) your main project's directory.\nIf you're currently in your project directory, cd up one level. (This root directory will also be called AspNetCoreTodo). Then use this command to scaffold a new test project:\ndotnet new xunit -o AspNetCoreTodo.UnitTests\nxUnit.NET is a popular test framework for .NET code that can be used to write both unit and integration tests. Like everything else, it's a set of NuGet packages that can be installed in any project. The dotnet new xunit template already includes everything you need.\nYour directory structure should now look like this:\nAspNetCoreTodo/\n AspNetCoreTodo/\n AspNetCoreTodo.csproj\n Controllers/\n (etc...)\n\n AspNetCoreTodo.UnitTests/\n AspNetCoreTodo.UnitTests.csproj\nSince the test project will use the classes defined in your main project, you'll need to add a reference to the AspNetCoreTodo project:\ndotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj\nDelete the UnitTest1.cs file that's automatically created. You're ready to write your first test.\n\nIf you're using Visual Studio Code, you may need to close and reopen the Visual Studio Code window to get code completion working in the new project.\n\nWrite a service test\nTake a look at the logic in the AddItemAsync() method of the TodoItemService:\npublic async Task AddItemAsync(\n TodoItem newItem, ApplicationUser user)\n{\n newItem.Id = Guid.NewGuid();\n newItem.IsDone = false;\n newItem.DueAt = DateTimeOffset.Now.AddDays(3);\n newItem.UserId = user.Id;\n\n _context.Items.Add(newItem);\n\n var saveResult = await _context.SaveChangesAsync();\n return saveResult == 1;\n}\n\nThis method makes a number of decisions or assumptions about the new item (in other words, performs business logic on the new item) before it actually saves it to the database:\n\nThe UserId property should be set to the user's ID\nNew items should always be incomplete (IsDone = false)\nThe title of the new item should be copied from newItem.Title\nNew items should always be due 3 days from now\n\nImagine if you or someone else refactored the AddItemAsync() method and forgot about part of this business logic. The behavior of your application could change without you realizing it! You can prevent this by writing a test that double-checks that this business logic hasn't changed (even if the method's internal implementation changes).\n\nIt might seem unlikely now that you could introduce a change in business logic without realizing it, but it becomes much harder to keep track of decisions and assumptions in a large, complex project. The larger your project is, the more important it is to have automated checks that make sure nothing has changed!\n\nTo write a unit test that will verify the logic in the TodoItemService, create a new class in your test project:\nAspNetCoreTodo.UnitTests/TodoItemServiceShould.cs\nusing System;\nusing System.Threading.Tasks;\nusing AspNetCoreTodo.Data;\nusing AspNetCoreTodo.Models;\nusing AspNetCoreTodo.Services;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\n\nnamespace AspNetCoreTodo.UnitTests\n{\n public class TodoItemServiceShould\n {\n [Fact]\n public async Task AddNewItemAsIncompleteWithDueDate()\n {\n // ...\n }\n }\n}\n\n\nThere are many different ways of naming and organizing tests, all with different pros and cons. I like postfixing my test classes with Should to create a readable sentence with the test method name, but feel free to use your own style!\n\nThe [Fact] attribute comes from the xUnit.NET package, and it marks this method as a test method.\nThe TodoItemService requires an ApplicationDbContext, which is normally connected to your database. You won't want to use that for tests. Instead, you can use Entity Framework Core's in-memory database provider in your test code. Since the entire database exists in memory, it's wiped out every time the test is restarted. And, since it's a proper Entity Framework Core provider, the TodoItemService won't know the difference!\nUse a DbContextOptionsBuilder to configure the in-memory database provider, and then make a call to AddItemAsync():\nvar options = new DbContextOptionsBuilder()\n .UseInMemoryDatabase(databaseName: \"Test_AddNewItem\").Options;\n\n// Set up a context (connection to the \"DB\") for writing\nusing (var context = new ApplicationDbContext(options))\n{\n var service = new TodoItemService(context);\n\n var fakeUser = new ApplicationUser\n {\n Id = \"fake-000\",\n UserName = \"fake@example.com\"\n };\n\n await service.AddItemAsync(new TodoItem\n {\n Title = \"Testing?\"\n }, fakeUser);\n}\n\nThe last line creates a new to-do item called Testing?, and tells the service to save it to the (in-memory) database.\nTo verify that the business logic ran correctly, write some more code below the existing using block:\n// Use a separate context to read data back from the \"DB\"\nusing (var context = new ApplicationDbContext(options))\n{\n var itemsInDatabase = await context\n .Items.CountAsync();\n Assert.Equal(1, itemsInDatabase);\n\n var item = await context.Items.FirstAsync();\n Assert.Equal(\"Testing?\", item.Title);\n Assert.Equal(false, item.IsDone);\n\n // Item should be due 3 days from now (give or take a second)\n var difference = DateTimeOffset.Now.AddDays(3) - item.DueAt;\n Assert.True(difference \nThe first assertion is a sanity check: there should never be more than one item saved to the in-memory database. Assuming that's true, the test retrieves the saved item with FirstAsync and then asserts that the properties are set to the expected values.\n\nBoth unit and integration tests typically follow the AAA (Arrange-Act-Assert) pattern: objects and data are set up first, then some action is performed, and finally the test checks (asserts) that the expected behavior occurred.\n\nAsserting a datetime value is a little tricky, since comparing two dates for equality will fail if even the millisecond components are different. Instead, the test checks that the DueAt value is less than a second away from the expected value.\nRun the test\nOn the terminal, run this command (make sure you're still in the AspNetCoreTodo.UnitTests directory):\ndotnet test\nThe test command scans the current project for tests (marked with [Fact] attributes in this case), and runs all the tests it finds. You'll see output similar to:\nStarting test execution, please wait...\n Discovering: AspNetCoreTodo.UnitTests\n Discovered: AspNetCoreTodo.UnitTests\n Starting: AspNetCoreTodo.UnitTests\n Finished: AspNetCoreTodo.UnitTests\n\nTotal tests: 1. Passed: 1. Failed: 0. Skipped: 0.\nTest Run Successful.\nTest execution time: 1.9074 Seconds\nYou now have one test providing test coverage of the TodoItemService. As an extra challenge, try writing unit tests that ensure:\n\nThe MarkDoneAsync() method returns false if it's passed an ID that doesn't exist\nThe MarkDoneAsync() method returns true when it makes a valid item as complete\nThe GetIncompleteItemsAsync() method returns only the items owned by a particular user\n\n"},"chapters/automated-testing/integration-testing.html":{"url":"chapters/automated-testing/integration-testing.html","title":"集成测试","keywords":"","body":"集成测试\n与单元测试相比,集成测试在范围上大得多。它检验整个程序栈。集成测试并不会把一个类或组件隔离出来,而是确保你程序的所有组件协作良好,这些组件包括:路由、控制器、服务、数据库访问等等。\n与单元测试相比,集成测试较慢,并且涵盖的范围较大,所以,一般来说,一个项目会有大量的单元测试内容,而集成测试的内容则屈指可数。\n为了测试整个程序栈(包括控制器路由),集成测试往往像网络浏览器那样向程序发起 HTTP 请求。\n要执行一个集成测试,你也可以启动程序,并手动向http://localhost:5000发起请求。不过,ASP.NET Core 提供了一个上佳的替代品:TestServer 类。这个类能够在测试期间托管你的程序,并在测试完成之后自动关闭它。\n创建一个测试项目\n如果你此刻位于项目目录,cd 到上一层的 AspNetCoreTodo 目录,使用以下命令搭建一个新项目:\ndotnet new xunit -o AspNetCoreTodo.IntegrationTests\n你现在的目录结构看起来应该是这样:\nAspNetCoreTodo/\n AspNetCoreTodo/\n AspNetCoreTodo.csproj\n Controllers/\n (etc...)\n\n AspNetCoreTodo.UnitTests/\n AspNetCoreTodo.UnitTests.csproj\n\n AspNetCoreTodo.IntegrationTests/\n AspNetCoreTodo.IntegrationTests.csproj\n\n如果你愿意,可以把单元测试和集成测试放置在同一个项目里。对大型项目而言,通常会把它们分开,以便于它们各自独立运行。\n\n既然这个测试项目要用到主项目中的类,你需要添加一个引用指向主项目:\ndotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj\n还需要添加 NuGet 包 Microsoft.AspNetCore.TestHost:\ndotnet add package Microsoft.AspNetCore.TestHost\n删除 dotnet new 默认创建的文件 UnitTest1.cs,这样你就为集成测试的编写准备就绪了。\n编写集成测试\n在每次集成测试执行之前,需要进行一些配置。为免配置相关的代码把测试代码弄的乱七八糟,你可以把配置相关的内容提取到一个独立的类里。创建一个名为 TestFixture 的类:\nAspNetCoreTodo.IntegrationTests/TestFixture.cs\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net.Http;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Microsoft.Extensions.Configuration;\n\nnamespace AspNetCoreTodo.IntegrationTests\n{\n public class TestFixture : IDisposable \n {\n private readonly TestServer _server;\n\n public HttpClient Client { get; }\n\n public TestFixture()\n {\n var builder = new WebHostBuilder()\n .UseStartup()\n .ConfigureAppConfiguration((context, config) =>\n {\n config.SetBasePath(Path.Combine(\n Directory.GetCurrentDirectory(),\n \"..\\\\..\\\\..\\\\..\\\\AspNetCoreTodo\"));\n\n config.AddJsonFile(\"appsettings.json\");\n });\n\n _server = new TestServer(builder);\n\n Client = _server.CreateClient();\n Client.BaseAddress = new Uri(\"http://localhost:8888\");\n }\n\n public void Dispose()\n {\n Client.Dispose();\n _server.Dispose();\n }\n }\n}\n\n这个类配置好了一个 TestServer,并使测试代码干净利索。\n现在你(真的)可以开始编写集成测试了。创建一个名为 TodoRouteShould 的类:\nAspNetCoreTodo.IntegrationTests/TodoRouteShould.cs\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace AspNetCoreTodo.IntegrationTests\n{\n public class TodoRouteShould : IClassFixture\n {\n private readonly HttpClient _client;\n\n public TodoRouteShould(TestFixture fixture)\n {\n _client = fixture.Client;\n }\n\n [Fact]\n public async Task ChallengeAnonymousUser()\n {\n // Arrange\n var request = new HttpRequestMessage(\n HttpMethod.Get, \"/todo\");\n\n // Act: request the /todo route\n var response = await _client.SendAsync(request);\n\n // Assert: the user is sent to the login page\n Assert.Equal(\n HttpStatusCode.Redirect,\n response.StatusCode);\n\n Assert.Equal(\n \"http://localhost:8888/Account\" +\n \"/Login?ReturnUrl=%2Ftodo\",\n response.Headers.Location.ToString());\n }\n }\n}\n\n这个测试发起一个匿名(未登录)的请求到路径 /todo,并验证浏览器被重定向到了登录页面。\n这是个很适合集成测试的使用场景,因为它涵盖了程序的多个组件:路由系统、控制器、控制器被标记了 [Authorize] 等等。这是个良好的测试点,因为它确保你不会意外地弄丢了 [Authorize] 属性,从而导致待办事项视图对所有人可见。\n在终端窗口运行 dotnet test,如果一切工作顺利,你会看到这样的成功信息:\nStarting test execution, please wait...\n Discovering: AspNetCoreTodo.IntegrationTests\n Discovered: AspNetCoreTodo.IntegrationTests\n Starting: AspNetCoreTodo.IntegrationTests\n Finished: AspNetCoreTodo.IntegrationTests\n\nTotal tests: 1. Passed: 1. Failed: 0. Skipped: 0.\nTest Run Successful.\nTest execution time: 2.0588 Seconds\n本章总结\n测试是个宽泛的话题,还有很多东西需要学习。本章节没有涉及 UI 测试,也没有对前端(JavaScript)代码进行测试——它本身可能就需要一整本书去讲述。不过,你应该已经掌握了一些基本的技能和知识,可用于实践并学习更多相关测试程序的编写。\n像以往一样,ASP.NET Core 文档(https://docs.asp.net)和 StackOverflow 都是用于了解更多知识以及遇到问题时查找答案的好资源。\n\nIntegration testing\nCompared to unit tests, integration tests are much larger in scope. exercise the whole application stack. Instead of isolating one class or method, integration tests ensure that all of the components of your application are working together properly: routing, controllers, services, database code, and so on.\nIntegration tests are slower and more involved than unit tests, so it's common for a project to have lots of small unit tests but only a handful of integration tests.\nIn order to test the whole stack (including controller routing), integration tests typically make HTTP calls to your application just like a web browser would.\nTo perform an integration test, you could start your application and manually make requests to http://localhost:5000. However, ASP.NET Core provides a better alternative: the TestServer class. This class can host your application for the duration of the test, and then stop it automatically when the test is complete.\nCreate a test project\nIf you're currently in your project directory, cd up one level to the root AspNetCoreTodo directory. Use this command to scaffold a new test project:\ndotnet new xunit -o AspNetCoreTodo.IntegrationTests\nYour directory structure should now look like this:\nAspNetCoreTodo/\n AspNetCoreTodo/\n AspNetCoreTodo.csproj\n Controllers/\n (etc...)\n\n AspNetCoreTodo.UnitTests/\n AspNetCoreTodo.UnitTests.csproj\n\n AspNetCoreTodo.IntegrationTests/\n AspNetCoreTodo.IntegrationTests.csproj\n\nIf you prefer, you can keep your unit tests and integration tests in the same project. For large projects, it's common to split them up so it's easy to run them separately.\n\nSince the test project will use the classes defined in your main project, you'll need to add a reference to the main project:\ndotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj\nYou'll also need to add the Microsoft.AspNetCore.TestHost NuGet package:\ndotnet add package Microsoft.AspNetCore.TestHost\nDelete the UnitTest1.cs file that's created by dotnet new. You're ready to write an integration test.\nWrite an integration test\nThere are a few things that need to be configured on the test server before each test. Instead of cluttering the test with this setup code, you can keep this setup in a separate class. Create a new class called TestFixture:\nAspNetCoreTodo.IntegrationTests/TestFixture.cs\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net.Http;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Microsoft.Extensions.Configuration;\n\nnamespace AspNetCoreTodo.IntegrationTests\n{\n public class TestFixture : IDisposable \n {\n private readonly TestServer _server;\n\n public HttpClient Client { get; }\n\n public TestFixture()\n {\n var builder = new WebHostBuilder()\n .UseStartup()\n .ConfigureAppConfiguration((context, config) =>\n {\n config.SetBasePath(Path.Combine(\n Directory.GetCurrentDirectory(),\n \"..\\\\..\\\\..\\\\..\\\\AspNetCoreTodo\"));\n\n config.AddJsonFile(\"appsettings.json\");\n });\n\n _server = new TestServer(builder);\n\n Client = _server.CreateClient();\n Client.BaseAddress = new Uri(\"http://localhost:8888\");\n }\n\n public void Dispose()\n {\n Client.Dispose();\n _server.Dispose();\n }\n }\n}\n\nThis class takes care of setting up a TestServer, and will help keep the tests themselves clean and tidy.\nNow you're (really) ready to write an integration test. Create a new class called TodoRouteShould:\nAspNetCoreTodo.IntegrationTests/TodoRouteShould.cs\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace AspNetCoreTodo.IntegrationTests\n{\n public class TodoRouteShould : IClassFixture\n {\n private readonly HttpClient _client;\n\n public TodoRouteShould(TestFixture fixture)\n {\n _client = fixture.Client;\n }\n\n [Fact]\n public async Task ChallengeAnonymousUser()\n {\n // Arrange\n var request = new HttpRequestMessage(\n HttpMethod.Get, \"/todo\");\n\n // Act: request the /todo route\n var response = await _client.SendAsync(request);\n\n // Assert: the user is sent to the login page\n Assert.Equal(\n HttpStatusCode.Redirect,\n response.StatusCode);\n\n Assert.Equal(\n \"http://localhost:8888/Account\" +\n \"/Login?ReturnUrl=%2Ftodo\",\n response.Headers.Location.ToString());\n }\n }\n}\n\nThis test makes an anonymous (not-logged-in) request to the /todo route and verifies that the browser is redirected to the login page.\nThis scenario is a good candidate for an integration test, because it involves multiple components of the application: the routing system, the controller, the fact that the controller is marked with [Authorize], and so on. It's also a good test because it ensures you won't ever accidentally remove the [Authorize] attribute and make the to-do view accessible to everyone.\nRun the test\nRun the test in the terminal with dotnet test. If everything's working right, you'll see a success message:\nStarting test execution, please wait...\n Discovering: AspNetCoreTodo.IntegrationTests\n Discovered: AspNetCoreTodo.IntegrationTests\n Starting: AspNetCoreTodo.IntegrationTests\n Finished: AspNetCoreTodo.IntegrationTests\n\nTotal tests: 1. Passed: 1. Failed: 0. Skipped: 0.\nTest Run Successful.\nTest execution time: 2.0588 Seconds\nWrap up\nTesting is a broad topic, and there's much more to learn. This chapter doesn't touch on UI testing or testing frontend (JavaScript) code, which probably deserve entire books of their own. You should, however, have the skills and base knowledge you need to learn more about testing and to practice writing tests for your own applications.\nThe ASP.NET Core documentation (https://docs.asp.net) and Stack Overflow are great resources for learning more and finding answers when you get stuck.\n"},"chapters/deploy-the-application/":{"url":"chapters/deploy-the-application/","title":"部署程序","keywords":"","body":"部署程序\n万事俱备,只欠东风。当一个良好的程序构建完成,就应该与全世界分享它了。\n因为 ASP.NET Core 程序能够运行在 Windows、Mac 以及 Linux 上,你拥有多种部署程序的方式。这一章里,我将教给你最常用(也是最简单)的上线方式。\n部署方式\nASP.NET Core 通常会部署到下列环境之一:\n\n一部 Dockers 主机 任何有能力托管 Docker 容器的机器都能用来托管 ASP.NET Core 程序。创建 Docker 镜像是个非常快捷的部署程序的方式,尤其是在你熟悉 Docker 的情况下。(如果你还不熟悉,别担心!我会在后面逐步介绍。)\n\nAzure 微软的 Azure 对 ASP.NET Core 程序提供原生的支持。如果你有一个 Azure 订阅,你只要创建一个 Web App 并上传你的项目文件即可。下一节,我会介绍通过 Azure CLI 完成这种操作。\n\nLinux (连同 Nginx) 如果你不想用 Docker 那个方式,依然可以在任意 Linux 服务器(这包括亚马逊的 EC2 和 DigitalOcean 虚拟机)上托管程序。通常把 ASP.NET Core 跟 Nginx 反向代理配对工作。(下面有更详细的 Nginx 相关内容。)\n\nWinddows 你可以在 Windows 上使用 IIS 网络服务器托管 ASP.NET Core 程序。一般来说,部署到 Azure 更容易(也更便宜),不过你要是愿意自己管理 Windows 服务器,这也是个可行的方案。\n\n\nKestrel 和 反向代理\n\n如果你不在意 ASP.NET Core 程序托管工作的细节,而只希望参考分步的指导,可以跳转到后续两小节的任一个继续阅读。\n\nASP.NET Core 里包含一个名为 Kestrel 的快速轻量级的 web 开发服务器。你每次运行 dotnet run 并浏览 http://localhost:5000 的时候,用的就是这个服务器。当你把程序部署到生产环境的时候,它仍会在幕后使用 Kestrel。但强烈建议你在 Kestrel 之前添加一个反向代理,因为 Kestrel 并不具有负载均衡和其它更成熟的 Web 服务器所具有的其它特性。\n在 Linux(和 Docker 容器)里,你可以用 Nginx 或者 Apache web 服务器接收从互联网上传入的请求,并派发到你用 Kestrel 托管的程序。如果你用的是 Windows,IIS 也能处理这个工作。\n如果你把程序托管在 Azure,这些就都是自动为你处理的。在 Docker 那一节,我会讲述如何配置 Nginx 进行反向代理。\n\nDeploy the application\nYou've come a long way, but you're not quite done yet. Once you've created a great application, you need to share it with the world!\nBecause ASP.NET Core applications can run on Windows, Mac, or Linux, there are a number of different ways you can deploy your application. In this chapter, I'll show you the most common (and easiest) ways to go live.\nDeployment options\nASP.NET Core applications are typically deployed to one of these environments:\n\nA Docker host. Any machine capable of hosting Docker containers can be used to host an ASP.NET Core application. Creating a Docker image is a very quick way to get your application deployed, especially if you're familiar with Docker. (If you're not, don't worry! I'll cover the steps later.)\n\nAzure. Microsoft Azure has native support for ASP.NET Core applications. If you have an Azure subscription, you just need to create a Web App and upload your project files. I'll cover how to do this with the Azure CLI in the next section.\n\nLinux (with Nginx). If you don't want to go the Docker route, you can still host your application on any Linux server (this includes Amazon EC2 and DigitalOcean virtual machines). It's typical to pair ASP.NET Core with the Nginx reverse proxy. (More about Nginx below.)\n\nWindows. You can use the IIS web server on Windows to host ASP.NET Core applications. It's usually easier (and cheaper) to just deploy to Azure, but if you prefer managing Windows servers yourself, it'll work just fine.\n\n\nKestrel and reverse proxies\n\nIf you don't care about the guts of hosting ASP.NET Core applications and just want the step-by-step instructions, feel free to skip to one of the next two sections.\n\nASP.NET Core includes a fast, lightweight web server called Kestrel. It's the server you've been using every time you ran dotnet run and browsed to http://localhost:5000. When you deploy your application to a production environment, it'll still use Kestrel behind the scenes. However, it's recommended that you put a reverse proxy in front of Kestrel, because Kestrel doesn't yet have load balancing and other features that more mature web servers have.\nOn Linux (and in Docker containers), you can use Nginx or the Apache web server to receive incoming requests from the internet and route them to your application hosted with Kestrel. If you're on Windows, IIS does the same thing.\nIf you're using Azure to host your application, this is all done for you automatically. I'll cover setting up Nginx as a reverse proxy in the Docker section.\n"},"chapters/deploy-the-application/deploy-to-azure.html":{"url":"chapters/deploy-the-application/deploy-to-azure.html","title":"部署到 Azure","keywords":"","body":"部署到 Azure\n把你的 ASP.NET Core 程序部署到 Azure 只需要简单几步。你可以通过 Azure 的网上门户实施,也可以在 Azure CLI 命令行工具里实施。我会讲解后者。\n准备材料\n\nGit(使用 git --version 命令确认它已经安装了)\nAzure CLI(按照 https://github.com/Azure/azure-cli 的指示进行安装)\n一个 Azure 订阅(免费的订阅就可以了)\n项目的根目录里要有一个部署配置文件\n\n创建部署配置文件\n因为你的目录结构里存在多个项目(Web项目和两个测试项目),Azure 并不知道该把哪个发布出去。为解决这个问题,在你的目录结构顶层创建一个名为 .deployment 的文件:\n.deployment\n[config]\nproject = AspNetCoreTodo/AspNetCoreTodo.csproj\n\n确保你把这个文件保存为 .deployment,而不带有什么其它的零碎儿。(在 Windows 上,你可能需要把文件名用引号括起来,比如 \".deployment\",以此避免被添加一个 .txt 扩展名。)\n如果你在顶层目录里执行 ls 或者 dir 命令,应该看到如下的内容:\n.deployment\nAspNetCoreTodo\nAspNetCoreTodo.IntegrationTests\nAspNetCoreTodo.UnitTests\n设置 Azure 资源\n如果你的 Azure CLI 才初次安装完成,运行:\naz login\n并按照提示在你的电脑上登录,然后,为这个程序创建一个新的 资源组(Resource Group):\naz group create -l westus -n AspNetCoreTodoGroup\n这个命令在美国西部(West US)地区创建了一个资源组。如果你距离美国西部很远,请使用 az account list-locations 命令获取一个地点列表,并找出距离你比较近的一个。\n接下来,在你刚刚创建的组里,创建一个 App Service 方案:\naz appservice plan create -g AspNetCoreTodoGroup -n AspNetCoreTodoPlan --sku F1\n\n提示:F1 是免费的 app 方案。如果想在你的应用上使用自己指定的域名,请使用 D1($10/月)或更高级的方案。\n\n现在,在这个 App Service 方案里创建一个 Web 应用:\naz webapp create -g AspNetCoreTodoGroup -p AspNetCoreTodoPlan -n MyTodoApp\n这个应用的名称(上面的 MyTodoApp)在 Azure 上必须是全局唯一的。一旦这个应用创建好了,会具有一个以下格式的默认 URL:http://mytodoapp.azurewebsites.net\n把项目文件部署到 Azure\n你可以用 Git 把程序文件推送到 Azure 网络应用。如果你本地目录尚未作为一个 Git 仓库管理,执行下列命令进行设置:\ngit init\ngit add .\ngit commit -m \"First commit!\"\n接下来,为部署工作创建一个 Azure 用户名和密码,\naz webapp deployment user set --user-name nate\n按提示创建密码。然后用 config-local-git 得到一个 Git URL:\naz webapp deployment source config-local-git -g AspNetCoreTodoGroup -n MyTodoApp --out tsv\n\nhttps://nate@mytodoapp.scm.azurewebsites.net/MyTodoApp.git\n复制这个 URL 到剪切板,并把它在本地仓库里添加为一个 Git remote:\ngit remote add azure \n你只需要执行这些步骤一次。现在开始,任何时候,你需要推送程序文件到 Azure ,只需要在 Git 里提交它们,然后运行:\ngit push azure master\n程序部署到 Azure 的时候,你会看到一系列的日志信息。\n输出结束之后,浏览 http://yourappname.azurewebsites.net 以检验结果。\n\nDeploy to Azure\nDeploying your ASP.NET Core application to Azure only takes a few steps. You can do it through the Azure web portal, or on the command line using the Azure CLI. I'll cover the latter.\nWhat you'll need\n\nGit (use git --version to make sure it's installed)\nThe Azure CLI (follow the install instructions at https://github.com/Azure/azure-cli)\nAn Azure subscription (the free subscription is fine)\nA deployment configuration file in your project root\n\nCreate a deployment configuration file\nSince there are multiple projects in your directory structure (the web application, and two test projects), Azure won't know which one to publish. To fix this, create a file called .deployment at the very top of your directory structure:\n.deployment\n[config]\nproject = AspNetCoreTodo/AspNetCoreTodo.csproj\n\nMake sure you save the file as .deployment with no other parts to the name. (On Windows, you may need to put quotes around the filename, like \".deployment\", to prevent a .txt extension from being added.)\nIf you ls or dir in your top-level directory, you should see these items:\n.deployment\nAspNetCoreTodo\nAspNetCoreTodo.IntegrationTests\nAspNetCoreTodo.UnitTests\nSet up the Azure resources\nIf you just installed the Azure CLI for the first time, run\naz login\nand follow the prompts to log in on your machine. Then, create a new Resource Group for this application:\naz group create -l westus -n AspNetCoreTodoGroup\nThis creates a Resource Group in the West US region. If you're located far away from the western US, use az account list-locations to get a list of locations and find one closer to you.\nNext, create an App Service plan in the group you just created:\naz appservice plan create -g AspNetCoreTodoGroup -n AspNetCoreTodoPlan --sku F1\n\nF1 is the free app plan. If you want to use a custom domain name with your app, use the D1 ($10/month) plan or higher.\n\nNow create a Web App in the App Service plan:\naz webapp create -g AspNetCoreTodoGroup -p AspNetCoreTodoPlan -n MyTodoApp\nThe name of the app (MyTodoApp above) must be globally unique in Azure. Once the app is created, it will have a default URL in the format: http://mytodoapp.azurewebsites.net\nDeploy your project files to Azure\nYou can use Git to push your application files up to the Azure Web App. If your local directory isn't already tracked as a Git repo, run these commands to set it up:\ngit init\ngit add .\ngit commit -m \"First commit!\"\nNext, create an Azure username and password for deployment:\naz webapp deployment user set --user-name nate\nFollow the instructions to create a password. Then use config-local-git to spit out a Git URL:\naz webapp deployment source config-local-git -g AspNetCoreTodoGroup -n MyTodoApp --out tsv\n\nhttps://nate@mytodoapp.scm.azurewebsites.net/MyTodoApp.git\nCopy the URL to the clipboard, and use it to add a Git remote to your local repository:\ngit remote add azure \nYou only need to do these steps once. Now, whenever you want to push your application files to Azure, check them in with Git and run\ngit push azure master\nYou'll see a stream of log messages as the application is deployed to Azure.\nWhen it's complete, browse to http://yourappname.azurewebsites.net to check out the app!\n"},"chapters/deploy-the-application/deploy-with-docker.html":{"url":"chapters/deploy-the-application/deploy-with-docker.html","title":"使用 Docker 进行部署","keywords":"","body":"使用 Docker 进行部署\n如果你不使用 Azure 这样的平台,像 Docker 这样的容器化技术能极大地简化把 web 程序部署到你自己服务器上的工作。不再需要浪费时间在一个服务器上配置你程序所需的依赖、复制文件、重启进程,你只需要创建一个 Docker 镜像,里面包含你程序运行所需的一切,然后在任何 Docker 宿主机上作为容器启动起来就行了。\nDocker 也便于把你的应用扩展为多个服务器。一旦你创建了一个镜像,用它来创建 1 个容器和 100 个容器所需要的工作是一样的。\n开始之前,需要在你的开发机上安装 Docker CLI。搜索 \"get docker for (mac/windows/linux)\" 并执行 Docker 官网的提示内容。要检验是否安装成功,可以执行:\ndocker version\n添加 Dockerfile\n首先需要的就是一个 Dockerfile,它就像个清单,告诉 Docker 你程序的构建和运行需要些什么。\n在程序根目录,也就是最外层的 AspNetCoreTodo 文件夹里,创建一个名为 Dockerfile(没有扩展名)的文件。用你常用的编辑器打开它,输入下面这行:\nFROM microsoft/dotnet:2.0-sdk AS build\n\n这指示 Docker 以 microsoft/dotnet:2.0-sdk 为基础创建你的镜像。这个镜像是微软发布的,其中包含了执行 dotnet build 编译程序所需的工具和依赖。以这个预编译镜像为基础,Docker 可以优化镜像生成过程并使它容量紧凑。\n接下来,添加这一行:\nCOPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/\n\n这条 COPY 指令复制 .csproj 项目文件到镜像里的路径 /app/AspNetCoreTodo/ 下。注意实际的代码(.cs 文件)并未复制到镜像里。你稍后即可弄清个中缘由。\nWORKDIR /app/AspNetCoreTodo\nRUN dotnet restore\n\nWORKDIR 是 Docker 里的 cd。Dockerfile 中之后的命令都会在这个 /app/AspNetCoreTodo 文件夹内执行,该文件夹是上一步的 COPY 命令创建的。\n运行 dotnet restore 命令重建在 .csproj 中定义的那些程序所需的 NuGet 包。在添加其它代码 之前 于镜像中重建这些包,Docker 将有能力缓存这些重建的包。然后,当你修改代码(而没修改项目文件中定义的包)时,重建这个 Docker 镜像将会非常迅速。\n现在,就到了复制其余代码并编译程序的时候了:\nCOPY AspNetCoreTodo/. ./AspNetCoreTodo/\nRUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest=\"false\"\n\ndotnet publish 命令编译项目,而 -o out 标识会将结果输出到一个名为 out 的目录里。\n这些编译好的文件,将会通过这最终的几条命令,运行起这个程序:\nFROM microsoft/dotnet:2.0-runtime AS runtime\nENV ASPNETCORE_URLS http://+:80\nWORKDIR /app\nCOPY --from=build /app/AspNetCoreTodo/out ./\nENTRYPOINT [\"dotnet\", \"AspNetCoreTodo.dll\"]\n\nFROM 命令再次被用到,以选择一个较小的镜像,其中仅含有运行程序所需的依赖。ENV 命令用于容器中的设置环境变量,环境变量 ASPNETCORE_URLS 指示 ASP.NET Core 应该把服务绑定到哪个网卡和端口上(本例中时 80 端口)。\nENTRYPOINT 命令给 Docker 指出了在被运行的时候去执行 dotnet AspNetCoreTodo.dll。这条命令告诉 dotnet,使用先前由 dotnet publish 编译出来的文件启动你的程序。(当你在开发时运行 dotnet run,它一步就完成了这些事情。)\n完整的 Dockerfile 看起来是这样的:\nDockerfile\nFROM microsoft/dotnet:2.0-sdk AS build\nCOPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/\nWORKDIR /app/AspNetCoreTodo\nRUN dotnet restore\n\nCOPY AspNetCoreTodo/. ./\nRUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest=\"false\"\n\nFROM microsoft/dotnet:2.0-runtime AS runtime\nENV ASPNETCORE_URLS http://+:80\nWORKDIR /app\nCOPY --from=build /app/AspNetCoreTodo/out ./\nENTRYPOINT [\"dotnet\", \"AspNetCoreTodo.dll\"]\n\n创建一个镜像\n确保 Dockerfile 已经保存好了,然后用 docker build 命令创建一个镜像:\ndocker build -t aspnetcoretodo .\n不要漏掉结尾那个句点!它告诉 Docker 在当前目录下查找 Dockerfile。\n一旦镜像创建完成,你可以运行 docker images 命令列出你本地电脑上的全部镜像。要通过容器尝试一下,请执行:\ndocker run --name aspnetcoretodo_sample --rm -it -p 8080:80 aspnetcoretodo\n-it 标识告诉 Docker 以交互模式运行这个容器(输出到终端,而不是在后台运行)。当你想要停止这个容器的时候,按 Control-C。\n还记得环境变量 ASPNETCORE_URLS 指示 ASP.NET Core 去监听 80 端口吗?这里的 -p 8080:80 选项指示 Docker 把 你的 电脑的 8080 端口映射到 容器的 80端口。打开你的浏览器,浏览地址 http://localhost:8080 去查看运行在容器中的程序。\n设置 Nginx\n在本章开头,我提到过,你应该使用一个 Nginx 之类的反向代理服务器,把请求代理到 Kestrel 上。这件事也可以用 Docker 来做。\n整体架构会包括两个容器:一个 Nginx 容器监听 80 端口,把请求转发到另一个运行着 Kestrel 并监听 5000 端口的容器。\nNginx 容器自己也需要一个 Dockerfile。为避免跟你刚才创建那个 Dockerfile 冲突,在 Web 程序根目录新建一个目录:\nmkdir nginx\n创建一个新的 Dockerfile 并添加这些行:\nnginx/Dockerfile\nFROM nginx\nCOPY nginx.conf /etc/nginx/nginx.conf\n\n接下来,创建一个 nginx.conf 文件:\nnginx/nginx.conf\nevents { worker_connections 1024; }\n\nhttp {\n server {\n listen 80;\n location / {\n proxy_pass http://kestrel:80;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection 'keep-alive';\n proxy_set_header Host $host;\n proxy_cache_bypass $http_upgrade;\n }\n }\n}\n这个配置文件告诉 Nginx 把接到的请求转发到 http://kestrel:80。(你马上就会知道为什么要使用 kestrel 作为主机名。)\n\n当你把程序部署到生产环境,你应该添加 server_name 指令,并验证及限定 host 头字段为一个已知的有效值(known good values)。更多信息请参见:https://github.com/aspnet/Announcements/issues/295\n\n设置 Docker Compose\n还需要创建一个文件,回到 Web 程序的根目录,创建 docker-compose.yml:\ndocker-compose.yml\nnginx:\n build: ./nginx\n links:\n - kestrel:kestrel\n ports:\n - \"80:80\"\nkestrel:\n build: .\n ports:\n - \"80\"\n\nDocker Compose 是个帮助你创建并运行多容器程序的工具。这个配置文件定义了两个容器: 用 ./nginx/Dockerfile 清单创建 nginx,用 ./Dockerfile 创建 kestrel。这两个容器显式地链接在一起,所以它们可以互相通信。\n你可以运行以下指令来启动这个多容器程序:\ndocker-compose up\n打开一个浏览器并导航至 http://localhost(不是 8080!)。Nginx 在 80 (HTTP 的默认)端口上进行监听,并把请求转发到由 Kestrel 托管的 ASP.NET Core 程序。\n搭建 Docker 服务器\n详尽的设置指令超出了这本书的范畴,但是任何较新的 Linux 发行版(例如 Ubuntu)都可以搭建成一个 Docker 宿主。例如,你可以用亚马逊 EC2 创建一个虚拟机,在上面安装 Docker 服务,为此你可以搜索 “amazon ec2 set up docker” 以获取说明。\n我更喜欢用 DigitalOcean,因为他们把入门的门槛降得非常低。DigitalOcean 既有现成的 Docker 虚拟机,也有关于搭建和运行 Docker 的深度教程(请搜索“digitalocean docker”)。\n\nDeploy with Docker\nIf you aren't using a platform like Azure, containerization technologies like Docker can make it easy to deploy web applications to your own servers. Instead of spending time configuring a server with the dependencies it needs to run your app, copying files, and restarting processes, you can simply create a Docker image that describes everything your app needs to run, and spin it up as a container on any Docker host.\nDocker can make scaling your app across multiple servers easier, too. Once you have an image, using it to create 1 container is the same process as creating 100 containers.\nBefore you start, you need the Docker CLI installed on your development machine. Search for \"get docker for (mac/windows/linux)\" and follow the instructions on the official Docker website. You can verify that it's installed correctly with\ndocker version\nAdd a Dockerfile\nThe first thing you'll need is a Dockerfile, which is like a recipe that tells Docker what your application needs to build and run.\nCreate a file called Dockerfile (no extension) in the root, top-level AspNetCoreTodo folder. Open it in your favorite editor. Write the following line:\nFROM microsoft/dotnet:2.0-sdk AS build\n\nThis tells Docker to use the microsoft/dotnet:2.0-sdk image as a starting point. This image is published by Microsoft and contains the tools and dependencies you need to execute dotnet build and compile your application. By using this pre-built image as a starting point, Docker can optimize the image produced for your app and keep it small.\nNext, add this line:\nCOPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/\n\nThe COPY command copies the .csproj project file into the image at the path /app/AspNetCoreTodo/. Note that none of the actual code (.cs files) have been copied into the image yet. You'll see why in a minute.\nWORKDIR /app/AspNetCoreTodo\nRUN dotnet restore\n\nWORKDIR is the Docker equivalent of cd. This means any commands executed next will run from inside the /app/AspNetCoreTodo directory that the COPY command created in the last step.\nRunning the dotnet restore command restores the NuGet packages that the application needs, defined in the .csproj file. By restoring packages inside the image before adding the rest of the code, Docker is able to cache the restored packages. Then, if you make code changes (but don't change the packages defined in the project file), rebuilding the Docker image will be super fast.\nNow it's time to copy the rest of the code and compile the application:\nCOPY AspNetCoreTodo/. ./AspNetCoreTodo/\nRUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest=\"false\"\n\nThe dotnet publish command compiles the project, and the -o out flag puts the compiled files in a directory called out.\nThese compiled files will be used to run the application with the final few commands:\nFROM microsoft/dotnet:2.0-runtime AS runtime\nENV ASPNETCORE_URLS http://+:80\nWORKDIR /app\nCOPY --from=build /app/AspNetCoreTodo/out ./\nENTRYPOINT [\"dotnet\", \"AspNetCoreTodo.dll\"]\n\nThe FROM command is used again to select a smaller image that only has the dependencies needed to run the application. The ENV command is used to set environment variables in the container, and the ASPNETCORE_URLS environment variable tells ASP.NET Core which network interface and port it should bind to (in this case, port 80).\nThe ENTRYPOINT command lets Docker know that the container should be started as an executable by running dotnet AspNetCoreTodo.dll. This tells dotnet to start up your application from the compiled file created by dotnet publish earlier. (When you do dotnet run during development, you're accomplishing the same thing in one step.)\nThe full Dockerfile looks like this:\nDockerfile\nFROM microsoft/dotnet:2.0-sdk AS build\nCOPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/\nWORKDIR /app/AspNetCoreTodo\nRUN dotnet restore\n\nCOPY AspNetCoreTodo/. ./\nRUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest=\"false\"\n\nFROM microsoft/dotnet:2.0-runtime AS runtime\nENV ASPNETCORE_URLS http://+:80\nWORKDIR /app\nCOPY --from=build /app/AspNetCoreTodo/out ./\nENTRYPOINT [\"dotnet\", \"AspNetCoreTodo.dll\"]\n\nCreate an image\nMake sure the Dockerfile is saved, and then use docker build to create an image:\ndocker build -t aspnetcoretodo .\nDon't miss the trailing period! That tells Docker to look for a Dockerfile in the current directory.\nOnce the image is created, you can run docker images to to list all the images available on your local machine. To test it out in a container, run\ndocker run --name aspnetcoretodo_sample --rm -it -p 8080:80 aspnetcoretodo\nThe -it flag tells Docker to run the container in interactive mode (outputting to the terminal, as opposed to running in the background). When you want to stop the container, press Control-C.\nRemember the ASPNETCORE_URLS variable that told ASP.NET Core to listen on port 80? The -p 8080:80 option tells Docker to map port 8080 on your machine to the container's port 80. Open up your browser and navigate to http://localhost:8080 to see the application running in the container!\nSet up Nginx\nAt the beginning of this chapter, I mentioned that you should use a reverse proxy like Nginx to proxy requests to Kestrel. You can use Docker for this, too.\nThe overall architecture will consist of two containers: an Nginx container listening on port 80, forwarding requests to the container you just built that hosts your application with Kestrel.\nThe Nginx container needs its own Dockerfile. To keep it from conflicting with the Dockerfile you just created, make a new directory in the web application root:\nmkdir nginx\nCreate a new Dockerfile and add these lines:\nnginx/Dockerfile\nFROM nginx\nCOPY nginx.conf /etc/nginx/nginx.conf\n\nNext, create an nginx.conf file:\nnginx/nginx.conf\nevents { worker_connections 1024; }\n\nhttp {\n server {\n listen 80;\n location / {\n proxy_pass http://kestrel:80;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection 'keep-alive';\n proxy_set_header Host $host;\n proxy_cache_bypass $http_upgrade;\n }\n }\n}\nThis configuration file tells Nginx to proxy incoming requests to http://kestrel:80. (You'll see why kestrel works as a hostname in a moment.)\n\nWhen you make deploy your application to a production environment, you should add the server_name directive and validate and restrict the host header to known good values. For more information, see:\nhttps://github.com/aspnet/Announcements/issues/295\n\nSet up Docker Compose\nThere's one more file to create. Up in the root directory, create docker-compose.yml:\ndocker-compose.yml\nnginx:\n build: ./nginx\n links:\n - kestrel:kestrel\n ports:\n - \"80:80\"\nkestrel:\n build: .\n ports:\n - \"80\"\n\nDocker Compose is a tool that helps you create and run multi-container applications. This configuration file defines two containers: nginx from the ./nginx/Dockerfile recipe, and kestrel from the ./Dockerfile recipe. The containers are explicitly linked together so they can communicate.\nYou can try spinning up the entire multi-container application by running:\ndocker-compose up\nTry opening a browser and navigating to http://localhost (port 80, not 8080!). Nginx is listening on port 80 (the default HTTP port) and proxying requests to your ASP.NET Core application hosted by Kestrel.\nSet up a Docker server\nSpecific setup instructions are outside the scope of this book, but any modern flavor of Linux (like Ubuntu) can be used to set up a Docker host. For example, you could create a virtual machine with Amazon EC2, and install the Docker service. You can search for \"amazon ec2 set up docker\" (for example) for instructions.\nI like using DigitalOcean because they've made it really easy to get started. DigitalOcean has both a pre-built Docker virtual machine, and in-depth tutorials for getting Docker up and running (search for \"digitalocean docker\").\n"},"chapters/conclusion/":{"url":"chapters/conclusion/","title":"结束语","keywords":"","body":"结束语\n感谢你读完了这本简明 ASP.NET Core 手册!如果这本书有点(或者没有)用处,我很乐于倾听您的想法。请在 Twitter 上发表看法:https://twitter.com/nbarbettini\n更深入的学习\n ASP.NET Core 还有很多功能,但是无法纳入到这本小册子里,包括:\n\n构建 RESTFul 的 API 和 微服务\n把 ASP.NET Core 用于 单页面应用,例如 Angular 和 React\nRazor 页面\n打包和压缩静态资源\nWebSockets 和 SignalR\n\n如果要深入学习,以下这些方式可供参考:\n\nASP.NET Core 文档 官方的 ASP.NET Core 文档位于 https://docs.asp.net,其中包含了一些有关这些主题的,深入详尽的教程。本人强烈推荐。\n\nLinkedIn Learning 和 Pluralsight 上的教程 如果你更喜欢通过视频学习,在 Pluralsight 和 LinkedIn Learning 上就有很多非常精彩(其中某些就是来自于你们读者)。如果你在上面没有账号或者想要一张优惠券,请发信到:nate@barbettini.com。\n\nNate's 博客 我在自己的博客 https://www.recaffeinate.co 上有也写一些有关 ASP.NET Core 和其它主题的博文。\n\n\n祝你代码敲得愉快!\n关于作者\n嗨,我是 Nate!我在一个漫长的灌着咖啡的周末写了这本 简明 ASP.NET Core 手册,因为我热爱 .NET 社区,并希望以我的微薄之力付出回报。希望它帮助你学了一点儿新东西。\n你可以在 Twitter(@nbarbettini)上和我保持联系,或者在我的博客上(https://www.recaffeinate.co)。你还可以通过电子邮件(nate@barbettini.com)联系我。\n特别致谢\nJennifer,她总是支持我各种疯狂的点子。\n以下这些贡献者,提升了这本书的质量:\n\n0xNF\nMatt Welke [welkie]\nRaman Zhylich [zhilich]\n\n以下这些很棒的各国程序员,翻译了本书:\n\nsahinyanlik (土耳其语)\nwindsting、yuyi (简体中文)\n\n变更记录\n需要完整、详尽的变更记录,可以到:\nhttps://github.com/nbarbettini/little-aspnetcore-book/releases\n1.1.1 (2018-06-11): 修正了读者们发现的一些笔误。\n1.1.0 (2018-05-03): 大幅度重写了 添加新特性 一章,深入地使用了整个 MVC 框架并移除了 AJAX 模式。移除 Facebook 登录以简化安全章节、流水线式的测试和部署。修改了 Docker 指令以反映最新的优秀实践。修正了笔误,添加了来自读者的建议。还弄了个新改良的封面得瑟了一下!\n1.0.4 (2018-01-15): 为服务容器(service container)的生命周期添加说明,阐释服务端口和 -o 选项,移除 Razor 指令后的分号。修正中文版译者信息。修正其它笔误和读者反馈的问题。\n1.0.3 (2017-11-13): 笔误修正和一些读者建议的改进。\n1.0.2 (2017-10-20): 更多的Bug修正和一些小改进。添加译版的链接。\n1.0.1 (2017-09-23): Bug修正和一些小改进。\n1.0.0 (2017-09-18): 初次发布。\n\nConclusion\nThanks for making it to the end of the Little ASP.NET Core Book! If this book was helpful (or not), I'd love to hear your thoughts. Send me your comments via Twitter: https://twitter.com/nbarbettini\nHow to learn more\nThere's a lot more that ASP.NET Core can do that couldn't fit in this short book, including\n\nBuilding RESTful APIs and microservices\nUsing ASP.NET Core with single-page apps like Angular and React\nRazor Pages\nBundling and minifying static assets\nWebSockets and SignalR\n\nThere are a number of ways you can learn more:\n\nThe ASP.NET Core documentation. The official ASP.NET Core documentation at http://docs.asp.net contains a number of in-depth tutorials covering many of these topics. I'd highly recommend it!\n\nASP.NET Core in Action. This book by Andrew Lock is a comprehensive, deep dive into ASP.NET Core. You can get it from Amazon or a local bookstore.\n\nCourses on LinkedIn Learning and Pluralsight. If you learn best from videos, there are fantastic courses available on Pluralsight and LinkedIn Learning (including some by yours truly). If you don't have an account and need a coupon, send me an email: nate@barbettini.com.\n\nNate's blog. I also write about ASP.NET Core and more on my blog at https://www.recaffeinate.co.\n\n\nHappy coding!\nAbout the author\nHey, I'm Nate! I wrote the Little ASP.NET Core Book in a long, caffeine-fueled weekend because I love the .NET community and wanted to give back in my own little way. I hope it helped you learn something new!\nYou can stay in touch with me on Twitter (@nbarbettini) or on my blog (https://www.recaffeinate.co). You can also reach me via email at nate@barbettini.com.\nSpecial thanks\nTo Jennifer, who always supports my crazy ideas.\nTo the following contributors who improved the Little ASP.NET Core Book:\n\n0xNF\nMatt Welke [welkie]\nRaman Zhylich [zhilich]\n\nTo these amazing polyglot programmers who translated the Little ASP.NET Core Book:\n\nsahinyanlik (Turkish)\nwindsting, yuyi (Simplified Chinese)\n\nChangelog\nThe full, detailed changelog is always available here:\nhttps://github.com/nbarbettini/little-aspnetcore-book/releases\n1.1.1 (2018-06-11): Fixed typos found by readers.\n1.1.0 (2018-05-03): Significantly reworked the Add more features chapter to use MVC thorough the whole stack and remove the AJAX pattern. Removed Facebook login to simplify the security chapter and streamline testing and deployment. Updated the Docker instructions to reflect the latest best practices. Fixed typos and added suggestions from readers. The book also sports a new, improved cover design!\n1.0.4 (2018-01-15): Added explanation of service container lifecycles, clarified server ports and the -o flag, and removed semicolons after Razor directives. Corrected Chinese translation author credit. Fixed other small typos and issues noticed by readers.\n1.0.3 (2017-11-13): Typo fixes and small improvements suggested by readers.\n1.0.2 (2017-10-20): More bug fixes and small improvements. Added link to translations.\n1.0.1 (2017-09-23): Bug fixes and small improvements.\n1.0.0 (2017-09-18): Initial release.\n"}}} \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..7337d50 --- /dev/null +++ b/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +gitbook build . book +cd book +rm .gitignore .nojekyll cover.pdn cover_3d.png cover_cn.pdn cover_lulu.png isbn_barcode.pdf build.sh +cd .. diff --git a/chapters/add-external-packages/README.md b/chapters/add-external-packages/README.md index 72a6d49..cde3bb8 100644 --- a/chapters/add-external-packages/README.md +++ b/chapters/add-external-packages/README.md @@ -1,3 +1,62 @@ +# 添加外来软件包 + +选择诸如 .NET 这种成熟的生态系统,其最大的优势之一,就是第三方软件包和插件的量非常庞大。正如其它的软件包系统一样,你可以下载并安装 .NET 软件包,以获取协助,来完成几乎任何能想到的任务和难题。 + +NuGet 即是包管理工具,也是官方的软件包仓库(位于 [https://www.nuget.org](https://www.nuget.org))。你可以在网页上检索 NuGet 软件包,并在自己的机器上使用终端(或者 Visual Studio 里的图形界面)安装它们。 + +## 安装软件包 Humanizer + +上一章结尾处,待办事项 程序展示的 待办事项条目 看起来是这样的: + +![Dates in ISO 8601 format](iso8601.png) + +“截止日期”一栏所展示的日期,这种格式(叫做 ISO 8601)对机器来说很方便,但是人类看着就不爽了。如果看到的是“还剩 X 天”这样,不是更好吗? + +你完全可以自己写一段代码,把一个日期转换成更人性化的字符串,不过幸运的是,还有个更便捷的方法。 + +NuGet 上的软件包 Humanizer (https://www.nuget.org/packages/Humanizer) 解决了这种问题,它提供的方法可以“人性化(humanize)” 或者说 改写 几乎任何东西:日期、时间、时长、数字等等。它是个很好很有用的开源项目,根据 MIT 许可证发布。 + +要把它加入到你的项目里,在终端窗口运行这个命令: + +``` +dotnet add package Humanizer +``` + +如果你浏览项目文件 `AspNetCoreTodo.csproj`,会看到新增了一行 `PackageReference`,引用了 `Humanizer`。 + +## 在视图中使用 Humanizer + +要在代码里使用一个软件包,你通常需要在文件顶端添加一个 `using` 语句,以导入该软件包的内容。 + +既然 Humanizer 将用于在视图中改写日期,你可以直接在视图里使用它。首先在视图顶端添加一个 `@using` 语句: + +**`Views/Todo/Index.cshtml`** + +```html +@model TodoViewModel +@using Humanizer + +// ... +``` + +然后,修改那行写着 `DueAt` 方法的代码,使用 Humanizer 里的 `Humanize` 方法: + +```html +@item.DueAt.Humanize() +``` + +现在,日期的可读性大大提高了: + +![Human-readable dates](friendly-dates.png) + +NuGet 上有着大量的软件包,从 XML解析 到 机器学习 到 Twitter发帖,包罗万象。ASP.NET Core 自身,在表象之下,也只不过是添加到你项目里的一个 NuGet 软件包集合。 + +> 使用 `dotnet new mvc` 创建的项目文件包含一条指向`Microsoft.AspNetCore.All`软件包的引用,这是个便捷的“元软件包(metapackage)”,它引用了你在项目中所需的所有其它 ASP.NET Core 软件包。这样,你就不必在项目文件里添加数百个软件包的引用了。 + +下一章里,你将使用另一套 NuGet 软件包(一个叫 Entity Framework Core 的系统),编写代码与数据库进行交互。 + +--- + # Add external packages One of the big advantages of using a mature ecosystem like .NET is that the number of third-party packages and plugins is huge. Just like other package systems, you can download and install .NET packages that help with almost any task or problem you can imagine. diff --git a/chapters/add-more-features/README.md b/chapters/add-more-features/README.md index 9da483b..c4f82e8 100644 --- a/chapters/add-more-features/README.md +++ b/chapters/add-more-features/README.md @@ -1,2 +1,8 @@ +# 添加新特性 + +现在,你借助 Entity Framework Core 连接到了数据库,就为“给程序添加更多新特性”做好准备了。首先是这个功能:使用一个表单,添加新的待办事项条目。 + +--- + # Add more features Now that you've connected to a database using Entity Framework Core, you're ready to add some more features to the application. First, you'll make it possible to add new to-do items using a form. diff --git a/chapters/add-more-features/add-todo-items.md b/chapters/add-more-features/add-todo-items.md index ee906cc..7760c9b 100644 --- a/chapters/add-more-features/add-todo-items.md +++ b/chapters/add-more-features/add-todo-items.md @@ -1,3 +1,166 @@ +## 添加 待办事项 条目 + +使用列表下面那个简易的表单,用户可以添加新的 待办事项 条目: + +![Final form](final-form.png) + +添加这个功能,需要几个步骤: + +* 在视图里添加一个 表单 +* 在控制器里添加一个新的 action 处理这个表单 +* 在服务层添加代码,对数据库进行修改 + +### 添加一个表单 + +视图 `Todo/Index.cshtml` 里有个占位符,代表 Add Item form: + +```html + +``` + +为保持各部分独立且组织良好,你应该以 **局部视图(partial view)** 的形式创建这个表单。局部视图是较大视图的一个小片段,存放于一个独立的文件。 + +创建一个 `AddItemPartial.cshtml` 视图: + +**Views/Todo/AddItemPartial.cshtml** + +```html +@model TodoItem + +
                                                                    + + + +
                                                                    +``` + +`asp-action` 这个 tag helper 会为该表单生成一个 URL,就像你将其应用在一个 `` 元素上那样。在本例中,`asp-action` 会被你创建的 `AddItem` 的真实地址取代: + +```html +
                                                                    +``` + +在 `` 元素里,添加一个 `asp-` tag helper 的同时会在表单里添加一个隐藏字段,其中包含一个验证标记。该验证标记可用于防止 跨站请求伪造(cross-site request forgery -- CSRF) 攻击。在你编写这个 action 的时候,会验证这个标记。 + +局部视图就这样创建好了。然后,要在 Todo 主视图里引用它: + +**Views/Todo/Index.cshtml** + +```html + +``` + +### 添加 action + +当某个用户在你刚刚创建的表单里点击 Add,其浏览器会构建一个 POST 请求到你应用程序的 `/Todo/AddItem`。眼下这不会有效果,因为还没有任何 action 会处理 `/Todo/AddItem` 这个路由。如果你现在去尝试,ASP.NET Core 会返回一个 `404 Not Found` 错误。 + +你需要在 `TodoConteoller` 中添加一个名为 `AddItem` 的新 action: + +```csharp +[ValidateAntiForgeryToken] +public async Task AddItem(TodoItem newItem) +{ + if (!ModelState.IsValid) + { + return RedirectToAction("Index"); + } + + var successful = await _todoItemService.AddItemAsync(newItem); + if (!successful) + { + return BadRequest("Could not add item."); + } + + return RedirectToAction("Index"); +} +``` + +注意到 `AddItem` action 接受一个 `TodoItem` 参数的方式了吗?这是你在 _MVC basics_ 章节中创建的那个,用于存储一个 待办事项条目 相关信息的 `TodoItem` 模型。当它在这里作为一个 action 参数使用, ASP.NET Core 会自动执行一个称为 **模型绑定** 的处理流程。 + +模型绑定流程会查看请求内的数据,并试图智能地把输入的字段和模型里的属性匹配起来。换句话说,当用户提交这个表单,并且浏览器 POST 到了此 action,ASP.NET Core 会从表单里提取信息,并存放到那个 `newItem` 变量里。 + +位于 action 前面的 `[ValidateAntiForgeryToken]` 属性告知 ASP.NET Core 去查找(并验证)那个隐藏的验证标记,就是由 `asp-action` tag helper 添加到表单里的那个标记。在处理 跨站请求伪造(CSRF) 的时候,这是个重要的安全措施,你的用户可能被欺骗,以至于在一个恶意的网站上提交数据。这里的验证标记被用于确保呈现和提交表单的,是你的程序。 + +再检视一次 `AddItemPartial.cshtml` 视图。文件顶部的 `@model TodoItem` 那行告知 ASP.NET Core,该视图需要配合 `TodoItem` 模型一起使用。它促成了以下功能,在 `` 标签上,应用 `asp-for="Title"`,让 ASP.NET Core 知晓该 input 元素是为 `Title` 字段服务的。 + +由于 `@model` 这一行的存在,此局部视图在被渲染的时候,期望被传入一个 `TodoItem` 对象。经由 `Html.PartialAsync` 传给它一个 `new TodoItem`,以一个空条目初始化该表单。(请尝试添加`{ Title = "hello" }`,看看会发生什么!) + +在模型绑定流程中,模型里的任何属性,如果不能匹配到请求里的字段,都会被忽略掉。由于表单里仅包含一个 `Title` 元素,你能预见 `TodoItem` 上的其它属性(`IsDone` 标记,`DueAt` 日期)将为空,或者包含着一个默认值。 + +> 作为复用 `TodoItem` 模型的替代方案,还可以创建一个独立的模型(比如叫 `NewTodoItem`),仅用于这个 action 中,并仅具有特定的字段(Title),用于添加新的待办事项条目。模型绑定流程依然要用到,但现在,你分离了两个模型,一个用于在数据库中存储待办事项条目,另一个用于绑定传入的请求数据。这个方案,也被称作 **绑定模型(binding model)** 或者 **数据传输对象(data transfer object)**(DTO)。这个模式常见于更大更复杂的项目。 + +请求数据绑定到模型后,ASP.NET Core 还进行了 **模型核验操作(model validation)**。核验操作检查从传入请求绑定到模型的数据,鉴别其合理性和有效性。你可以在模型中添加属性,告知 ASP.NET Core 以怎样的方式进行核验。 + +`Title` 字段上的 `[Required]` 属性告知 ASP.NET Core 的模型核验器,如果标题缺失或为空,则判定其无效。看一下 action `AddItem` 的代码:首个代码块检查 `ModelState`(模型核验的结果)是否有效。习惯上,这种核验都在 action 最开始的地方进行。 + +```csharp +if (!ModelState.IsValid) +{ + return RedirectToAction("Index"); +} +``` + +如果 `ModelState` 出于某种原因无效,浏览器会被重定向到路由 `/Todo/Index`,后者会刷新页面。 + +接下来,控制器调用到服务层,进行实际的数据库操作,保存这个新的待办事项条目: + +```csharp +var successful = await _todoItemService.AddItemAsync(newItem); +if (!successful) +{ + return BadRequest(new { error = "Could not add item." }); +} +``` + +取决于该条目添加到数据库的结果成功与否,`AddItemAsync` 方法会返回 `true` 或者 `false`。如果该操作因为某些原因失败了,action 会连带一个包含 `error` 字段的对象,返回 `400 Bad Request`。 + +最终,如果操作顺利完成,action 会将浏览器重定向到路由 `/Todo/Index`,后者会刷新页面并向用户显示新的待办事项列表。 + +### 添加服务方法(函数) + +如果你使用的代码编辑器了解 C# 的语法,你会在 `AddItemAsync` 下面看到红色的波浪线,因为该方法尚未定义。 + +作为最后一步,你需要在服务层里添加一个方法。首先,在 `ITodoItemService` 接口里添加它的定义: + +```csharp +public interface ITodoItemService +{ + Task GetIncompleteItemsAsync(); + + Task AddItemAsync(TodoItem newItem); +} +``` + +然后,在 `TodoItemService` 里面添加实现: + +```csharp +public async Task AddItemAsync(TodoItem newItem) +{ + newItem.Id = Guid.NewGuid(); + newItem.IsDone = false; + newItem.DueAt = DateTimeOffset.Now.AddDays(3); + + _context.Items.Add(newItem); + + var saveResult = await _context.SaveChangesAsync(); + return saveResult == 1; +} +``` + +字段 `newItem.Title` 已经由 ASP.NET Core 的模型绑定器设置,所以,这个方法仅需要分配 ID 并为其它字段设置缺省值。然后,这个新条目被加入到数据库上下文中。在调用 `SaveChangesAsync()` 前它尚未被保存。如果保存操作成功,`SaveChangesAsync()` 会返回 1。 + +### 试试看 + +运行程序,使用页面上的表单添加几个条目到 待办事项 列表里。因为这些条目存储在数据库里,就算你关闭程序后再重新运行,这些条目都还保存在那里。 + +> 作为附加练习,请尝试使用 HTML 和 JavaScript 添加一个日期选择框,并让用户为 `DueAt` 属性选择一个(可选的)日期。然后,用这个日期替换那个默认的“3天后到期”。 + +--- + ## Add new to-do items The user will add new to-do items with a simple form below the list: diff --git a/chapters/add-more-features/complete-with-checkbox.md b/chapters/add-more-features/complete-with-checkbox.md index b4e9c8e..2601848 100644 --- a/chapters/add-more-features/complete-with-checkbox.md +++ b/chapters/add-more-features/complete-with-checkbox.md @@ -1,3 +1,157 @@ +## 使用复选框标记条目完成 + +向 待办事项 列表里添加条目,这功能很棒,但无论如何,这些事项都得被处理掉。在 `Views/Todo/Index.cshtml` 视图里,为每个待办事项条目显示了一个复选框: + +```html + +``` + +点击这个复选框(还)不会导致任何结果。像上一章节一样,你要通过表单和 action 添加这一功能。在本例中,你还要写一丁点 JavaScript 代码。 + +### 向视图添加表单元素 + +首先,修改视图,并用让每个复选框都被一个 `` 元素包含。然后,添加一个隐藏元素,其中包含条目的 ID: + +**Views/Todo/Index.cshtml** + +```html + + + + + + +``` + +当视图中的 `foreach` 循环运行并为每个待办事项条目显示一行,每一行都会包含此表单的一个副本。隐藏的输入框包含该 待办事项条目 的 ID,以便你的控制器代码辨别是哪个复选框被选中了。(如果没有它,你只能知道 *某个* 复选框被选中了,而无法知道是哪个。) + +如果你现在立刻运行你的程序,复选框还是没什么作用,因为没有提交按钮通知浏览器,让它根据表单数据构建一个 POST 请求。你可以在每个复选框下面添加一个提交按钮,但这样的用户体验太蠢了。理想的方法是,点击复选框的时候,能够自动地提交该表单。你可以添加一些 JavaScript 达成这一点。 + +### 添加 JavaScript 代码 + +到 `wwwroot/js` 目录找到文件 `site.js` ,并添加如下代码: + +**wwwroot/js/site.js** + +```javascript +$(document).ready(function() { + + // Wire up all of the checkboxes to run markCompleted() + $('.done-checkbox').on('click', function(e) { + markCompleted(e.target); + }); +}); + +function markCompleted(checkbox) { + checkbox.disabled = true; + + var row = checkbox.closest('tr'); + $(row).addClass('done'); + + var form = checkbox.closest('form'); + form.submit(); +} +``` + +这段代码先使用 jQuery(一个 JavaScript 辅助库),通过 CSS 类 `done-checkbox` 找出页面上的所有复选框,将一些代码关联到其 `click` 事件。当一个复选框被点击,`markCompleted()` 函数就被执行。 + +`markCompleted()` 函数的功能如下: + +* 添加 `disabled` 属性到该复选框,避免它再次被点击 +* 为包含该复选框的行添加 `done` CSS 类,这个类会基于 `style.css` 中的 CSS 规则,改变该行的外观 +* 提交该表单 + +视图和前端代码就这样搞定了。是时候添加一个新 action 了! + +### 在控制器里添加 action + +正如你可能已经猜到的那样,你需要在 `TodoController` 里添加一个 action `MarkDone`: + +```csharp +[ValidateAntiForgeryToken] +public async Task MarkDone(Guid id) +{ + if (id == Guid.Empty) + { + return RedirectToAction("Index"); + } + + var successful = await _todoItemService.MarkDoneAsync(id); + if (!successful) + { + return BadRequest("Could not mark item as done."); + } + + return RedirectToAction("Index"); +} +``` + +让我们逐行分析这个 action 方法。首先,该方法接受一个名为 `id` 的 `Guid` 类型参数。参数 `id` 非常简单,这跟 `AddItem` 不同,那个 action 用了一个模型作为参数,还进行了 模型绑定/核验 的处理。如果传入的请求中包括一个名为 `id` 的参数, ASP.NET Core 会尝试将其解析为一个 guid。这项功能得益于你在表单里加入的那个名为 `id` 的隐藏元素。 + +既然你没使用 模型绑定流程,就没有用于有效性检查的 `ModelState`。取而代之,你可以直接检查 guid 的值,以判断它的有效性。如果出于某些原因,请求中的 `id` 参数缺失了,或者无法解析为一个 guid,则 `id` 的值将是 `GUID.Empty`。如果这种情况发生,action 就让浏览器重定向到 `/Todo/Index` 并刷新页面。 + +接下来,控制器需要调用服务层去修改数据库。这个功能,将要由 `ITodoItemService` 接口中的一个新方法 `MarkDoneAsync` 来实现,它会根据操作成功与否,返回 true 或者 false: + +```csharp +var successful = await _todoItemService.MarkDoneAsync(id); +if (!successful) +{ + return BadRequest("Could not mark item as done."); +} +``` + +最终,如果一切顺利,浏览器会被重定向到 `/Todo/Index`,并刷新页面。 + +修改过视图和控制器,剩下的就是要添加缺失的服务方法了。 + +### 添加服务方法 + +首先,在接口定义中添加 `MarkDoneAsync`: + +**Services/ITodoItemService.cs** + +```csharp +Task MarkDoneAsync(Guid id); +``` + +然后,在 `TodoItemService` 中添加具体的实现: + +**Services/TodoItemService.cs** + +```csharp +public async Task MarkDoneAsync(Guid id) +{ + var item = await _context.Items + .Where(x => x.Id == id) + .SingleOrDefaultAsync(); + + if (item == null) return false; + + item.IsDone = true; + + var saveResult = await _context.SaveChangesAsync(); + return saveResult == 1; // One entity should have been updated +} +``` + +该方法使用 Entity Framework Core 和 `Where()` 在数据库中按 ID 查找一个条目。`SingleOrDefaultAsync()` 方法要么返回该条目(若存在),要么返回 `null`——如果找不到。 + +一旦你确定 `item` 不是 null,设置 `IsDone` 属性就是小事一桩了: + +```csharp +item.IsDone = true; +``` + +修改该字段仅仅影响该条目的本地拷贝,`SaveChangesAsync()` 被调用之后才会把修改的内容持久化到数据库里。`SaveChangesAsync()` 返回一个整数,表示在这次保存操作中被更新的条目的数量。在当前的情况下,它要么是1(条目更新了),要么是0(有错误发生)。 + +### 试试看 + +运行程序并勾选列表中的某些条目完成掉。刷新页面,它们将自动消失掉,这归功于 `GetIncompleteItemsAsync()` 方法中的 `Where()` 过滤器。 + +现在,程序里包含一个单一、共享的待办事项列表。如果它为每个用户保存独立的列表,将会更有用。下一章,你将使用 ASP.NET Core Identity,为项目添加安全及认证等特性。 + +--- + ## Complete items with a checkbox Adding items to your to-do list is great, but eventually you'll need to get things done, too. In the `Views/Todo/Index.cshtml` view, a checkbox is rendered for each to-do item: diff --git a/chapters/automated-testing/README.md b/chapters/automated-testing/README.md index 2864e0f..11a1b58 100644 --- a/chapters/automated-testing/README.md +++ b/chapters/automated-testing/README.md @@ -1,3 +1,11 @@ +# 自动化测试 + +测试的编写在构建任何程序时都很重要。测试代码有助于发现及避免 bug,并使你后续重构代码的工作轻松些,以免破坏现有功能或引入新的问题。 + +在本章里,你将学习如何编写 **单元测试** 和 **集成测试** 以检验你的 ASP.NET Core 程序。单元测试较小,用来确保单个方法或者逻辑块工作良好。集成测试(有时候也叫 **功能性** 测试)较大,模拟实际的应用场景,并检验你程序里的多个层次或组件。 + +--- + # Automated testing Writing tests is an important part of building any application. Testing your code helps you find and avoid bugs, and makes it easier to refactor your code later without breaking functionality or introducing new problems. diff --git a/chapters/automated-testing/integration-testing.md b/chapters/automated-testing/integration-testing.md index 11297ea..07b9574 100644 --- a/chapters/automated-testing/integration-testing.md +++ b/chapters/automated-testing/integration-testing.md @@ -1,3 +1,177 @@ +## 集成测试 + +与单元测试相比,集成测试在范围上大得多。它检验整个程序栈。集成测试并不会把一个类或组件隔离出来,而是确保你程序的所有组件协作良好,这些组件包括:路由、控制器、服务、数据库访问等等。 + +与单元测试相比,集成测试较慢,并且涵盖的范围较大,所以,一般来说,一个项目会有大量的单元测试内容,而集成测试的内容则屈指可数。 + +为了测试整个程序栈(包括控制器路由),集成测试往往像网络浏览器那样向程序发起 HTTP 请求。 + +要执行一个集成测试,你也可以启动程序,并手动向`http://localhost:5000`发起请求。不过,ASP.NET Core 提供了一个上佳的替代品:`TestServer` 类。这个类能够在测试期间托管你的程序,并在测试完成之后自动关闭它。 + +### 创建一个测试项目 + +如果你此刻位于项目目录,`cd` 到上一层的 `AspNetCoreTodo` 目录,使用以下命令搭建一个新项目: + +``` +dotnet new xunit -o AspNetCoreTodo.IntegrationTests +``` + +你现在的目录结构看起来应该是这样: + +``` +AspNetCoreTodo/ + AspNetCoreTodo/ + AspNetCoreTodo.csproj + Controllers/ + (etc...) + + AspNetCoreTodo.UnitTests/ + AspNetCoreTodo.UnitTests.csproj + + AspNetCoreTodo.IntegrationTests/ + AspNetCoreTodo.IntegrationTests.csproj +``` + +> 如果你愿意,可以把单元测试和集成测试放置在同一个项目里。对大型项目而言,通常会把它们分开,以便于它们各自独立运行。 + +既然这个测试项目要用到主项目中的类,你需要添加一个引用指向主项目: + +``` +dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj +``` + +还需要添加 NuGet 包 `Microsoft.AspNetCore.TestHost`: + +``` +dotnet add package Microsoft.AspNetCore.TestHost +``` + +删除 `dotnet new` 默认创建的文件 `UnitTest1.cs`,这样你就为集成测试的编写准备就绪了。 + +### 编写集成测试 + +在每次集成测试执行之前,需要进行一些配置。为免配置相关的代码把测试代码弄的乱七八糟,你可以把配置相关的内容提取到一个独立的类里。创建一个名为 `TestFixture` 的类: + +**AspNetCoreTodo.IntegrationTests/TestFixture.cs** + +```csharp +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; + +namespace AspNetCoreTodo.IntegrationTests +{ + public class TestFixture : IDisposable + { + private readonly TestServer _server; + + public HttpClient Client { get; } + + public TestFixture() + { + var builder = new WebHostBuilder() + .UseStartup() + .ConfigureAppConfiguration((context, config) => + { + config.SetBasePath(Path.Combine( + Directory.GetCurrentDirectory(), + "..\\..\\..\\..\\AspNetCoreTodo")); + + config.AddJsonFile("appsettings.json"); + }); + + _server = new TestServer(builder); + + Client = _server.CreateClient(); + Client.BaseAddress = new Uri("http://localhost:8888"); + } + + public void Dispose() + { + Client.Dispose(); + _server.Dispose(); + } + } +} +``` + +这个类配置好了一个 `TestServer`,并使测试代码干净利索。 + +现在你(真的)可以开始编写集成测试了。创建一个名为 `TodoRouteShould` 的类: + +**AspNetCoreTodo.IntegrationTests/TodoRouteShould.cs** + +```csharp +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Xunit; + +namespace AspNetCoreTodo.IntegrationTests +{ + public class TodoRouteShould : IClassFixture + { + private readonly HttpClient _client; + + public TodoRouteShould(TestFixture fixture) + { + _client = fixture.Client; + } + + [Fact] + public async Task ChallengeAnonymousUser() + { + // Arrange + var request = new HttpRequestMessage( + HttpMethod.Get, "/todo"); + + // Act: request the /todo route + var response = await _client.SendAsync(request); + + // Assert: the user is sent to the login page + Assert.Equal( + HttpStatusCode.Redirect, + response.StatusCode); + + Assert.Equal( + "http://localhost:8888/Account" + + "/Login?ReturnUrl=%2Ftodo", + response.Headers.Location.ToString()); + } + } +} +``` + +这个测试发起一个匿名(未登录)的请求到路径 `/todo`,并验证浏览器被重定向到了登录页面。 + +这是个很适合集成测试的使用场景,因为它涵盖了程序的多个组件:路由系统、控制器、控制器被标记了 `[Authorize]` 等等。这是个良好的测试点,因为它确保你不会意外地弄丢了 `[Authorize]` 属性,从而导致待办事项视图对所有人可见。 + +在终端窗口运行 `dotnet test`,如果一切工作顺利,你会看到这样的成功信息: + +``` +Starting test execution, please wait... + Discovering: AspNetCoreTodo.IntegrationTests + Discovered: AspNetCoreTodo.IntegrationTests + Starting: AspNetCoreTodo.IntegrationTests + Finished: AspNetCoreTodo.IntegrationTests + +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. +Test Run Successful. +Test execution time: 2.0588 Seconds +``` + +## 本章总结 + +测试是个宽泛的话题,还有很多东西需要学习。本章节没有涉及 UI 测试,也没有对前端(JavaScript)代码进行测试——它本身可能就需要一整本书去讲述。不过,你应该已经掌握了一些基本的技能和知识,可用于实践并学习更多相关测试程序的编写。 + +像以往一样,ASP.NET Core 文档(https://docs.asp.net)和 StackOverflow 都是用于了解更多知识以及遇到问题时查找答案的好资源。 + +--- + ## Integration testing Compared to unit tests, integration tests are much larger in scope. exercise the whole application stack. Instead of isolating one class or method, integration tests ensure that all of the components of your application are working together properly: routing, controllers, services, database code, and so on. diff --git a/chapters/automated-testing/unit-testing.md b/chapters/automated-testing/unit-testing.md index 2521f44..fbe20b2 100644 --- a/chapters/automated-testing/unit-testing.md +++ b/chapters/automated-testing/unit-testing.md @@ -1,3 +1,193 @@ +## 单元测试 + +单元测试是短小的测试,检查单个方法或类的行为。当你测试的代码依赖其它方法或类时,单元测试依赖于 **虚构(mocking)** 出来的其它类,以便在一个时时刻专注在一个点上。 + +例如,`TodoController` 有两个依赖: `ITodoItemService` 和 `UserManager`。`TodoItemService` 接下来又依赖于 `ApplicationDbContext`。(你可以画一条线表示 `TodoController` > `TodoItemService` > `ApplicationDbContext`,这种方式被称为 **依赖图**)。 + +当程序运转正常的时候, ASP.NET Core 的服务容器和依赖注入系统在 `TodoController` 或者 `TodoItemService` 被创建时,把这些对象逐一地注入到依赖图里。 + +另一方面,当你写单元测试的时候,你需要自己处理这个依赖图。典刑的做法是,提供这些依赖的 虚构 或者 测试专用 版本。这意味着你可以把正在测试的类或者方法的逻辑隔离出来。(这很重要!如果你在测试一个服务,显然不应该一失手 **顺带** 写到数据库里去。) + +### 创建一个测试项目 + +为测试创建独立的项目是一个良好的实践,以便把它们和你的程序代码分离开。新的测试项目应该被置于你主项目的同级目录(而非在主项目目录内)。 + +如果你当前在你项目目录里,向上 `cd` 一层。(这个目录也叫做 `AspNetCoreTodo`)。然后使用以下命令搭建出一个新的测试项目: + +``` +dotnet new xunit -o AspNetCoreTodo.UnitTests +``` + +xUnit.NET 是一个常用的针对 .NET 代码的测试框架,可用于编写单元和集成测试。像其它组件一样,它也是一组NuGet 包,可被安装在任意项目中 。`dotnet new xunit` 已经包括了你所需的一切。 + +你的目录结构看起来应该是这样: + +``` +AspNetCoreTodo/ + AspNetCoreTodo/ + AspNetCoreTodo.csproj + Controllers/ + (etc...) + + AspNetCoreTodo.UnitTests/ + AspNetCoreTodo.UnitTests.csproj +``` + +既然测试项目要使用你主项目中的类,你需要添加一个引用指向主项目: + +``` +dotnet add reference ../AspNetCoreTodo/AspNetCoreTodo.csproj +``` + +删除自动创建的文件 `UnitTest1.cs`。你已经为第一个测试的编写准备就绪了。 + +> 如果你用的是 Visual Studio Code,你可能需要关闭并重新打开 Visual Studio Code 窗口,以便代码完成功能在新项目里生效。 + +### 写一个服务测试 + +看一下 `TodoItemService` 里面的 `AddItemAsync()` 方法: + +```csharp +public async Task AddItemAsync( + TodoItem newItem, ApplicationUser user) +{ + newItem.Id = Guid.NewGuid(); + newItem.IsDone = false; + newItem.DueAt = DateTimeOffset.Now.AddDays(3); + newItem.UserId = user.Id; + + _context.Items.Add(newItem); + + var saveResult = await _context.SaveChangesAsync(); + return saveResult == 1; +} +``` + +该方法在把新条目真正存入数据库之前,做了多个判断与假设(换句话说,在新条目上执行了业务逻辑): + +* `UserId` 属性应该被设置为用户的 ID +* 新条目应该总是未完成状态(`IsDone = false`) +* 新条目的标题应该复制自 `newItem.Title` +* 新条目应该总是从现在开始3天后过期 + +设想一下,如果你或者其他什么人重构了这个 `AddItemAsync()` 方法,并遗漏了某些以上的业务逻辑。你程序的行为,会在你意识不到的情况下变掉!你有办法避免这个情况,方法是编写一个测试,用以复核这些业务逻辑并未发生变化(就算是该方法的内部实现已经发生了变化)。 + +> 这种情形——你意识不到自己改变了业务逻辑,虽然现在看起来好像不会发生,但是在一个更大更复杂的项目中,这会因为各种决策和假设而变得难以追踪。在越大的项目中,确保业务逻辑稳定的自动化检查就越重要。 + +要编写一个单元测试来检验 `TodoItemService` 中的逻辑,在你的测试项目中创建一个新类: + +**AspNetCoreTodo.UnitTests/TodoItemServiceShould.cs** + +```csharp +using System; +using System.Threading.Tasks; +using AspNetCoreTodo.Data; +using AspNetCoreTodo.Models; +using AspNetCoreTodo.Services; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace AspNetCoreTodo.UnitTests +{ + public class TodoItemServiceShould + { + [Fact] + public async Task AddNewItemAsIncompleteWithDueDate() + { + // ... + } + } +} +``` + +> 有很多不同的方法可以命名和组织测试,它们都有着各自的优缺点。我喜欢给测试类加上 `Should` 前缀,使方法名构成一个可读性良好的句子,不过你可以按自己的意愿选择命名风格。 + +`[Fact]` 属性是 xUnit.NET 包里带来的,它把这个方法标记为一个测试方法。 + +`TodoItemService` 需要一个 `ApplicationDbContext`,后者通常连接到你的开发或生产环境里的数据库。你不该把这些数据库用于测试。相反,你可以在测试代码里使用 Entity Framework Core 的内存数据库 provider。因为整个数据库都存在于内存里,每次测试重新开始的时候,他就会被清空。并且,因为这是个合乎规格的 Entity Framework Core 的 provider,`TodoItemService` 不会察觉有什么异样。 + +用一个 `DbContextOptionsBuilder` 来配置内存数据库的 provider,然后对 `AddItemAsync()` 发起一个调用: + +```csharp +var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: "Test_AddNewItem").Options; + +// Set up a context (connection to the "DB") for writing +using (var context = new ApplicationDbContext(options)) +{ + var service = new TodoItemService(context); + + var fakeUser = new ApplicationUser + { + Id = "fake-000", + UserName = "fake@example.com" + }; + + await service.AddItemAsync(new TodoItem + { + Title = "Testing?" + }, fakeUser); +} +``` + +最后一行创建了一个新的名为 `Testing?` 的待办事项,并通知服务将其存储到(内存)数据库里。 + +为验证业务逻辑执行的正确性,请在原有的 `using` 代码块下编写新内容: + +```csharp +// Use a separate context to read data back from the "DB" +using (var context = new ApplicationDbContext(options)) +{ + var itemsInDatabase = await context + .Items.CountAsync(); + Assert.Equal(1, itemsInDatabase); + + var item = await context.Items.FirstAsync(); + Assert.Equal("Testing?", item.Title); + Assert.Equal(false, item.IsDone); + + // Item should be due 3 days from now (give or take a second) + var difference = DateTimeOffset.Now.AddDays(3) - item.DueAt; + Assert.True(difference < TimeSpan.FromSeconds(1)); +} +``` + +第一个验证步骤是个明智的检查:内存数据库里保存的条目绝不会超过一条。假设这个检查通过了,测试会使用 `FirstAsync` 方法取出存储的条目,然后断言其中的属性被设置了预期的值。 + +> 不论是单元测试还是集成测试,都遵循 AAA(布置-执行-断言——Arrange-Act-Assert)模式:对象和数据首先被建立出来,然后执行一些动作,最后测试程序检查(断言)预期表现的存在。 + +断言一个日期时间值有点棘手,因为比较两个日期值的时候,就算是只有毫秒部分不同,两个值也是不等的。替代方案是,检查 `DueAt` 的值距离期望值小于一秒。 + +### 运行测试 + +在终端窗口,运行以下命令(请确保你位于 `AspNetCoreTodo.UnitTests` 目录): + +``` +dotnet test +``` + +`test` 命令在当前的项目里查找测试方法(本例中,由 `[Fact]` 属性标记出来),然后运行它找到的所有测试,你会看到类似这样的输出: + +``` +Starting test execution, please wait... + Discovering: AspNetCoreTodo.UnitTests + Discovered: AspNetCoreTodo.UnitTests + Starting: AspNetCoreTodo.UnitTests + Finished: AspNetCoreTodo.UnitTests + +Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. +Test Run Successful. +Test execution time: 1.9074 Seconds +``` + +你现在有了测试程序,覆盖了 `TodoItemService` 的测试范围。作为一个补充练习,请写出单元测试以确保: + +* 如果传入一个不存在的 ID, `MarkDoneAsync()` 返回 false +* 当一个有效的条目被标记为完成状态, `MarkDoneAsync()` 返回 true +* `GetIncompleteItemsAsync()` 只返回某个特定用户的条目 + +--- + ## Unit testing Unit tests are small, short tests that check the behavior of a single method or class. When the code you're testing relies on other methods or classes, unit tests rely on **mocking** those other classes so that the test only focuses on one thing at a time. diff --git a/chapters/conclusion/README.md b/chapters/conclusion/README.md index 8ca7faa..c5376e1 100644 --- a/chapters/conclusion/README.md +++ b/chapters/conclusion/README.md @@ -1,3 +1,70 @@ +# 结束语 + +感谢你读完了这本简明 ASP.NET Core 手册!如果这本书有点(或者没有)用处,我很乐于倾听您的想法。请在 Twitter 上发表看法:https://twitter.com/nbarbettini + +## 更深入的学习 + + ASP.NET Core 还有很多功能,但是无法纳入到这本小册子里,包括: + +* 构建 RESTFul 的 API 和 微服务 +* 把 ASP.NET Core 用于 单页面应用,例如 Angular 和 React +* Razor 页面 +* 打包和压缩静态资源 +* WebSockets 和 SignalR + +如果要深入学习,以下这些方式可供参考: + +* **ASP.NET Core 文档** 官方的 ASP.NET Core 文档位于 https://docs.asp.net,其中包含了一些有关这些主题的,深入详尽的教程。本人强烈推荐。 + +* **LinkedIn Learning 和 Pluralsight 上的教程** 如果你更喜欢通过视频学习,在 Pluralsight 和 LinkedIn Learning 上就有很多非常精彩(其中某些就是来自于你们读者)。如果你在上面没有账号或者想要一张优惠券,请发信到:nate@barbettini.com。 + +* **Nate's 博客** 我在自己的博客 https://www.recaffeinate.co 上有也写一些有关 ASP.NET Core 和其它主题的博文。 + +祝你代码敲得愉快! + +## 关于作者 + +嗨,我是 Nate!我在一个漫长的灌着咖啡的周末写了这本 简明 ASP.NET Core 手册,因为我热爱 .NET 社区,并希望以我的微薄之力付出回报。希望它帮助你学了一点儿新东西。 + +你可以在 Twitter([@nbarbettini](https://twitter.com/nbarbettini))上和我保持联系,或者在我的博客上(https://www.recaffeinate.co)。你还可以通过电子邮件(nate@barbettini.com)联系我。 + +## 特别致谢 + +Jennifer,她总是支持我各种疯狂的点子。 + +以下这些贡献者,提升了这本书的质量: + +* 0xNF +* Matt Welke [welkie] +* Raman Zhylich [zhilich] + +以下这些很棒的各国程序员,翻译了本书: + +* sahinyanlik (土耳其语) +* windsting、yuyi (简体中文) + +## 变更记录 + +需要完整、详尽的变更记录,可以到: + +https://github.com/nbarbettini/little-aspnetcore-book/releases + +**1.1.1** (2018-06-11): 修正了读者们发现的一些笔误。 + +**1.1.0** (2018-05-03): 大幅度重写了 *添加新特性* 一章,深入地使用了整个 MVC 框架并移除了 AJAX 模式。移除 Facebook 登录以简化安全章节、流水线式的测试和部署。修改了 Docker 指令以反映最新的优秀实践。修正了笔误,添加了来自读者的建议。还弄了个新改良的封面得瑟了一下! + +**1.0.4** (2018-01-15): 为服务容器(service container)的生命周期添加说明,阐释服务端口和 -o 选项,移除 Razor 指令后的分号。修正中文版译者信息。修正其它笔误和读者反馈的问题。 + +**1.0.3** (2017-11-13): 笔误修正和一些读者建议的改进。 + +**1.0.2** (2017-10-20): 更多的Bug修正和一些小改进。添加译版的链接。 + +**1.0.1** (2017-09-23): Bug修正和一些小改进。 + +**1.0.0** (2017-09-18): 初次发布。 + +--- + # Conclusion Thanks for making it to the end of the Little ASP.NET Core Book! If this book was helpful (or not), I'd love to hear your thoughts. Send me your comments via Twitter: https://twitter.com/nbarbettini diff --git a/chapters/deploy-the-application/README.md b/chapters/deploy-the-application/README.md index 1a724a0..dc5f99c 100644 --- a/chapters/deploy-the-application/README.md +++ b/chapters/deploy-the-application/README.md @@ -1,3 +1,33 @@ +# 部署程序 + +万事俱备,只欠东风。当一个良好的程序构建完成,就应该与全世界分享它了。 + +因为 ASP.NET Core 程序能够运行在 Windows、Mac 以及 Linux 上,你拥有多种部署程序的方式。这一章里,我将教给你最常用(也是最简单)的上线方式。 + +## 部署方式 + +ASP.NET Core 通常会部署到下列环境之一: + +* **一部 Dockers 主机** 任何有能力托管 Docker 容器的机器都能用来托管 ASP.NET Core 程序。创建 Docker 镜像是个非常快捷的部署程序的方式,尤其是在你熟悉 Docker 的情况下。(如果你还不熟悉,别担心!我会在后面逐步介绍。) + +* **Azure** 微软的 Azure 对 ASP.NET Core 程序提供原生的支持。如果你有一个 Azure 订阅,你只要创建一个 Web App 并上传你的项目文件即可。下一节,我会介绍通过 Azure CLI 完成这种操作。 + +* **Linux (连同 Nginx)** 如果你不想用 Docker 那个方式,依然可以在任意 Linux 服务器(这包括亚马逊的 EC2 和 DigitalOcean 虚拟机)上托管程序。通常把 ASP.NET Core 跟 Nginx 反向代理配对工作。(下面有更详细的 Nginx 相关内容。) + +* **Winddows** 你可以在 Windows 上使用 IIS 网络服务器托管 ASP.NET Core 程序。一般来说,部署到 Azure 更容易(也更便宜),不过你要是愿意自己管理 Windows 服务器,这也是个可行的方案。 + +## Kestrel 和 反向代理 + +> 如果你不在意 ASP.NET Core 程序托管工作的细节,而只希望参考分步的指导,可以跳转到后续两小节的任一个继续阅读。 + +ASP.NET Core 里包含一个名为 Kestrel 的快速轻量级的 web 开发服务器。你每次运行 `dotnet run` 并浏览 `http://localhost:5000` 的时候,用的就是这个服务器。当你把程序部署到生产环境的时候,它仍会在幕后使用 Kestrel。但强烈建议你在 Kestrel 之前添加一个反向代理,因为 Kestrel 并不具有负载均衡和其它更成熟的 Web 服务器所具有的其它特性。 + +在 Linux(和 Docker 容器)里,你可以用 Nginx 或者 Apache web 服务器接收从互联网上传入的请求,并派发到你用 Kestrel 托管的程序。如果你用的是 Windows,IIS 也能处理这个工作。 + +如果你把程序托管在 Azure,这些就都是自动为你处理的。在 Docker 那一节,我会讲述如何配置 Nginx 进行反向代理。 + +--- + # Deploy the application You've come a long way, but you're not quite done yet. Once you've created a great application, you need to share it with the world! diff --git a/chapters/deploy-the-application/deploy-to-azure.md b/chapters/deploy-the-application/deploy-to-azure.md index 96577ce..7a750cb 100644 --- a/chapters/deploy-the-application/deploy-to-azure.md +++ b/chapters/deploy-the-application/deploy-to-azure.md @@ -1,3 +1,110 @@ +## 部署到 Azure + +把你的 ASP.NET Core 程序部署到 Azure 只需要简单几步。你可以通过 Azure 的网上门户实施,也可以在 Azure CLI 命令行工具里实施。我会讲解后者。 + +### 准备材料 + +* Git(使用 `git --version` 命令确认它已经安装了) +* Azure CLI(按照 https://github.com/Azure/azure-cli 的指示进行安装) +* 一个 Azure 订阅(免费的订阅就可以了) +* 项目的根目录里要有一个部署配置文件 + +### 创建部署配置文件 + +因为你的目录结构里存在多个项目(Web项目和两个测试项目),Azure 并不知道该把哪个发布出去。为解决这个问题,在你的目录结构顶层创建一个名为 `.deployment` 的文件: + +**.deployment** + +```ini +[config] +project = AspNetCoreTodo/AspNetCoreTodo.csproj +``` + +确保你把这个文件保存为 `.deployment`,而不带有什么其它的零碎儿。(在 Windows 上,你可能需要把文件名用引号括起来,比如 `".deployment"`,以此避免被添加一个 `.txt` 扩展名。) + +如果你在顶层目录里执行 `ls` 或者 `dir` 命令,应该看到如下的内容: + +``` +.deployment +AspNetCoreTodo +AspNetCoreTodo.IntegrationTests +AspNetCoreTodo.UnitTests +``` + +### 设置 Azure 资源 + +如果你的 Azure CLI 才初次安装完成,运行: + +``` +az login +``` + +并按照提示在你的电脑上登录,然后,为这个程序创建一个新的 资源组(Resource Group): + +``` +az group create -l westus -n AspNetCoreTodoGroup +``` + +这个命令在美国西部(West US)地区创建了一个资源组。如果你距离美国西部很远,请使用 `az account list-locations` 命令获取一个地点列表,并找出距离你比较近的一个。 + +接下来,在你刚刚创建的组里,创建一个 App Service 方案: + +``` +az appservice plan create -g AspNetCoreTodoGroup -n AspNetCoreTodoPlan --sku F1 +``` + +> 提示:`F1` 是免费的 app 方案。如果想在你的应用上使用自己指定的域名,请使用 D1($10/月)或更高级的方案。 + +现在,在这个 App Service 方案里创建一个 Web 应用: + +``` +az webapp create -g AspNetCoreTodoGroup -p AspNetCoreTodoPlan -n MyTodoApp +``` + +这个应用的名称(上面的 `MyTodoApp`)在 Azure 上必须是全局唯一的。一旦这个应用创建好了,会具有一个以下格式的默认 URL:http://mytodoapp.azurewebsites.net + +### 把项目文件部署到 Azure + +你可以用 Git 把程序文件推送到 Azure 网络应用。如果你本地目录尚未作为一个 Git 仓库管理,执行下列命令进行设置: + +``` +git init +git add . +git commit -m "First commit!" +``` + +接下来,为部署工作创建一个 Azure 用户名和密码, + +``` +az webapp deployment user set --user-name nate +``` + +按提示创建密码。然后用 `config-local-git` 得到一个 Git URL: + +``` +az webapp deployment source config-local-git -g AspNetCoreTodoGroup -n MyTodoApp --out tsv + +https://nate@mytodoapp.scm.azurewebsites.net/MyTodoApp.git +``` + +复制这个 URL 到剪切板,并把它在本地仓库里添加为一个 Git remote: + +``` +git remote add azure <粘贴> +``` + +你只需要执行这些步骤一次。现在开始,任何时候,你需要推送程序文件到 Azure ,只需要在 Git 里提交它们,然后运行: + +``` +git push azure master +``` + +程序部署到 Azure 的时候,你会看到一系列的日志信息。 + +输出结束之后,浏览 http://yourappname.azurewebsites.net 以检验结果。 + +--- + ## Deploy to Azure Deploying your ASP.NET Core application to Azure only takes a few steps. You can do it through the Azure web portal, or on the command line using the Azure CLI. I'll cover the latter. diff --git a/chapters/deploy-the-application/deploy-with-docker.md b/chapters/deploy-the-application/deploy-with-docker.md index c1779d4..1c30f06 100644 --- a/chapters/deploy-the-application/deploy-with-docker.md +++ b/chapters/deploy-the-application/deploy-with-docker.md @@ -1,3 +1,192 @@ +## 使用 Docker 进行部署 + +如果你不使用 Azure 这样的平台,像 Docker 这样的容器化技术能极大地简化把 web 程序部署到你自己服务器上的工作。不再需要浪费时间在一个服务器上配置你程序所需的依赖、复制文件、重启进程,你只需要创建一个 Docker 镜像,里面包含你程序运行所需的一切,然后在任何 Docker 宿主机上作为容器启动起来就行了。 + +Docker 也便于把你的应用扩展为多个服务器。一旦你创建了一个镜像,用它来创建 1 个容器和 100 个容器所需要的工作是一样的。 + +开始之前,需要在你的开发机上安装 Docker CLI。搜索 "get docker for (mac/windows/linux)" 并执行 Docker 官网的提示内容。要检验是否安装成功,可以执行: + +``` +docker version +``` + +### 添加 Dockerfile + +首先需要的就是一个 Dockerfile,它就像个清单,告诉 Docker 你程序的构建和运行需要些什么。 + +在程序根目录,也就是最外层的 `AspNetCoreTodo` 文件夹里,创建一个名为 `Dockerfile`(没有扩展名)的文件。用你常用的编辑器打开它,输入下面这行: + +```dockerfile +FROM microsoft/dotnet:2.0-sdk AS build +``` + +这指示 Docker 以 `microsoft/dotnet:2.0-sdk` 为基础创建你的镜像。这个镜像是微软发布的,其中包含了执行 `dotnet build` 编译程序所需的工具和依赖。以这个预编译镜像为基础,Docker 可以优化镜像生成过程并使它容量紧凑。 + +接下来,添加这一行: + +```dockerfile +COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/ +``` + +这条 `COPY` 指令复制 `.csproj` 项目文件到镜像里的路径 `/app/AspNetCoreTodo/` 下。注意实际的代码(`.cs` 文件)并未复制到镜像里。你稍后即可弄清个中缘由。 + +```dockerfile +WORKDIR /app/AspNetCoreTodo +RUN dotnet restore +``` + +`WORKDIR` 是 Docker 里的 `cd`。Dockerfile 中之后的命令都会在这个 `/app/AspNetCoreTodo` 文件夹内执行,该文件夹是上一步的 `COPY` 命令创建的。 + +运行 `dotnet restore` 命令重建在 `.csproj` 中定义的那些程序所需的 NuGet 包。在添加其它代码 **之前** 于镜像中重建这些包,Docker 将有能力缓存这些重建的包。然后,当你修改代码(而没修改项目文件中定义的包)时,重建这个 Docker 镜像将会非常迅速。 + +现在,就到了复制其余代码并编译程序的时候了: + +```dockerfile +COPY AspNetCoreTodo/. ./AspNetCoreTodo/ +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false" +``` + +`dotnet publish` 命令编译项目,而 `-o out` 标识会将结果输出到一个名为 `out` 的目录里。 + +这些编译好的文件,将会通过这最终的几条命令,运行起这个程序: + +```dockerfile +FROM microsoft/dotnet:2.0-runtime AS runtime +ENV ASPNETCORE_URLS http://+:80 +WORKDIR /app +COPY --from=build /app/AspNetCoreTodo/out ./ +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"] +``` + +`FROM` 命令再次被用到,以选择一个较小的镜像,其中仅含有运行程序所需的依赖。`ENV` 命令用于容器中的设置环境变量,环境变量 `ASPNETCORE_URLS` 指示 ASP.NET Core 应该把服务绑定到哪个网卡和端口上(本例中时 80 端口)。 + +`ENTRYPOINT` 命令给 Docker 指出了在被运行的时候去执行 `dotnet AspNetCoreTodo.dll`。这条命令告诉 `dotnet`,使用先前由 `dotnet publish` 编译出来的文件启动你的程序。(当你在开发时运行 `dotnet run`,它一步就完成了这些事情。) + +完整的 Dockerfile 看起来是这样的: + +**Dockerfile** + +```dockerfile +FROM microsoft/dotnet:2.0-sdk AS build +COPY AspNetCoreTodo/*.csproj ./app/AspNetCoreTodo/ +WORKDIR /app/AspNetCoreTodo +RUN dotnet restore + +COPY AspNetCoreTodo/. ./ +RUN dotnet publish -o out /p:PublishWithAspNetCoreTargetManifest="false" + +FROM microsoft/dotnet:2.0-runtime AS runtime +ENV ASPNETCORE_URLS http://+:80 +WORKDIR /app +COPY --from=build /app/AspNetCoreTodo/out ./ +ENTRYPOINT ["dotnet", "AspNetCoreTodo.dll"] +``` + +### 创建一个镜像 + +确保 Dockerfile 已经保存好了,然后用 `docker build` 命令创建一个镜像: + +``` +docker build -t aspnetcoretodo . +``` + +不要漏掉结尾那个句点!它告诉 Docker 在当前目录下查找 Dockerfile。 + +一旦镜像创建完成,你可以运行 `docker images` 命令列出你本地电脑上的全部镜像。要通过容器尝试一下,请执行: + +``` +docker run --name aspnetcoretodo_sample --rm -it -p 8080:80 aspnetcoretodo +``` + +`-it` 标识告诉 Docker 以交互模式运行这个容器(输出到终端,而不是在后台运行)。当你想要停止这个容器的时候,按 `Control-C`。 + +还记得环境变量 `ASPNETCORE_URLS` 指示 ASP.NET Core 去监听 80 端口吗?这里的 `-p 8080:80` 选项指示 Docker 把 *你的* 电脑的 8080 端口映射到 *容器的* 80端口。打开你的浏览器,浏览地址 http://localhost:8080 去查看运行在容器中的程序。 + +### 设置 Nginx + +在本章开头,我提到过,你应该使用一个 Nginx 之类的反向代理服务器,把请求代理到 Kestrel 上。这件事也可以用 Docker 来做。 + +整体架构会包括两个容器:一个 Nginx 容器监听 80 端口,把请求转发到另一个运行着 Kestrel 并监听 5000 端口的容器。 + +Nginx 容器自己也需要一个 Dockerfile。为避免跟你刚才创建那个 Dockerfile 冲突,在 Web 程序根目录新建一个目录: + +``` +mkdir nginx +``` + +创建一个新的 Dockerfile 并添加这些行: + +**nginx/Dockerfile** + +```dockerfile +FROM nginx +COPY nginx.conf /etc/nginx/nginx.conf +``` + +接下来,创建一个 `nginx.conf` 文件: + +**nginx/nginx.conf** + +``` +events { worker_connections 1024; } + +http { + server { + listen 80; + location / { + proxy_pass http://kestrel:80; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'keep-alive'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + } +} +``` + +这个配置文件告诉 Nginx 把接到的请求转发到 `http://kestrel:80`。(你马上就会知道为什么要使用 `kestrel` 作为主机名。) + +> 当你把程序部署到生产环境,你应该添加 `server_name` 指令,并验证及限定 host 头字段为一个已知的有效值(known good values)。更多信息请参见: +> https://github.com/aspnet/Announcements/issues/295 + +### 设置 Docker Compose + +还需要创建一个文件,回到 Web 程序的根目录,创建 `docker-compose.yml`: + +**`docker-compose.yml`** + +```yaml +nginx: + build: ./nginx + links: + - kestrel:kestrel + ports: + - "80:80" +kestrel: + build: . + ports: + - "80" +``` + +Docker Compose 是个帮助你创建并运行多容器程序的工具。这个配置文件定义了两个容器: 用 `./nginx/Dockerfile` 清单创建 `nginx`,用 `./Dockerfile` 创建 `kestrel`。这两个容器显式地链接在一起,所以它们可以互相通信。 + +你可以运行以下指令来启动这个多容器程序: + +``` +docker-compose up +``` + +打开一个浏览器并导航至 `http://localhost`(不是 8080!)。Nginx 在 80 (HTTP 的默认)端口上进行监听,并把请求转发到由 Kestrel 托管的 ASP.NET Core 程序。 + +### 搭建 Docker 服务器 + +详尽的设置指令超出了这本书的范畴,但是任何较新的 Linux 发行版(例如 Ubuntu)都可以搭建成一个 Docker 宿主。例如,你可以用亚马逊 EC2 创建一个虚拟机,在上面安装 Docker 服务,为此你可以搜索 “amazon ec2 set up docker” 以获取说明。 + +我更喜欢用 DigitalOcean,因为他们把入门的门槛降得非常低。DigitalOcean 既有现成的 Docker 虚拟机,也有关于搭建和运行 Docker 的深度教程(请搜索“digitalocean docker”)。 + +--- + ## Deploy with Docker If you aren't using a platform like Azure, containerization technologies like Docker can make it easy to deploy web applications to your own servers. Instead of spending time configuring a server with the dependencies it needs to run your app, copying files, and restarting processes, you can simply create a Docker image that describes everything your app needs to run, and spin it up as a container on any Docker host. diff --git a/chapters/mvc-basics/README.md b/chapters/mvc-basics/README.md index 12def49..2cd78e2 100644 --- a/chapters/mvc-basics/README.md +++ b/chapters/mvc-basics/README.md @@ -1,3 +1,33 @@ +# MVC 基础 + +在这一章,你将探究 ASP.NET Core 中的 MVC 系统。 **MVC**(模型-视图-控制器,Model-View-Controller)是一个构建 web应用 的模式,其应用几乎遍及所有的 web框架(Ruby on Rails 和 Express 就是常见的范例)以及 Angular 这样的前端 JavaScript 框架。iOS 和 Android 上的移动应用也是 MVC 的一个变种。 + +正如其名字所示,MVC 有三个组件:模型、视图、和控制器。**控制器**处理从客户端浏览器传入的请求,并选定相应的代码进行处理。**视图**就是模板(一般是 HTML 外加某种 Handlebars、Pug、Razor 之类的模板语言),它接收传入的数据并展示给用户。**模型**则保管着数据,要么是准备发送给视图的,要么是用户输入的。 + +MVC 程序里常见的模式是: + +* 控制器接收请求,到数据库查找所需资料 +* 控制器使用查找到的信息创建模型,并使之与一个视图绑定 +* 视图在用户的浏览器里渲染并呈现 +* 用户点击一个按钮或者提交一个表单,从而发送一个新的请求给控制器,重复整个处理流程 + +如果你用其它开发语言写过 MVC,那你在 ASP.NET Core 里将如鱼得水。如果你是初次跟 MVC 打交道,这一章将教你基础知识,带你上道。 + +## 练习内容 + +MVC 练习里的 “Hello World”,就是创建一个待办事项清单应用程序。这是个很棒的练习,麻雀小,五脏俱全,它将涉及 MVC 的各个组件,而且涵盖了很多概念,它们可以直接应用于规模更大的应用程序。 + +通读本书,你将构建一个待办清单应用,允许用户添加待办项,并在事项完成之后勾掉它。具体来说,你将创建的是: + +* 一个 web 应用程序服务器(有时也被称为“后端”),使用 ASP.NET Core、C#和MVC模式 +* 一个用于存储用户待办事项条目的数据库,使用 SQLite 数据库引擎和一个被称为 Entity Framework Core 的系统创建 +* 让用户通过她们的浏览器进行交互的网页和界面(也被称为“前端”),使用HTML、CSS、JavaScript创建 +* 一个登录及安全检查表单,以便每个用户的待办事项列表都保持私密 + +听起来心动吗?那就整起来吧!你要是还没按上一章所讲,用 `dotnet new mvc` 创建一个新的 ASP.NET Core 项目。那你应该现在就创建并运行那个项目,直到看见默认的欢迎页面为止。 + +--- + # MVC basics In this chapter, you'll explore the MVC system in ASP.NET Core. **MVC** (Model-View-Controller) is a pattern for building web applications that's used in almost every web framework (Ruby on Rails and Express are popular examples), plus frontend JavaScript frameworks like Angular. Mobile apps on iOS and Android use a variation of MVC as well. diff --git a/chapters/mvc-basics/add-service-class.md b/chapters/mvc-basics/add-service-class.md index ad0fb1a..2af208b 100644 --- a/chapters/mvc-basics/add-service-class.md +++ b/chapters/mvc-basics/add-service-class.md @@ -1,3 +1,100 @@ +## 添加一个服务类 + +你已经创建了一个模型、一个视图、一个控制器。在你把模型和视图应用于控制器中之前,需要先写点代码,用它把用户的待办事项条目从数据库里取出来。 + +你可以在直接在控制器里编写这段数据库相关的代码,但是作为更良好的实践,应该保持你的代码独立。为什么呢?在一个巨大的,现实世界的程序里,你不得不应付一些事情: + +* **渲染视图** 并处理接收的数据:你的控制器已经处理好了。 +* **执行业务逻辑**,或者说跟你程序的目标和“业务”相关联的代码与逻辑。在一个待办事项列表程序里,业务逻辑意味着“为新任务设置一个默认的截止时间”,或者“仅显示未完成的任务”这些决策。业务逻辑的其它例子,包括“基于产品价格和税率计算总价”,或者“在游戏里检查一个玩家是否有足够的经验值升级”。 +* **存入和取出**数据库中的数据。 + +还是那句话,把所有这些东西写进一个单独的巨大的控制器是可行的,但这很快就会变得难以管理和测试。相反,常见的程序都把这些分割成两个、三个或更多的“层”或级,每个层级处理(且仅处理)一件事情。这有助于保持控制器尽量简单,并简化测试工作,以及后续的业务逻辑和数据库代码的修改。 + +把程序以这种方式分割,有时被称为 **多级** 或者 **n级架构**。在某些情况下,这些层级被隔离在完全分离的项目中,也有时候这仅仅意味着各个类之间组织和调用的方式。重点在于考量如何把你的程序分割成多个可管理的部分,以避免控制器或者某些臃肿的类试图去处理所有事情。 + +对当前这个项目而言,你将把程序分为两个层:一个由控制器和视图构成的 **表示层**,用来处理用户的交互,和一个包含了业务逻辑和数据库代码的 **服务层**。表示层已经有了,所以,接下来就应该构建一个服务,用来处理 待办事项 的业务逻辑,并把待办事项条目保存到数据库里去。 + +> 多数较大的项目使用一种 3级 架构:一个表示层,一个逻辑服务层,一个数据仓储层。**仓储(repository)** 是一个仅关注数据库操作(不处理业务逻辑)的类。咱们眼下的程序里,为简化操作,我们将把这些混进一个服务层里,不过你尽可尝试采用不同的方式去架构你的代码。 + +### 创建一个接口 + +C# 编程语言里有一个概念叫 **接口(interface)**,在接口中,一个对象中方法和属性的定义与实际包含这些方法和属性的类分离开来。接口有助于解耦你的那些类,也有助于测试,如你接下来(以及在后续的 *自动化测试* 章节中)所见。你将用一个接口来表示一个服务,该服务负责就待办事项条目事宜与数据库交互。 + +习惯上,接口以大写字母“I”开头,在 Services 目录下新建一个文件: + +**Services/ITodoItemService.cs** + +```csharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using AspNetCoreTodo.Models; + +namespace AspNetCoreTodo.Services +{ + public interface ITodoItemService + { + Task GetIncompleteItemsAsync(); + } +} +``` + +注意一下,这个文件的命名空间是 `AspNetCoreTodo.Services`。命名空间是一种组织 .NET 代码文件的方式,一般与存放该文件的目录名保持一致(`Services`目录下的文件,命名空间是`AspNetCoreTodo.Services`,以此类推)。 + +因为这个文件(在命名空间`AspNetCoreTodo.Services`中)引用了 `TodoItem` 类(在命名空间 `AspNetCoreTodo.Models`中),它需要在文件顶部包含一条 `using` 语句,引入那个命名空间。如果不写这个 `using` 语句,你会看到这样的报错: + +```txt +The type or namespace name 'TodoItem' could not be found (are you missing a using directive or an assembly reference?) +``` + +因为这是一个接口,所以不包含任何实现相关的代码,只有 `GetIncompleteItemsAsync` 方法的定义(或者叫 **方法签名(method signature)**)。该方法不需要任何参数,并且返回一个 `Task`。 + +> 如果这种语法让你看上去感到困惑,就这么理解:“一个 Task 里面装着一个 TodoItem 的数组”。 + +`Task` 类型类似于一个 future 或者 promise[^1],这里使用它的原因是,这将是个 **异步的(asynchronous)** 方法。换句话说,这个方法可能不会即时返回待办事项的列表,因为它需要先查询数据库。(详情见后续章节。) + +### 创建服务类 + +现在接口已经定义好,你可开始创建具体的服务类了。在后续的 *使用数据库* 那章,我会深入讲解有关数据库的代码,但目前你可以造个假,直接返回硬编码的值: + +**Services/FakeTodoItemService.cs** + +```csharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using AspNetCoreTodo.Models; + +namespace AspNetCoreTodo.Services +{ + public class FakeTodoItemService : ITodoItemService + { + public Task GetIncompleteItemsAsync() + { + var item1 = new TodoItem + { + Title = "Learn ASP.NET Core", + DueAt = DateTimeOffset.Now.AddDays(1) + }; + + var item2 = new TodoItem + { + Title = "Build awesome apps", + DueAt = DateTimeOffset.Now.AddDays(2) + }; + + return Task.FromResult(new[] { item1, item2 }); + } + } +} +``` + +`FakeTodoItemService` 实现了 `ITodoItemService` 接口,但总是返回这个包含两个 `TodoItem` 的数组。你可以用它去测试控制器和视图,然后在 *使用数据库* 那章添加真正的代码去访问数据库。 + +[^1]: 译者注:二者都是其它语言中,与异步编程相关的概念,它们是用于指代某个尚未就绪的值的对象。而这个值,往往是某个计算过程的结果。要了解详细,请参考 https://en.wikipedia.org/wiki/Futures_and_promises + +--- + ## Add a service class You've created a model, a view, and a controller. Before you use the model and view in the controller, you also need to write code that will get the user's to-do items from a database. diff --git a/chapters/mvc-basics/create-controller.md b/chapters/mvc-basics/create-controller.md index 6e59149..eaa111e 100644 --- a/chapters/mvc-basics/create-controller.md +++ b/chapters/mvc-basics/create-controller.md @@ -1,3 +1,61 @@ +## 创建控制器 + +在项目的 Controllers 目录里,已经预置了几个控制器,其中有渲染默认欢迎页的 `HomeController`,就是你访问 `http://localhost:5000` 看到的那个页面。暂时不用管这些控制器。 + +给待办清单功能创建一个新的控制器,取名叫 `TodoController` ,并添加如下代码: + +**Controllers/TodoController.cs** + +``` csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace AspNetCoreTodo.Controllers +{ + public class TodoController : Controller + { + // 在这里添加 Actions + } +} +``` + +由控制器本身处理的路由叫 **action** ,在控制器类里用方法表示。比如,`HomeController` 包含三个 action 方法(`Index`,`About`,和 `Contact`),由 ASP.NET Core 分别映射到如下的 URL: + +```text +localhost:5000/Home -> Index() +localhost:5000/Home/About -> About() +localhost:5000/Home/Contact -> Contact() +``` + +ASP.NET Core 中有几个惯例(常见的模式),比如这个 `FooController` 映射到 `/Foo` 的模式,还有 `Index` 的 action名 可以在 URL 里省略。如果你有需要,可以自定义这些行为,不过就目前的情况,让我们暂且遵循这些惯例。 + +在 `TodoController` 里,添加一个名为 `Index` 的 action,把那句 `// Actions go here` 注释替换掉: + +```csharp +public class TodoController : Controller +{ + public IActionResult Index() + { + // 从数据库获取 to-do 条目 + + // 把条目置于 model 中 + + // 使用 model 渲染视图 + } +} +``` + +一个 action 方法可以返回视图、JSON数据,或者 `200 OK`和`404 Not Found` 之类的状态码。返回类型 `IActionResult` 给了你足够的灵活性,以返回上面提到的任意一个。 + +使控制器尽可能保持轻量化,是一个良好的习惯。在当前的情形里,这个控制器应该仅仅完成这些事情:从数据库取出待办事项的记录,把这些事项包装在一个可用于视图的模型中,并把这个视图发送到用户的浏览器。 + +继续编码这个控制器之前,你需要创建 模型 和 视图。 + +--- + ## Create a controller There are already a few controllers in the project's Controllers directory, including the `HomeController` that renders the default welcome screen you see when you visit `http://localhost:5000`. You can ignore these controllers for now. diff --git a/chapters/mvc-basics/create-models.md b/chapters/mvc-basics/create-models.md index 8f7f7af..3439bd0 100644 --- a/chapters/mvc-basics/create-models.md +++ b/chapters/mvc-basics/create-models.md @@ -1,3 +1,70 @@ +## 创建模型 + +我们需要创建两个独立的模型类:一个模型表示保存在数据库里的条目(有时候也称为一个 **记录(entity)**),另一个模型将与视图结合(MVC里的 **MV**)发送到用户的浏览器。因为他们都可以被称为模型,我将称后者为 **视图模型(view model)**。 + +首先,在 Models 目录下,创建一个名为 `TodoItem` 的类: + +**`Models/TodoItem.cs`** + +```csharp +using System; + +namespace AspNetCoreTodo.Models +{ + public class TodoItem + { + public Guid Id { get; set; } + + public bool IsDone { get; set; } + + [Required] + public string Title { get; set; } + + public DateTimeOffset? DueAt { get; set; } + } +} +``` + +这个类定义了每个待办事项都要保存的内容:一个 ID、一个标题或者名称、该事项是否已经完成,以及截至日期是什么时候。每行定义了这个类的一个属性: + +* **Id** 属性是一个 guid,或者说是 全局(**g**lobally) 唯一(**u**nique) 标识符(**id**entifier). Guid(或者GUID)是一个由字母和数字组成的长长的字符串,看起来是这样的 `43ec09f2-7f70-4f4b-9559-65011d5781bb`。因为 guid 是随机的,并极少会有重复值,所以常被用作唯一标识。你也可以用数字(整形 integer)作为数据库记录的标识,但你需要在数据库里配置,以便这个数字在添加新条目的时候始终增长。因为 Guid 是随机生产的,所以就你不必再担心这个 自增 的问题了。 + +* **IsDone** 属性是一个 布尔值(值为 true/false)。默认情况下,所有新建条目的该值为 `false`。你后面会编写代码,在用户在视图里点击某个条目的复选框时,修改这个属性为 `true`。 + +* **Title** 属性是一个字符串,用于保存待办事项的名称或者简述。 + +* **DueAt** 属性是一个 `DateTimeOffset`,C# 用于这种类型保存一个 日期/时间 的戳记和一个与 UTC 偏移量表示的时区。把时期、时间和时区一起保存,有助于在不同时区的系统上准确地显示时间。 + +看到 `DateTimeOffset` 类型后面那个问号 `?` 了吗?它表示 DueAt 属性 **可空(nullable)**,或者说是可选的。如果不加这个 `?`,每个待办事项都必须带有一个截止日期。`Id` 和 `IsDone` 属性没有标记为可空,所以是必须的,并可以确保始终有值(或者是一个缺省值)。 + +> C#里的字符串总是可空的,所以没必要给 Title 属性添加可空标记。C# 字符串可以没有值,也可以是空白字符串或者包含任意文本。 + +每个属性后面都跟着 `get; set;` ,这是个简写,表示该属性 可读/可写(read/write)(或者,更确切地说,它有 getter 和 setter 方法各一个)。 + +现在,暂且不必关心底层数据库采用的是哪种实现。它可以是 SQL Server,MySQL,MongoDB,Redis,或者什么其它稀奇古怪的玩意儿。这个模型定义了数据库里的行或者记录在 C# 里看起来是什么样的,所以你无须在代码层面担心数据库层面的东西。这种模型简单的风格被称为“朴实可爱的 C# 对象(plain old C# object)” 或者 POCO。 + +### 视图模型 + +通常,你保存在数据库里的模型(实体),跟你在 MVC 里用的模型(视图模型)非常相似,但又不尽相同。在现在的情形下, `TodoItem` 模型代表单一的一个数据库里的条目,而视图则需要展示两个、十个,甚至是一百个待办事项(取决于用户拖延症的病情轻重)。 + +因此,视图模型应该是一个独立的类,里面包含着一个 `TodoItem` 的数组: + +**Models/TodoViewModel.cs** + +```csharp +namespace AspNetCoreTodo.Models +{ + public class TodoViewModel + { + public TodoItem[] Items { get; set; } + } +} +``` + +好了,现在模型也有了,是时候创建一个接收 `TodoViewModel` 并以 HTML 向用户展示待办事项列表的视图了。 + +--- + ## Create models There are two separate model classes that need to be created: a model that represents a to-do item stored in the database (sometimes called an **entity**), and the model that will be combined with a view (the **MV** in MVC) and sent back to the user's browser. Because both of them can be referred to as "models", I'll refer to the latter as a **view model**. diff --git a/chapters/mvc-basics/create-view.md b/chapters/mvc-basics/create-view.md index 3756a0e..8a8260a 100644 --- a/chapters/mvc-basics/create-view.md +++ b/chapters/mvc-basics/create-view.md @@ -1,3 +1,83 @@ +## 创建视图 + +ASP.NET Core 里的视图使用 Razor 模板语言编写,这种模板语言混合了 HTML 和 C# 的代码。(如果你在 JavaScript 下用 Jade、Pug 或者 Handlebars moustaches,在 Ruby on Rails 下用 ERB,在 Java 下用 Thymeleaf 写过页面,那你就已经了解其基本概念了.) + +绝大多数视图代码就是 HTML,偶尔掺杂一点 C# 语句,用以从视图模型里抽取数据并转换为文本或者 HTML。这些 C# 语句以符号 `@` 作为前缀。 + +由 `TodoController` 中的 action `Index` 生成的视图,需要从视图模型(一个待办事项的数组)获取数据,并用一个适当的表格展示给用户。按规定,视图要置于 `Views` 目录里,在一个与所属控制器同名的子目录下。视图文件的文件名就是 action 的名字加上一个 `.cshtml` 扩展名。 + +**Views/Todo/Index.cshtml** + +```html +@model TodoViewModel + +@{ + ViewData["Title"] = "Manage your todo list"; +} + +
                                                                    +
                                                                    @ViewData["Title"]
                                                                    + + + + + + + + + + + @foreach (var item in Model.Items) + { + + + + + + } +
                                                                    ItemDue
                                                                    + + @item.Title@item.DueAt
                                                                    + + +
                                                                    +``` + +在文件顶端,`@model` 指令告诉 Razor 该视图要绑定到哪个模型。模型通过 `Model` 属性进行访问。 + +如果在 `Model.Items` 里有一些待办事项条目,则 `foreach` 语句将遍历到每个代办事项,并渲染成一个表格的行(`` 元素),改行包含条目的名字和截止日期。还会展示一个带有 ID 的复选框,可以在后续操作中把该条目标记为已完成。 + +### 布局文件 + +你可能会纳闷,其余的 HTML:`` 标签,或者 页首 和 页脚 在哪儿?ASP.NET Core 使用一个布局视图,用以定义容纳视图的基础结构的其余部分。布局视图被保存在 `Views/Shared/_Layout.cshtml`。 + +默认的 ASP.NET Core 模板在布局文件中包含了 Bootstrap 和 jQuery,便于你快捷地创建一个 web 应用程序。当然,只要你愿意,你可以使用自己的 CSS 和 JavaScript 库。 + +### 定制样式表 + +现在,请在 `site.css` 文件的底部添加以下这些 CSS 样式规则: + +**wwwroot/css/site.css** + +```css +div.todo-panel { + margin-top: 15px; +} + +table tr.done { + text-decoration: line-through; + color: #888; +} +``` + +你可以用类似的规则完全自定义页面的外观和体验。 + +ASP.NET Core 和 Razor 还有更多功能,比如部分视图和后端渲染的视图组件,但你现在只需要一个简单的布局和视图。想要了解更多的内容,ASP.NET Core 的官方文档(位于 `https://docs.asp.net`)有几个示例可以参考。 + +--- + ## Create a view Views in ASP.NET Core are built using the Razor templating language, which combines HTML and C# code. (If you've written pages using Handlebars moustaches, ERB in Ruby on Rails, or Thymeleaf in Java, you've already got the basic idea.) diff --git a/chapters/mvc-basics/finish-controller.md b/chapters/mvc-basics/finish-controller.md index 8f55350..b503814 100644 --- a/chapters/mvc-basics/finish-controller.md +++ b/chapters/mvc-basics/finish-controller.md @@ -1,3 +1,42 @@ +## 完成控制器 + +最后一步,让我们来完成控制器的编码。控制器现在已经从 服务层 获取到一个 待办事项 的列表,它应该把这些条目放进一个 `TodoViewModel`,并把该 模型 与你先前创建的 视图 绑定: + +**Controllers/TodoController.cs** + +```csharp +public async Task Index() +{ + var items = await _todoItemService.GetIncompleteItemsAsync(); + + var model = new TodoViewModel() + { + Items = items + }; + + return View(model); +} +``` + +如果你还没在文件顶部添加 `using` 语句,现在加上: + +```csharp +using AspNetCoreTodo.Services; +using AspNetCoreTodo.Models; +``` + +如果你用的是 Visual Studio 或者 Visual Studio Code,当你鼠标指针指向一个红色波浪线时,编辑器会提示你添加这些 `using` 语句。 + +## 测试一下 + +按 F5 启动程序(如果你用的是 Visual Studio 或者 Visual Studio Code),或者在终端窗口里运行 `dotnet run`。如果代码通过编译而没有报错,服务器将在默认的 5000 端口上运行。 + +如果你的网络浏览器没自动弹出来,打开它,浏览 http://localhost:5000/todo 。你会看到自己创建的视图,展示着(暂时)从伪数据库层提取的数据。 + +尽管可以径直浏览 `http://localhost:5000/todo`,但如果导航栏上有一个 **我的待办事项** 条目就更好了。要达成这个目的,你可以去编辑共享的布局文件。 + +--- + ## Finish the controller The last step is to finish the controller code. The controller now has a list of to-do items from the service layer, and it needs to put those items into a `TodoViewModel` and bind that model to the view you created earlier: diff --git a/chapters/mvc-basics/update-the-layout.md b/chapters/mvc-basics/update-the-layout.md index bbed376..3d3a577 100644 --- a/chapters/mvc-basics/update-the-layout.md +++ b/chapters/mvc-basics/update-the-layout.md @@ -1,3 +1,39 @@ +## 修改布局 + +位于 `Views/Shared/_Layout.cshtml` 的布局文件里面存放着所有视图的“基础”HTML。其中就包括导航栏,它被显示在每个页面的顶端。 + +为了向导航栏添加新条目,请先找到原有导航栏的 HTML 代码: + +**Views/Shared/_Layout.cshtml** + +```html +
                                                                    +``` + +添加你的条目,不要指向 `Home` 控制器,而要改为指向 `Todo`: + +```html +
                                                                  • + My to-dos +
                                                                  • +``` + +`` 元素中的属性 `asp-controller` 和 `asp-action` 被称为 **tag helper**。在视图被渲染之前,ASP.NET Core 会把这些 tag helper 替换成真正的 HTML 属性。在本例中,会生成一个指向路由 `/Todo/Index` 的 URL 并作为 `href` 添加到 `` 元素中。这意味着你不必硬编码这个指向 `TodoController` 的路由。而是 ASP.NET Core 自动为你生成。 + +> 如果你在 ASP.NET 4.x 中用过 Razor,应该会注意到一些语法的差异。生成一个指向 action 链接的时候,tag helper 是现在的建议的方式,而不是使用 `@Html.ActionLink()`。tag helper 对表单也很有用(你会在后续章节明白原委)。要学习其它的 tag helper,可以参考位于 https://docs.asp.net 的文档。 + +--- + ## Update the layout The layout file at `Views/Shared/_Layout.cshtml` contains the "base" HTML for each view. This includes the navbar, which is rendered at the top of each page. diff --git a/chapters/mvc-basics/use-dependency-injection.md b/chapters/mvc-basics/use-dependency-injection.md index 5c3c1c9..c7b8240 100644 --- a/chapters/mvc-basics/use-dependency-injection.md +++ b/chapters/mvc-basics/use-dependency-injection.md @@ -1,3 +1,101 @@ +## 运用依赖注入 + +回到 `TodoController`,添加一些代码以使用 `ITodoItemService`: + +```csharp +public class TodoController : Controller +{ + private readonly ITodoItemService _todoItemService; + + public TodoController(ITodoItemService todoItemService) + { + _todoItemService = todoItemService; + } + + public IActionResult Index() + { + // Get to-do items from database + + // Put items into a model + + // Pass the view to a model and render + } +} +``` + +既然 `ITodoItemService` 在命名空间 `Services` 里,你同样需要在文件顶部添加一个 `using` 语句: + +```csharp +using AspNetCoreTodo.Services; +``` + +这个类的第一行声明了一个私有变量,保存 `ITodoItemService` 的引用。这个变量可以让你在后面的 `Index` 方法里使用该服务(具体方法,稍后便知)。 + +`public TodoController(ITodoItemService todoItemService)` 这一行给类定义了一个 **构造函数(constructor)**。构造函数是一个特殊的方法,它会在为(本例中是 `TodoController`)类创建一个新的实例的时候被调用。在构造函数中加入的 `ITodoItemService` 参数,表示你做出如下声明:要创建一个 `TodoController`,你必须提供一个能匹配 `ITodoItemService` 接口的对象。 + +> 接口如此有用的原因就在于,因为它们有助于解耦(分离)你程序里的逻辑。既然这个控制器依赖于 `ITodoItemService` 接口,而不是任何 *特定的* 类,它就不知道也不必关心实际使用的是哪个具体的类。它可以是 `FakeTodoItemService`,或者是其它读写数据库的类,或者别的什么类。只要它符合该接口的要求,控制器就能工作。这使你可以轻而易举地,独立测试程序的各部分。(我会在 *自动化测试* 一章讲解测试相关的内容。) + +现在,你终于可以在 action 方法里,(通过你声明的那个私有变量)使用 `ITodoItemService` 从服务层获取 待办事项 了: + +```csharp +public IActionResult Index() +{ + var items = await _todoItemService.GetIncompleteItemsAsync(); + + // ... +} +``` + +还记得吗? `GetIncompleteItemsAsync` 方法返回一个 `Task`。“返回一个 `Task`”的意思是说,该方法不能立刻给出一个结果,但是你可以使用关键字 `await`,以确保你的代码暂停,直到结果就绪才继续执行。 + +当你编写代码访问数据库或者外部 API 服务的时候,`Task` 模式是很常见的,因为在数据库(或者网络)响应之前,它不可能给出实际的结果。如果你在 JavaScript 或者其它语言里使用过 promise 或者 回调函数,`Task` 与之如出一辙:承诺你,肯定会给出一个结果——在未来的某个时候。 + +> 如果你在老式 JavaScript 里应付过 “回调地狱”,那你现在走运了。在 .NET 里使用 `Task` 跟依附代码打交道要容易得多,这归功于神奇的关键字 `await`。 `await` 把代码暂停在 异步(async) 操作上,而后,在底层数据库或者网络请求结束时,从暂停的地方恢复执行。就是说,你的程序并没有卡住或者阻塞住,因为它可以处理其它的请求。如果现在想不通也别担心,跟着做下去就行! + +目前的重点就是修改 `Index` 方法的签名,以返回一个 `Task`,代替之前的 `IActionResult`,并标记为 `async`: + +```csharp +public async Task Index() +{ + var items = await _todoItemService.GetIncompleteItemsAsync(); + + // Put items into a model + + // Pass the view to a model and render +} +``` + +胜利在望!你已经让 `TodoController` 依赖于 `ITodoItemService` 接口,但你还没告诉 ASP.NET Core,你想把 `FakeTodoItemService` 作为幕后的实际服务。可能你觉得这是理所当然的,因为你的`ITodoItemService`仅有这一个实现,但你后面会为同一个接口提供多个实现,所以,有必要明确指定实现。 + +要声明(或者“关联”)具体的类到每个接口上,需要写在 `StartUp` 类的 `ConfigureServices` 方法里,在当前情况里,应该这么写: + +**Startup.cs** + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + // (... some code) + + services.AddMvc(); +} +``` + +`ConfigureServices` 方法负责的是把东西添加到 **服务容器** 里,或者 ASP.NET Core 的说法是服务的集合。 `services.AddMvc` 这行添加了一些服务,它们是 ASP.NET Core 系统内部依赖的(你可以试试,把这行代码注释掉)。你在应用里所需的任何其它服务,也都要在这个地方添加到服务容器里。 + +把下面这行添加到`ConfigureServices`中的任意位置: + +```csharp +services.AddSingleton(); +``` + +这一行告知 ASP.NET Core,在任何时候,只要 `ITodoItemService` 被一个构造函数(或其它什么地方)被请求,就用这个 `FakeTodoItemService`。 + +`AddSingleton` 把你的服务作为 **singleton** 添加进服务容器。这意味着,只有一个`FakeTodoItemService`的实例被创建,并在每次被请求的时候都被复用。在后面,当你写另一个服务去跟数据库交互时,你会采用一个不同的方式(叫做 **scoped**)。我会在 *运用数据库* 一章里说明原因。 + +好了,当一个请求进来,将会被发送到 `TodoController`,当控制器需要一个`ITodoItemService` 时,ASP.NET Core 会在 可用服务集合 里查找并自动给出 `FakeTodoItemService`。因为服务是从服务容器里“注入(injected)”的,这个模式被称为 **依赖注入(dependency injection)**。 + +--- + ## Use dependency injection Back in the `TodoController`, add some code to work with the `ITodoItemService`: diff --git a/chapters/security-and-identity/README.md b/chapters/security-and-identity/README.md index 05503db..aaf39de 100644 --- a/chapters/security-and-identity/README.md +++ b/chapters/security-and-identity/README.md @@ -1,3 +1,29 @@ +# 安全和身份 + +安全性是任何现代 Web 应用或 API 都要重点关注的。确保用户或顾客的数据安全并免遭黑客染指,是非常重要的。这个话题所涉甚广,包括了: + +* 过滤输入数据,避免 SQL注入 +* 防止利用表单(form)进行的跨域(CSRF)攻击 +* 使用 HTTPS(TLS),避免在 Internet 上传输的数据被窃取 +* 确保用户 输入密码 或者 通过社交媒体授权 登录时的安全性 +* 设计 密码重置 或 多重身份认证流程 时,考虑到安全性的因素 + +ASP.NET Core 有助于实现这些功能。前两个(防止SQL注入和跨域攻击)功能已经内置了,要开启 HTTPS,只需寥寥数行代码即可。本章主要关注安全性的 **身份验证(identity)** 方面:管理用户的账号(注册、登录),安全地验证用户(登录),并在验证后做出授权决策。 + +> 验证 和 授权 二者常被混淆。**验证** 关心的是用户登录与否,而 **授权** 关心“用户在登录 *后* 能否做某些事”。你可以认为 验证 是在问:“我知道这个用户是谁吗?”,而 授权 问的是:“这个用户有权限做某件事吗?” + +你搭建项目的时候,应用了 MVC + Individual验证 项目模板,该模板中带有几个类,构建在 ASP.NET Core Identity(一个验证和身份系统,属于 ASP.NET Core 的一部分)之上。安装后,默认添加了通过 email 和密码进行登录的功能。 + +## ASP.NET Core Identity 是什么? + +ASP.NET Core Identity 是 ASP.NET Core 带来的身份系统,就像 ASP.NET Core 生态圈中的其它部分,它也是一组 NuGet 包,可以被安装在任何项目中(并且包括在默认的模板中了)。 + +ASP.NET Core Identity 处理用户账号的存储、散列并保存密码、还负责管理用户的角色。它支持 邮箱地址/密码 登录、多重身份验证、集成以 Google 和 Facebook 之类的身份提供者的 社交账号登录、以及借助 OAuth 2.0 和 OpenID Connect 等协议连接到其它的服务。 + + MVC + Individual验证 项目模板中的 Register 和 Login 视图 已经从 ASP.NET Core Identity 中受益,而且已经正常工作了,请试着注册一个账号并用它登录。 + +--- + # Security and identity Security is a major concern of any modern web application or API. It's important to keep your user or customer data safe and out of the hands of attackers. This is a very broad topic, involving things like: diff --git a/chapters/security-and-identity/add-facebook-login.md b/chapters/security-and-identity/add-facebook-login.md new file mode 100644 index 0000000..44c5534 --- /dev/null +++ b/chapters/security-and-identity/add-facebook-login.md @@ -0,0 +1,133 @@ +## 添加 Facebook 登录功能 + +Individual Auth 项目模板包括了“开箱即用”式的“使用电子邮件地址和密码注册”的功能。你可以添加额外的身份供应者(比如 Google 和 Facebook)来扩展这个功能。 + +要接入任何一个身份供应商,你通常需要做这两件事: + +1. 在供应商那里创建一个 应用(有时候也叫*客户(client)*),以此代表你的程序 +1. 复制供应商生成的 ID 和 密码,放进你的代码里 + +### 在 Facebook 创建一个应用 + +你可以使用位于 https://developers.facebook.com/apps 的 Facebook 开发者控制台创建一个新的 Facebook 应用。点击 **Add a New App** 并按提示创建一个应用 ID。 + +> 如果你没有 Facebook 账号,可以换成 Google 或者 Twitter 登录功能。在供应商网站上的操作会有些差异,但在代码里基本一致。 + +下一步,设置 Facebook Login 然后点击左边栏的 Settings —— 在 Facebook Login 下面: + +![Settings button](facebook-login-settings.png) + +把以下 URL 添加到 **Valid OAuth redirect URIs** 文本框里。 + +``` +http://localhost:5000/signin-facebook +``` + +> 你程序运行的时候,监听的端口可能不一样。如果你使用 `dotnet start` 通常是 5000 端口,但如果你在 Windows 上,可能是个随机的端口比如 54574。无论如何,当程序运行的时候,你总是可以在浏览器的地址栏里看到程序监听的端口。 + +点击 **Save Changes**,然后打开 Dashboard 页面。在这里你可以看到由 Facebook 创建的 应用ID 和 密码,这些稍后就会用到(请保持这个页面开启)。 + +要在 ASP.NET Core Identity 里启用 Facebook 登录功能,把下面这段代码添加到 `Startup` 类里 `ConfigureServices` 方法中的任意位置: + +```csharp +services + .AddAuthentication() + .AddFacebook(options => + { + options.AppId = Configuration["Facebook:AppId"]; + options.AppSecret = Configuration["Facebook:AppSecret"]; + }); +``` + +为免把 Facebook 应用ID 和 密码 硬编码在程序里,这些值应该从配置系统里获取。一般情况下 `appsettings.json` 文件是保存项目配置信息的地方。尽管如此,既然它会被提交到版本控制系统里,就不太适合 应用ID 和 密码 这些敏感信息。(比方说,你的密码推送到了 GitHub,任何人都可能窃取它,并滥用它来损害你的利益。) + +### 通过 Secrets Manager 来安全地保存密码 + +你可以把 Secrets Manager 工具用于 应用密码 这种敏感信息。在终端窗口里执行这一行以确保它安装过了(先确保你当前位于项目目录中): + +``` +dotnet user-secrets --help +``` + +从 Facebook 应用管理页面复制 应用ID 和 密码,并使用 `set` 命令将它们的值保存在 Secrets Manager 里: + +``` +dotnet user-secrets set Facebook:AppId <粘贴 应用ID> +dotnet user-secrets set Facebook:AppSecret <粘贴 应用密码> +``` + +当你的程序启动的时候,Secrets Manager 里的值会加载到 `Configuration` 属性中,所以你刚才在 `ConfigureServices` 中添加的代码能够访问到它们。 + +运行程序,在导航条上点击 Login,你会看到一个新的按钮,用于 Facebook 登录功能: + +![Facebook login button](facebook-login-button.png) + +试一下 Facebook 登录功能。你会被重定向到 Facebook 并被提示向你的应用授权,然后重定向回来再登录进去。 + +--- + +## Add Facebook login + +Out of the box, the Individual Auth template includes functionality for registering using an email and password. You can extend this by plugging in additional identity providers like Google and Facebook. + +For any external provider, you typically need to do two things: + +1. Create an app (sometimes called a *client*) on the external provider that represents your application +1. Copy the ID and secret generated by the provider and put them in your code + +### Create an app in Facebook + +You can create new Facebook apps using the Facebook Developer console at https://developers.facebook.com/apps. Click **Add a New App** and follow the instructions to create an app ID. + +> If you don't have a Facebook account, you can set up Google or Twitter login instead. The steps on the provider's site will be different, but the code is almost identical. + +Next, set up Facebook Login and then click Settings on the left side, under Facebook Login: + +![Settings button](facebook-login-settings.png) + +Add the following URL to the **Valid OAuth redirect URIs** box: + +``` +http://localhost:5000/signin-facebook +``` + +> The port that your application runs on may differ. It's typically port 5000 if you use `dotnet start`, but if you're on Windows, it could be a random port like 54574. Either way, you can always see the port your application is running on in the address bar of your web browser. + +Click **Save Changes** and then head over to the Dashboard page. Here you can see the app ID and secret generated by Facebook, which you'll need in a moment (keep this tab open). + +To enable Facebook login in ASP.NET Core Identity, add this code anywhere in the `ConfigureServices` method in the `Startup` class: + +```csharp +services + .AddAuthentication() + .AddFacebook(options => + { + options.AppId = Configuration["Facebook:AppId"]; + options.AppSecret = Configuration["Facebook:AppSecret"]; + }); +``` + +Instead of hardcoding the Facebook app ID and secret in your code, the values are pulled from the configuration system. The `appsettings.json` file is normally the place to store configuration data for your project. However, since it's checked into source control, it's not good for sensitive data like an app secret. (If your app secret was pushed to GitHub, for example, anyone could steal it and do bad things on your behalf.) + +### Store secrets safely with the Secrets Manager + +You can use the Secrets Manager tool for sensitive data like an app secret. Run this line in the terminal to make sure it's installed (make sure you're currently in the project directory): + +``` +dotnet user-secrets --help +``` + +Copy the app ID and secret from the Facebook app dashboard and use the `set` command to save the values in the Secrets Manager: + +``` +dotnet user-secrets set Facebook:AppId +dotnet user-secrets set Facebook:AppSecret +``` + +The values from the Secrets Manager are loaded into the `Configuration` property when your application starts up, so they're available to the code in `ConfigureServices` you added before. + +Run your application and click the Login link in the navbar. You'll see a new button for logging in with Facebook: + +![Facebook login button](facebook-login-button.png) + +Try logging in with Facebook. You'll be redirected and prompted to give your app permission in Facebook, then redirected back and logged in. diff --git a/chapters/security-and-identity/authorization-with-roles.md b/chapters/security-and-identity/authorization-with-roles.md index 81be180..9dc1333 100644 --- a/chapters/security-and-identity/authorization-with-roles.md +++ b/chapters/security-and-identity/authorization-with-roles.md @@ -1,3 +1,350 @@ +## 按角色进行授权 + +在网络应用里,角色是用于处理 授权 和 许可 的常见方法。例如,通常会为管理员创建一个 Administrator 角色,相对于普通用户,他们拥有更多的权限和能力。 + +在此项目中,你将添加一个 用户管理 页面,仅对管理员们可见。如果普通用户试图访问它,将会看到错误提示。 + +### 添加用户管理页面 + +首先,创建一个新控制器: + +**Controllers/ManageUsersController.cs** + +```csharp +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using AspNetCoreTodo.Models; +using Microsoft.EntityFrameworkCore; + +namespace AspNetCoreTodo.Controllers +{ + [Authorize(Roles = "Administrator")] + public class ManageUsersController : Controller + { + private readonly UserManager + _userManager; + + public ManageUsersController( + UserManager userManager) + { + _userManager = userManager; + } + + public async Task Index() + { + var admins = (await _userManager + .GetUsersInRoleAsync("Administrator")) + .ToArray(); + + var everyone = await _userManager.Users + .ToArrayAsync(); + + var model = new ManageUsersViewModel + { + Administrators = admins, + Everyone = everyone + }; + + return View(model); + } + } +} +``` + +在 `[Authorize]` 属性里加入 `Roles` 字段,可以确保用户必须已经登录 **并且** 被分配了 `Administrator` 角色才能查看这个页面。 + +接下来,创建一个视图模型: + +**Models/ManageUsersViewModel.cs** + +```csharp +using System.Collections.Generic; + +namespace AspNetCoreTodo.Models +{ + public class ManageUsersViewModel + { + public ApplicationUser[] Administrators { get; set; } + + public ApplicationUser[] Everyone { get; set;} + } +} +``` + +最后,为 action Index 创建一个名为`Views/ManageUsers`的文件夹和一个视图: + +**Views/ManageUsers/Index.cshtml** + +```html +@model ManageUsersViewModel + +@{ + ViewData["Title"] = "Manage users"; +} + +

                                                                    @ViewData["Title"]

                                                                    + +

                                                                    Administrators

                                                                    + + + + + + + + + + @foreach (var user in Model.Administrators) + { + + + + + } +
                                                                    IdEmail
                                                                    @user.Id@user.Email
                                                                    + +

                                                                    Everyone

                                                                    + + + + + + + + + + @foreach (var user in Model.Everyone) + { + + + + + } +
                                                                    IdEmail
                                                                    @user.Id@user.Email
                                                                    +``` + +启动程序,并以普通用户身份登录,尝试去访问一下 `/ManageUsers` 路径。你会见到这样的 拒绝访问 页面: + +![Access denied error](access-denied.png) + +这是因为注册用户不会自动获得 `Administrator` 这个角色。 + +### 创建一个测试用的管理员账号 + +出于显而易见的安全因素,对于任何人来说,都不能自主的注册成为一个管理员账号。事实上,Administrator 这个角色,在数据库中尚不存在。 + +你可以在该应用程序第一次启动的时候,将这个 Administrator 角色外加一个测试用的管理员账号添加到数据库中。向数据库添加初始数据的行为,被称为初始化,或者 **填充(seeding)** 数据库。 + +在项目的根目录创建一个新类,取名为 `SeedData`: + +**SeedData.cs** + +```csharp +using System; +using System.Linq; +using System.Threading.Tasks; +using AspNetCoreTodo.Models; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace AspNetCoreTodo +{ + public static class SeedData + { + public static async Task InitializeAsync( + IServiceProvider services) + { + var roleManager = services + .GetRequiredService>(); + await EnsureRolesAsync(roleManager); + + var userManager = services + .GetRequiredService>(); + await EnsureTestAdminAsync(userManager); + } + } +} +``` + +`InitializeAsync()` 方法使用一个 `IServiceProvider`(在`Startup.ConfigureServices()`方法中设置过的服务集合)从 ASP.NET Core Identity 中获取`RoleManager`和`UserManager`。 + +在`InitializeAsync()`方法下面再添加两个方法,第一个,`EnsureRolesAsync()`方法: + +```csharp +private static async Task EnsureRolesAsync( + RoleManager roleManager) +{ + var alreadyExists = await roleManager + .RoleExistsAsync(Constants.AdministratorRole); + + if (alreadyExists) return; + + await roleManager.CreateAsync( + new IdentityRole(Constants.AdministratorRole)); +} +``` + +此方法查看数据库里是否存在一个 `Administrator` 角色。如果没有,它就创建一个。为免反复地输入字符串 `"Administrator"`,创建一个名为 `Constants` 的小类以保存它的值: + +**Constants.cs** + +```csharp +namespace AspNetCoreTodo +{ + public static class Constants + { + public const string AdministratorRole = "Administrator"; + } +} +``` + +> 如果你愿意,也可以修改之前创建的 `ManageUsersController` 使用这个常量值。 + +接下来是 `EnsureTestAdminAsync()` 方法: + +**SeedData.cs** + +```csharp +private static async Task EnsureTestAdminAsync( + UserManager userManager) +{ + var testAdmin = await userManager.Users + .Where(x => x.UserName == "admin@todo.local") + .SingleOrDefaultAsync(); + + if (testAdmin != null) return; + + testAdmin = new ApplicationUser + { + UserName = "admin@todo.local", + Email = "admin@todo.local" + }; + await userManager.CreateAsync( + testAdmin, "NotSecure123!!"); + await userManager.AddToRoleAsync( + testAdmin, Constants.AdministratorRole); +} +``` + +如果数据库里不存在一个用户名为 `admin@todo.local` 的用户,这个方法将创建它并给它一个临时的密码。在你初次登录之后,就应该改为一个更安全的密码。 + +接下来,你需要提醒你的程序,在它启动的时候,执行这个逻辑。修改`Program.cs`,并更新`Main()`去调用一个新的方法`InitializeDatabase()`: + +**Program.cs** + +```csharp +public static void Main(string[] args) +{ + var host = BuildWebHost(args); + InitializeDatabase(host); + host.Run(); +} +``` + +然后,在`Main()`的下面添加这个新方法: + +```csharp +private static void InitializeDatabase(IWebHost host) +{ + using (var scope = host.Services.CreateScope()) + { + var services = scope.ServiceProvider; + + try + { + SeedData.InitializeAsync(services).Wait(); + } + catch (Exception ex) + { + var logger = services + .GetRequiredService>(); + logger.LogError(ex, "Error occurred seeding the DB."); + } + } +} +``` + +并把这个 `using` 语句添加到文件顶部: + +```csharp +using Microsoft.Extensions.DependencyInjection; +``` + +此方法获取`SeedData.InitializeAsync()`所需的服务集合,然后执行它以便初始化数据库。如果出现错误,将会记录一条错误日志。 + +> 因为`InitializeAsync()`返回一个 `Task`,就必须使用 `Wait()` 方法以确保它在应用程序启动前完成。你一般是用 `await` 做这件事,但是因为某些技术原因,你无法在 `Program` 方法中使用 `await`。这是个罕见的例外 —— 所有其它地方你都应该用 `await`! + +当你再次启动程序,`admin@todo.local` 这个账号会被创建并被赋予 Administrator 角色。请尝试用这个账号登录,并浏览位于 `http://localhost:5000/ManageUsers` 的页面,你将看到一个列表,列出了本程序的所有注册用户。 + +> 作为练习,请在这个页面添加更多管理功能特性。例如,添加一个按钮,为管理员提供 删除一个用户 的功能。 + +### 在视图里查看认证状态 + +`[Authorize]` 属性让控制器里执行认证操作变得很方便,但是如果你需要在视图里进行认证操作呢?比如,在导航条上为登入的管理员用户显示一个“管理用户”的链接。 + +你可以把 `UserManager` 直接注入到视图里来进行这些操作。为保持你视图整洁有序,创建一个新的局部视图(partial view),以便在布局中的导航条里添加一个项目: + +**Views/Shared/_AdminActionsPartial.cshtml** + +```html +@using Microsoft.AspNetCore.Identity +@using AspNetCoreTodo.Models + +@inject SignInManager signInManager +@inject UserManager userManager + +@if (signInManager.IsSignedIn(User)) +{ + var currentUser = await userManager.GetUserAsync(User); + + var isAdmin = currentUser != null + && await userManager.IsInRoleAsync( + currentUser, + Constants.AdministratorRole); + + if (isAdmin) + { +
                                                                    + } +} +``` + +> 按惯例,通常把局部视图的名字以 `_` 下划线开始,但这不是强制性的。 + +这个局部视图首先使用 `SignInManager` 判断用户是否已经登录。如果没有登录,其余的代码就都被跳过。如果这 **是** 个已登录用户,`UserManager` 就被用于查找用户详细信息,并用 `IsInRoleAsync()` 进行认证检查。如果所有检查都通过了,并且该用户是一个管理员,导航条上就会加入一个 **Manage Users** 链接。 + +要在主布局中包含这个局部视图,编辑 `_Layout.cshtml` 并在导航条部分添加: + +**Views/Shared/_Layout.cshtml** + +```html + +``` + +如果你用管理员账号登录,将在右上角见到一个新的导航项: + +![Manage Users link](manage-users.png) + +--- + ## Authorization with roles Roles are a common approach to handling authorization and permissions in a web application. For example, it's common to create an Administrator role that gives admin users more permissions or power than normal users. @@ -183,7 +530,7 @@ private static async Task EnsureRolesAsync( { var alreadyExists = await roleManager .RoleExistsAsync(Constants.AdministratorRole); - + if (alreadyExists) return; await roleManager.CreateAsync( diff --git a/chapters/security-and-identity/more-resources.md b/chapters/security-and-identity/more-resources.md index f00afe7..78e76cf 100644 --- a/chapters/security-and-identity/more-resources.md +++ b/chapters/security-and-identity/more-resources.md @@ -1,3 +1,21 @@ +## 附加资源 + +ASP.NET Core Identity 帮助你添加诸如 登录、注册 这些安全及身份鉴别的特性到程序里。`dotnet new` 指定的模板带给你预先构建好的视图和控制器,用以处理这些常见情景,以便你快速上手和运行。 + +ASP.NET Core Identity 还有很多其它功能,例如密码重置以及社交账户登录。位于 http://docs.asp.net 的文档非常适合用来学习这些特性。 + +### ASP.NET Core Identity 的替代品 + +ASP.NET Core Identity 并非添加身份鉴别的唯一方式。另外一种选择是使用诸如 Azure Active Directory 以及 Okta 这种云端的服务为你的程序处理身份验证。你可以把这些选项看作发展的各个环节: + +* **自己处理安全性**:不推荐,除非你是一个安全性方面的专家! +* **ASP.NET Core Identity**:你免费获得随模板而来的大量代码,易于上手。对于进阶的情形,你依然需要写一部分代码,并维护一个数据库以存储用户信息。 +* **基于云的身份鉴别服务**:这种服务既处理简单情况也处理复杂情况(多步验证、账号找回,),并且能极大地缩减你需要编写的代码量,和维护程序的工作量。另外,用户数据的敏感部分并不会保存在你的数据库里。 + +在本项目里,ASP.NET Core Identity 非常适合。对于更复杂的项目,我建议对各选项都作一些研究和尝试,以便找到你所需的最佳方案。 + +--- + ## More resources ASP.NET Core Identity helps you add security and identity features like login and registration to your application. The `dotnet new` templates give you pre-built views and controllers that handle these common scenarios so you can get up and running quickly. diff --git a/chapters/security-and-identity/require-authentication.md b/chapters/security-and-identity/require-authentication.md index 664e175..4652313 100644 --- a/chapters/security-and-identity/require-authentication.md +++ b/chapters/security-and-identity/require-authentication.md @@ -1,3 +1,29 @@ +## 提示认证 + +在用户访问你程序中某些特定内容时,你通常都会要求他们登录。比如说,把主页向所有人展示是合理的(不管你有没有登录),但只在登录之后才向你展示待办事项列表。 + +ASP.NET Core 里,你可以使用 `[Authorize]` 属性,要求用户在访问指定的 action 或整个控制器时,要事先登录过。要为 `TodoController` 里的所有 action 添加认证提示,在这个控制器的第一行上面添加这个属性: + +```csharp +[Authorize] +public class TodoController : Controller +{ + // ... +} +``` + +在文件顶部添加这条 `using` 语句: + +```csharp +using Microsoft.AspNetCore.Authorization; +``` + +试着运行程序并在未登录的情况下访问 `/todo`。你会被自动重定向到登录页面: + +> 尽管属性的名字是授权(Authorize),我们在这里检查的其实是认证(authorization),而非检查授权,很抱歉会有这样的混淆。 + +--- + ## Require authentication Often you'll want to require the user to log in before they can access certain parts of your application. For example, it makes sense to show the home page to everyone (whether you're logged in or not), but only show your to-do list after you've logged in. diff --git a/chapters/security-and-identity/using-identity-in-the-application.md b/chapters/security-and-identity/using-identity-in-the-application.md index d896ace..6713544 100644 --- a/chapters/security-and-identity/using-identity-in-the-application.md +++ b/chapters/security-and-identity/using-identity-in-the-application.md @@ -1,3 +1,231 @@ +## 在程序中使用身份 + +待办事项列表依然由所有用户共享,因为 待办事项条目 并未关联到特定的用户。现在,`[Authorize]` 属性确保了见到 待办事项视图 的人一定登录过,在查询数据库的时候,你就可以按照登录者的身份进行过滤了。 + +首先,在 `TodoController` 中注入一个 `UserManager`: + +**Controllers/TodoController.cs** + +```csharp +[Authorize] +public class TodoController : Controller +{ + private readonly ITodoItemService _todoItemService; + private readonly UserManager _userManager; + + public TodoController(ITodoItemService todoItemService, + UserManager userManager) + { + _todoItemService = todoItemService; + _userManager = userManager; + } + + // ... +} +``` + +还要在文件顶部加一个新的 `using` 语句: + +```csharp +using Microsoft.AspNetCore.Identity; +``` + +`UserManager` 包含在 ASP.NET Core Identity 里。你可以用它在 `Index` action 里查找当前用户: + +```csharp +public async Task Index() +{ + var currentUser = await _userManager.GetUserAsync(User); + if (currentUser == null) return Challenge(); + + var items = await _todoItemService + .GetIncompleteItemsAsync(currentUser); + + var model = new TodoViewModel() + { + Items = items + }; + + return View(model); +} +``` + +这个 action 方法的顶部添加了新代码,这行代码用 `UserManager` 从 `User` 属性中获取当前登录的用户——该属性在当前的 action 中有效: + +```csharp +var currentUser = await _userManager.GetUserAsync(User); +``` + +如果当前用户已经登录, `User` 属性就持有一个轻量级的对象,包括了用户的一些(并非全部)信息。`UserManager` 使用它,通过 `GetUserAsync()` 方法在数据库里查找该用户的详细信息。 + +因为控制器使用了 `[Authorize]` 属性,`currentUser` 的值绝不应该是 null。无论如何,做个明智的检查都没错,以防万一嘛。如果用户信息没找到,你可以用 `Challenge()` 方法强制用户再次登录: + +```csharp +if (currentUser == null) return Challenge(); +``` + +既然你现在把一个 `ApplicationUser` 参数传给了 `GetIncompleteItemsAsync()`,就该修改 `ITodoItemService` 接口了: + +**Services/ITodoItemService.cs** + +```csharp +public interface ITodoItemService +{ + Task GetIncompleteItemsAsync( + ApplicationUser user); + + // ... +} +``` + +而既然你修改了 `ITodoItemService` 接口,也就同样需要修改 `TodoItemService` 中 `GetIncompleteItemsAsync()` 方法的签名: + +**Services/TodoItemService** + +```csharp +public async Task GetIncompleteItemsAsync( + ApplicationUser user) +``` + +下一步是修改数据库查询,并添加一层过滤,仅显示当前用户创建的条目。但在做这些之前,你需要在数据库里添加一个新的字段。 + +### 修改数据库 + +你需要在 `TodoItem` 实体上添加一个新的属性,让每个条目都能够“记住”拥有它的用户: + +**Models/TodoItem.cs** + +```csharp +public string UserId { get; set; } +``` + +既然你修改了数据库上下文里的实体模型,就应该同步修改数据库。在终端窗口里用 `dotnet ef` 指令创建一个新的变更: + +``` +dotnet ef migrations add AddItemUserId +``` + +这个命令新建了一个名为 `AddItemUserId` 的变更,它将给 `Items` 表新添一个列,以反映你在 `TodoItem` 实体模型上所做的修改: + +再通过 `dotnet ef` 指令应用到数据库: + +``` +dotnet ef database update +``` + +### 修改服务类 + +修改了数据库和数据库上下文,你就可以修改 `TodoItemService` 里的 `GetIncompleteItemsAsync()` 方法和其中的 `Where` 查询子句了: + +**Services/TodoItemService.cs** + +```csharp +public async Task GetIncompleteItemsAsync( + ApplicationUser user) +{ + return await _context.Items + .Where(x => x.IsDone == false && x.UserId == user.Id) + .ToArrayAsync(); +} +``` + +如果你现在运行程序并注册或者登录,你将又一次见到一个空的 待办事项列表。糟糕的是,你尝试添加的任何条目也都会凭空消失,因为你还没修改 添加条目 的操作,并把用户信息存储到条目里: + +### 修改 添加条目 和 完成事项 操作 + +你需要在 `AddItem` 和 `MarkDone` 这两个 action 的方法里,使用 `UserManager` 以获取当前用户,如同在 `Index` 里那样。 + +下面是 `TodoController` 控制器里对这两个方法的修改: + +**Controllers/TodoController.cs** + +```csharp +[ValidateAntiForgeryToken] +public async Task AddItem(TodoItem newItem) +{ + if (!ModelState.IsValid) + { + return RedirectToAction("Index"); + } + + var currentUser = await _userManager.GetUserAsync(User); + if (currentUser == null) return Challenge(); + + var successful = await _todoItemService + .AddItemAsync(newItem, currentUser); + + if (!successful) + { + return BadRequest("Could not add item."); + } + + return RedirectToAction("Index"); +} + +[ValidateAntiForgeryToken] +public async Task MarkDone(Guid id) +{ + if (id == Guid.Empty) + { + return RedirectToAction("Index"); + } + + var currentUser = await _userManager.GetUserAsync(User); + if (currentUser == null) return Challenge(); + + var successful = await _todoItemService + .MarkDoneAsync(id, currentUser); + + if (!successful) + { + return BadRequest("Could not mark item as done."); + } + + return RedirectToAction("Index"); +} +``` + +这两个服务方法现在也必须接受 `ApplicationUser` 参数了,修改 `ITodoItemService` 里定义的接口: + +```csharp +Task AddItemAsync(NewTodoItem newItem, ApplicationUser user); + +Task MarkDoneAsync(Guid id, ApplicationUser user); +``` + +最后,修改 `TodoItemService` 里面的实现方法。在 `AddItemAsync` 方法里,构造一个 `new TodoItem` 的时候,设置 `UserId` 属性: + +```csharp +public async Task AddItemAsync( + TodoItem newItem, ApplicationUser user) +{ + newItem.Id = Guid.NewGuid(); + newItem.IsDone = false; + newItem.DueAt = DateTimeOffset.Now.AddDays(3); + newItem.UserId = user.Id; + + // ... +} +``` + +`MarkDoneAsync` 方法里的 `Where` 查询子句也需要检查用户的 ID,以防止恶意的用户通过猜测 ID 的方法把其他用户的事项标记为完成状态。 + +```csharp +public async Task MarkDoneAsync( + Guid id, ApplicationUser user) +{ + var item = await _context.Items + .Where(x => x.Id == id && x.UserId == user.Id) + .SingleOrDefaultAsync(); + + // ... +} +``` + +搞定!请用两个不同的账号尝试一下。待办事项条目现在是每个账户的私密信息了。 + +--- + ## Using identity in the application The to-do list items themselves are still shared between all users, because the stored to-do entities aren't tied to a particular user. Now that the `[Authorize]` attribute ensures that you must be logged in to see the to-do view, you can filter the database query based on who is logged in. diff --git a/chapters/use-a-database/README.md b/chapters/use-a-database/README.md index 6b006f5..7c9e1d6 100644 --- a/chapters/use-a-database/README.md +++ b/chapters/use-a-database/README.md @@ -1,3 +1,15 @@ +# 运用数据库 + +与数据库交互的代码写起来坑很多。除非你对其了如指掌,否则在程序代码里粘贴 SQL 查询字符串就是个糟糕的决定。一个 **对象-关系 映射(object-relational mapper)** (ORM)在你的代码和数据库之间添加一个抽象层,并以此简化了与数据库交互代码的编写。Java 中的 Hibernate 和 Ruby 中的 ActiveRecord 就是广为人知的 ORM。 + +.NET 上有多个 ORM,其中有一个由微软开发,并默认包含在 ASP.NET Core 中,这就是 Entity Framework Core。Entity Framework Core 支持多个不同类型的数据库,并允许你使用 C# 代码创建数据库查询语句,查询结果映射回 C# 模型(POCO)。 + +> 还记得创建服务接口以解耦控制器和服务的实现类吗?Entity Framework Core 就像一个数据库上的大型接口。你的 C# 代码可以于具体的数据库实现无关,你可以根据底层以来的数据库技术更换不同的 provider。 + +Entity Framework Core 可以连接到 SQL Server、PostgreSQL 和 MySQL 这种关系型数据库,也可以与 Mongo 这种 NoSQL(文档) 数据库协作。在本项目的开发过程中,你将使用一个 SQLite 数据库,以简化安装和配置的工作。 + +--- + # Use a database Writing database code can be tricky. Unless you really know what you're doing, it's a bad idea to paste raw SQL query strings into your application code. An **object-relational mapper** (ORM) makes it easier to write code that interacts with a database by adding a layer of abstraction between your code and the database itself. Hibernate in Java and ActiveRecord in Ruby are two well-known ORMs. diff --git a/chapters/use-a-database/connect-to-a-database.md b/chapters/use-a-database/connect-to-a-database.md index e50ca18..fb7c476 100644 --- a/chapters/use-a-database/connect-to-a-database.md +++ b/chapters/use-a-database/connect-to-a-database.md @@ -1,3 +1,29 @@ +## 连接数据库 + +通过 Entity Framework Core 连接数据库,需要做一些准备工作。因为你通过 `dotnet new` 让项目使用了 MVC + Individual认证 项目模板,这些准备已经就绪了: + +* **Entity Framework Core包** 这些都默认包括在了所有 ASP.NET Core 项目中。 + +* **数据库**(必须地呀) 经由 `dotnet new` 指令,在项目的根目录下生成了小型的 SQLite 数据库文件 `app.db`。 SQLite 是一个轻量级数据库引擎,可以运行在你的机器上而不必安装任何额外工具,所以在开发环境下使用起来既方便又快捷。 + +* **数据库上下文** 数据库上下文(database context)是一个 C# 类提供的数据库入口点。 你的代码就是通过它与数据库交互,进行读写的。`Data/ApplicationDbContext.cs` 文件里,就保存着一个很基本的数据库上下文。 + +* **连接字符串** 无论你连接本地文件数据库(SQLite)还是位于其它主机的数据库,都需要定义一个字符串,其中包含 数据库的名字 或 用来连接的数据库地址。 这一项已经在 `appsettings.json` 文件里为你设置好了: SQLite 数据库的 连接字符串 是 `DataSource=app.db`。 + +Entity Framework Core 借助 数据库上下文、连接字符串 与数据库建立连接。你需要在 `Startup` 类里的 `ConfigureServices` 方法中为 Entity Framework Core 指定所用的 数据库上下文、连接字符串和数据库类型。感谢项目模板: + +```csharp +services.AddDbContext(options => + options.UseSqlite( + Configuration.GetConnectionString("DefaultConnection"))); +``` + +这段代码把 `ApplicationDbContext` 添加到服务容器里,并通过配置(`appsettings.json`)中的 连接字符串 指定 Entity Framework Core 使用 SQLite 数据库。 + +如你所见,`dotnet new` 为你完成了很多工作! 数据库已经配置好待用了。但是还没有表用于保存 待办事项条目。为了能存储 `TodoItem` 实体,你需要修改数据库上下文,并对数据库进行变更。 + +--- + ## Connect to a database There are a few things you need to use Entity Framework Core to connect to a database. Since you used `dotnet new` and the MVC + Individual Auth template to set your project, you've already got them: diff --git a/chapters/use-a-database/create-migration.md b/chapters/use-a-database/create-migration.md index 993e219..481ba5e 100644 --- a/chapters/use-a-database/create-migration.md +++ b/chapters/use-a-database/create-migration.md @@ -1,3 +1,98 @@ +## 创建变更 + +变更按时间记录着数据库结构的变化。它们使以下的操作成为可能:撤销(回滚)一部分修改,或创建一个新的数据库——与原有数据库结构一致。有了变更,你有一个完整的数据库历史,记录着对数据库的修改,例如添加或删除字段(以及整个表)。 + +上一章节里,你在数据库上下文里添加了一个 Items 集合。既然现在数据库上下文里包括了一个集合(或者说表),而数据库里没有它,你就需要创建一个变更来修改数据库: + +``` +dotnet ef migrations add AddItems +``` + +这行代码通过检查你在数据库上下文里所做的修改,创建了一个新的变更,名为 `AddItems`。 + +> 如果你看到这样的报错: `No executable found matching command "dotnet-ef"`,请确保在正确的目录下。 这些命令必须在项目的根目录下执行(`Program.cs`所在目录)。 + +> 译者注:如果你使用 3.0 或以上版本的 SDK,需要手动安装 `dotnet-ef` 工具,原因请参考 [dotnet ef not found in .NET Core 3](https://stackoverflow.com/questions/57066856/dotnet-ef-not-found-in-net-core-3),使用如下命令进行安装。 + +```shell +dotnet tool install --global dotnet-ef +``` + +如果你打开 `Data/Migrations` 目录,你将会看到: + +![Multiple migrations](migrations.png) + +第一个变更文件(`00_CreateIdentitySchema.cs`),是在你执行 `dotnet new` 的时候创建并应用的。 变更 `AddItem` 带有你创建它时候的时间戳。 + +> 你可以用 `dotnet ef migrations list` 命令查看一个变更的列表。 + +如果你打开一个变更文件,可以看到两个方法,名字分别是 `Up` 和 `Down`: + +**Data/Migrations/_AddItems.cs** + +```csharp +protected override void Up(MigrationBuilder migrationBuilder) +{ + // (... some code) + + migrationBuilder.CreateTable( + name: "Items", + columns: table => new + { + Id = table.Column(nullable: false), + DueAt = table.Column(nullable: true), + IsDone = table.Column(nullable: false), + Title = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Items", x => x.Id); + }); + + // (some code...) +} + +protected override void Down(MigrationBuilder migrationBuilder) +{ + // (... some code) + + migrationBuilder.DropTable( + name: "Items"); + + // (some code...) +} +``` + +将变更应用到数据库时 `Up` 方法将会被执行。因为你在数据库上下文里添加了一个 `DbSet` ,应用变更时 Entity Framework Core 会创建一个 `Items` 表(其列与 `TodoItem` 相匹配)。 + + `Down` 方法刚好相反:当你需要撤销(回滚)变更时,`Items` 表将会被丢弃。 + +### 绕开 SQLite 的局限性 + +如果你按原样执行变更,会遭遇 SQLite 数据库的局限性带来的问题,要修复它,可以这样绕开: + +* 在 `Up` 方法里注释掉或删除 `migrationBuilder.AddForeignKey` 那些行。 +* 在 `Down` 方法里注释掉或删除 `migrationBuilder.DropForeignKey` 那些行。 + +如果你使用完善的数据库,如 SQL Server 或者 MySQL,就不需要这样(有点旁门左道的)绕弯了。 + +### 应用变更 + +创建变更的最后一步,就是要应用它(们)到数据库中: + +``` +dotnet ef database update +``` + +这条命令会导致 Entity Framework Core 在数据库中创建 `Items` 表。 + +> 如果你想回滚数据库,你可以提供 *上一个* 迁移的名称:`dotnet ef database update CreateIdentitySchema` 这将运行所有迟于你指定变更的 `Down` 方法。 +如果你需要完整的抹掉数据库并重新开始,运行 `dotnet ef database drop` 然后运行 `dotnet ef database update`,重新搭建数据库并应用到到当前的变更。 + +搞定! 数据库和上下文都已就绪。接下来,你将在服务层使用上下文。 + +--- + ## Create a migration Migrations keep track of changes to the database structure over time. They make it possible to undo (roll back) a set of changes, or create a second database with the same structure as the first. With migrations, you have a full history of modifications like adding or removing columns (and entire tables). diff --git a/chapters/use-a-database/create-service-class.md b/chapters/use-a-database/create-service-class.md index 655e70a..7bd8b64 100644 --- a/chapters/use-a-database/create-service-class.md +++ b/chapters/use-a-database/create-service-class.md @@ -1,3 +1,93 @@ +## 创建服务类 + +回顾 *MVC基础* 章节, 你创建了一个 `FakeTodoItemService`,其中包含硬编码的 待办事项。现在你有了数据库上下文,就可以创建一个新的服务类,从而借助 Entity Framework Core 从数据库中获取真实内容。 + +删除文件 `FakeTodoItemService.cs`,并创建一个新文件: + +**Services/TodoItemService.cs** + +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AspNetCoreTodo.Data; +using AspNetCoreTodo.Models; +using Microsoft.EntityFrameworkCore; + +namespace AspNetCoreTodo.Services +{ + public class TodoItemService : ITodoItemService + { + private readonly ApplicationDbContext _context; + + public TodoItemService(ApplicationDbContext context) + { + _context = context; + } + + public async Task GetIncompleteItemsAsync() + { + var items = await _context.Items + .Where(x => x.IsDone == false) + .ToArrayAsync(); + return items; + } + } +} +``` + +你应该注意到相同的依赖注入模式,如你在 *MVC基础* 章节所见到的那样,只是这次被注入的服务是 `ApplicationDbContext`。`ApplicationDbContext` 已经在`ConfigureServices` 方法里被添加到服务容器里,所以在这里可以直接使用。 + +让我们仔细探究 `GetIncompleteItemsAsync` 方法的代码。首先,它用数据库上下文中的 `Items` 的属性获取 `DbSet` 中所有的 待办事项: + +```csharp +var items = await _context.Items +``` + +然后,`Where` 用于过滤出所有“未完成”的条目: + +```csharp +.Where(x => x.IsDone == false) +``` + +`Where` 方法来自 C# 里的一个名为 `LINQ`(**l**anguage **in**tegrated **q**uery) 的特性,它受到函数式编程的启发,简化了在程序代码里数据库查询的写法。在底层,Entity Framework Core 把这个方法翻译成一个类似的语句 `SELECT * FROM Items WHERE IsDone = 0`,或在 NoSQL数据库 里的一个等效查询。 + +最后,`ToArrayAsync` 方法吩咐 Entity Framework Core 取出所有过滤后的数据,并作为一个数组返回。`ToArrayAsync` 是异步的(返回一个 `Task`),所以必须执行一次 `await`(等待) 以获取其中的值。 + +如果想使这个方法变简短一点,你可以删除中间变量 `items`,直接返回查询结果(跟原来功能一样): + +```csharp +public async Task GetIncompleteItemsAsync() +{ + return await _context.Items + .Where(x => x.IsDone == false) + .ToArrayAsync(); +} +``` + +### 修改服务容器 + +由于你删除了 `FakeTodoItemService` 类,就需要修改 `ConfigureServices` 方法里配置`ITodoItemService` 接口的那一行: + +```csharp +services.AddScoped(); +``` + +`AddScoped` 会以 **scoped** 的生命周期把你的服务添加到容器里。这意味着每次 web 请求中,一个 `TodoItemService` 类的新实例就会被创建出来。这对于那些跟数据库打交道的类来说,是必要的。 + +> 添加一个服务类去跟 Entity Framework Core(以及你的数据库)打交道,如果用单件(或其它)生命周期会引发麻烦,原因在于 Entity Framework Core 底层以请求为单位管数据库连接。要避免这些问题,请在跟 Entity Framework Core 打交道的服务上,始终采用 scoped 生命周期。 + +依赖于被注入的 `ITodoItemService` 的 `TodoController` 将幸福地对这个变化毫无察觉,但在底层,你将使用 Entity Framework Core 与真实的数据库进行交互! + +### 试试看 + +启动程序并导航至 `http://localhost:5000/todo`。硬编码的那些条目不见了,你的程序对数据库发起了真正的查询。数据库里刚好还没有任何已存的 待办事项条目,所以页面目前还是空白的。 + +下一章,你将在程序中添加更多的功能,从“创建新 待办事项 的能力”开始。 + +--- + ## Create a new service class Back in the *MVC basics* chapter, you created a `FakeTodoItemService` that contained hard-coded to-do items. Now that you have a database context, you can create a new service class that will use Entity Framework Core to get the real items from the database. diff --git a/chapters/use-a-database/update-context.md b/chapters/use-a-database/update-context.md index 44772f2..c0a26a9 100644 --- a/chapters/use-a-database/update-context.md +++ b/chapters/use-a-database/update-context.md @@ -1,3 +1,51 @@ +## 修改数据库上下文 + +数据库上下文这边所需的工作不多: + +**Data/ApplicationDbContext.cs** + +```csharp +public class ApplicationDbContext + : IdentityDbContext +{ + public ApplicationDbContext( + DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + // ... + } +} +``` + +在构造函数的下方,为 `ApplicationDbContext` 添加一个 `DbSet` 属性: + +```csharp +public ApplicationDbContext( + DbContextOptions options) + : base(options) +{ +} + +public DbSet Items { get; set; } + +// ... +``` + +`DbSet` 代表数据库里的 表 或者 集合。创建一个名为 `Items` 的 `DbSet` 属性,可以让 Entity Framework Core 知道,你需要在一个名为 `Items` 的表里保存 `TodoItem` 实体。 + +你修改了 数据库上下文 的类,却产生了一个小问题: 现在上下文和数据库不同步了,因为数据库里实际上并不存在 `Items` 这个表。(对数据库上下文代码的修改,并不会改变数据库本身。) + +为了把“数据库上下文中的改动”反映到数据库里,你需要创建一个 **变更(migration)**。 + +> 如果你已经有一个现存的数据库,请在网络上搜索“scaffold-dbcontext existing database”相关的内容,并阅读微软的关于使用 `Scaffold-DbContext` 工具的文档,以此对你的数据库进行逆向工程,自动地为数据库结构生成相应的 `DbContext` 和模型类。 + +--- + ## Update the context There's not a whole lot going on in the database context yet: diff --git a/chapters/your-first-application/README.md b/chapters/your-first-application/README.md index 1a9393b..b70d896 100644 --- a/chapters/your-first-application/README.md +++ b/chapters/your-first-application/README.md @@ -1,3 +1,17 @@ +# 你的第一个程序 + +准备好创建你的第一个 ASP.NET Core web 应用了么?先做点“利其器”的事: + +**你惯用的代码编辑器** 你可以用 Atom、Sublime、Notepad 或者任何你喜欢的编辑器。如果你还没有一个惯用的,请试试 Visual Studio Code。这是个免费、跨平台的代码编辑器,对于 C#、JavaScript、HTML 和很多其它语言编程的支持非常丰富。只需要搜索“下载 visual studio code”再按指令操作即可。(译者的话:别用 百度,试试 [bing.com](https://www.bing.com)) + +如果你在 Windows 下,也可以用 Visual Studio 构建 ASP.NET Core 应用程序。这需要用到 Visual Studio 2017 的 15.3 及以上的版本(免费的社区版就够用了)。Visual Studio 有着优秀的 代码补全 和 C# 的代码重构,且略优于 Visual Studio Code。 + +**.NET Core SDK** 不论你用什么编辑器或者平台,都需要安装 .NET Core SDK,包括运行时,基础库以及用于构建 ASP.NET Core 应用程序的命令行工具。它可以安装在 Windows、Mac、Linux上。 + +选定了编辑器,就该去获取 SDK 了。 + +--- + # Your first application Ready to build your first web app with ASP.NET Core? You'll need to gather a few things first: diff --git a/chapters/your-first-application/create-aspnetcore-project.md b/chapters/your-first-application/create-aspnetcore-project.md index 80d4751..820cb18 100644 --- a/chapters/your-first-application/create-aspnetcore-project.md +++ b/chapters/your-first-application/create-aspnetcore-project.md @@ -1,3 +1,87 @@ +## 创建一个 ASP.NET Core 项目 + +如果你还在 Hello World 示例的那个目录里,请退回到 我的文档 或者 home 目录: + +```shell +cd .. +``` + +接下来,创建一个新目录以保存你的整个项目,然后进到该目录里: + +```shell +mkdir AspNetCoreTodo +cd AspNetCoreTodo +``` + +接下来,使用 `dotnet new` 创建一个新项目,这一次添加几个选项: + +```shell +dotnet new mvc --auth Individual -o AspNetCoreTodo +cd AspNetCoreTodo +``` + +这个命令,使用 `mvc` 模板创建了一个新的项目,并添加了一些额外的验证和安全性相关的内容。(关于安全性的内容,我会在 *安全性与身份* 一章讲解。) + +> 你可能有点疑惑,为什么在一个 `AspNetCoreTodo` 目录里弄另一个 `AspNetCoreTodo` 目录。这个顶层或者说“根”目录可以容纳一个或多个项目目录。根目录有时候被称为 **解决方案目录**。后面,你将会在 `AspNetCoreTodo` 项目目录边上添加多个项目目录,它们全都在一个单一的根解决方案目录里。 + +在这个新的项目目录里,你会发现多出来几个文件。在你 `cd` 到新目录里之后,就只需要运行这个项目了: + +```shell +dotnet run + +Now listening on: http://localhost:5000 +Application started. Press Ctrl+C to shut down. +``` + +这个程序不再打印到控制台后直接退出,而是启动了一个 web 服务器,并在端口 5000 上等待访问请求。 + +开启你的网络浏览器,浏览 `http://localhost:5000`。你将看到 ASP.NET Core 程序的默认欢迎页面,说明你的程序工作正常!看够了这个页面之后,在终端窗口内按下 Ctrl-C 以便停止这个服务器。 + +### 一个 ASP.NET Core 项目的各部分 + +`dotnet new mvc` 模板为你生成了多个文件和目录。在默认创建的基本内容里,这几个是最重要的: + +* **Program.cs** 和 **Startup.cs** 文件,设置 web 服务器和 ASP.NET Core 的处理管线。在 **Startup** 类里,你可以添加中间件,它们用于 处理和调整传入的请求、提供静态内容和错误页面。在这里,你还可以向依赖注入容器中添加你自己的服务(后面细说)。 + +* **Models**、**Views**,和 **Controllers**目录里放置着 模型-视图-控制器(MVC,Model-View-Controller)架构的组件。下一章,你将一探他们三者的究竟。 + +* **wwwroot** 目录里放着 CSS、JavaScript、图片文件 这些静态资源。`wwwroot` 里的文件将作为静态内容,自动被打包和压缩。 + +* **appsettings.json** 文件里包含着 ASP.NET Core 启动时读取的配置信息。你可以用它来保存数据库连接字符串,或者其它你不想硬编码的任何内容。 + +### Visual Studio Code 技巧 + +如果你是初次使用 Visual Studio Code(或者 Visual Studio),下面这几个有益的小技巧将帮你轻松上手: + +* **打开项目的根文件夹** : 在 Visual Studio Code 里,选择 文件 -> 打开文件夹。打开 `AspNetCoreTodo` 文件夹(根目录),不是内层的项目目录。如果 Visual Studio Code 提示你安装缺失的文件,点击“是”以添加它们。 + +* **用 F5 运行(并调试断点)**:使你的项目处于打开状态,按下 F5 以调试模式运行项目。这跟命令行的 `dotnet run` 功能相同,但有一个额外好处——你可以在代码编辑器的左边栏上点击,以设置一个断点: + + ![Visual Studio Code 中的断点](breakpoint.png) + +* **潜在问题的小灯泡提示**:如果你的代码里有红色波浪线(编译错误),把编辑的光标放在红线里,到左边栏里找那个小灯泡的图标,小灯泡的提示信息会给出常见问题的修改建议,比如在代码里添加一个 `using` 语句: + + ![小灯泡提示](lightbulb.png) + +* **快捷编译**:使用快捷键 `Command-Shift-B` 或者 `Control-Shift-B` 运行编译任务,这跟 `dotnet build` 的效果一样。 + +> 这些也可以用在 Widnows 版的 Visual Studio (不带 Code)。如果你用的是 Visual Studio,你需要直接打开 `.csproj` 项目文件所在的目录。 Visual Studio 后面会提示你保存解决方案文件,你应该把它保存在根目录(第一个 `AspNetCoreTodo` 文件夹)。你也可以在 Visual Studio 里使用模板直接创建 ASP.NET Core 项目,操作是 文件 > 新建 > 项目。 + +### Git 小贴士: + +如果你使用 Git 或者 GitHub 管理你的源码,眼下就是一个适合的时机,在项目目录下用 `git init` 来初始化你的 Git 仓库: + +```shell +cd .. +git init +``` + +请确保你添加了一个 `.gitignore` 文件用以忽略 `bin` 和 `obj` 这些目录。 GitHub 上 gitignore 模板仓库([https://github.com/github/gitignore](https://github.com/github/gitignore))里的 [Visual Studio gitignore](https://github.com/github/gitignore/blob/master/VisualStudio.gitignore) 模板就很好用。 + +还有很多值得研究的内容,让我们着手构建这个应用吧! + +--- + ## Create an ASP.NET Core project If you're still in the directory you created for the Hello World sample, move back up to your Documents or home directory: diff --git a/chapters/your-first-application/get-the-sdk.md b/chapters/your-first-application/get-the-sdk.md index c8c8932..99488a4 100644 --- a/chapters/your-first-application/get-the-sdk.md +++ b/chapters/your-first-application/get-the-sdk.md @@ -1,3 +1,35 @@ +## 获取 SDK + +搜索“下载 .net core”,在微软为你所在平台提供的下载页面,获取 .NET Core 的 SDK。完成 SDK 的安装后,开启一个终端窗口(或者 Windows 上的 PowerShell),并使用 `dotnet` 命令行工具(command line tool,也叫 **CLI**)确保一切正常工作: + +```shell +dotnet --version + +2.1.104 +``` + +还可以通过 `--info` 选项,获取你所在平台更详细的信息: + +```shell +dotnet --info + +.NET Command Line Tools (2.1.104) + +Product Information: + Version: 2.1.104 + Commit SHA-1 hash: 48ec687460 + +Runtime Environment: + OS Name: Mac OS X + OS Version: 10.13 + +(more details...) +``` + +如果你看到类似于上面的输出,就大步前进吧。 + +--- + ## Get the SDK Search for "download .net core" and follow the instructions on Microsoft's download page to get the .NET Core SDK. After the SDK has finished installing, open up the Terminal (or PowerShell on Windows) and use the `dotnet` command line tool (also called a **CLI**) to make sure everything is working: diff --git a/chapters/your-first-application/hello-world-in-csharp.md b/chapters/your-first-application/hello-world-in-csharp.md index fa38532..0e9a812 100644 --- a/chapters/your-first-application/hello-world-in-csharp.md +++ b/chapters/your-first-application/hello-world-in-csharp.md @@ -1,3 +1,73 @@ +## C# 版的 Hello World + +深入钻研 ASP.NET Core 之前,先试着创建并运行一个简单的应用程序吧。 + +这个可以在命令行下执行。首先开启一个终端窗口(或者 Windows 上的 PowerShell)。一路 `cd` 到要放置你项目的路径下,比如你的“我的文档”目录: + +```shell +cd Documents +``` + +使用 `dotnet` 命令创建一个新的项目: + +```shell +dotnet new console -o CsharpHelloWorld +``` + +`dotnet new` 指令默认会用 C# 创建一个 .NET 项目。参数 `console` 选择了一个命令行应用(一种向屏幕输出文本的程序)的模板。`-o CsharpHelloWorld` 参数指示 `dotnet new` 为项目的所有文件创建一个名为 `CsharpHelloWorld` 的目录。进入到这个新目录里: + +```shell +cd CsharpHelloWorld +``` + +`dotnet new console` 命令创建了一个基本的 C# 程序,它输出文本 `Hello World!` 到屏幕上。这个程序由两个文件构成:一个项目文件(使用 `.csproj` 扩展名)和一个 C# 源文件(带有 `.cs` 扩展名),打开前面那个文件的话,可以看到以下内容: + +**CsharpHelloWorld.csproj** + +```xml + + + + Exe + netcoreapp2.0 + + + +``` + +项目文件基于 XML,其中定义了一些关于项目的元数据。到后面,你引用其它包的时候,那些包将被记录在这里(类似于 npm 的 `package.json`),你不需要经常手动编辑这个文件。 + +**Program.cs** + +```csharp +using System; + +namespace CsharpHelloWorld +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} +``` + +`static void Main` 是 C# 程序的入口点方法,按照惯例,会被置于一个叫 `Program` 的类(一种代码结构或模块)里。最上面的 `using` 语句引入了 .NET 内置于 `System` 的那些类,以便在你的这个类里使用它们。 + +在项目的目录里,用 `dotnet run` 指令运行这个程序,在代码编译完成之后,你将看到输出在控制台里面的内容: + +```shell +dotnet run + +Hello World! +``` + +这就是构建一个 .NET 程序所需的全部!下一节,你将把同样的流程应用在一个 ASP.NET Core 程序上。 + +--- + ## Hello World in C# # Before you dive into ASP.NET Core, try creating and running a simple C# application. diff --git a/cover.jpg b/cover.jpg index c82a844..05bface 100644 Binary files a/cover.jpg and b/cover.jpg differ diff --git a/cover_3d.png b/cover_3d.png index 8b04c24..8821e03 100644 Binary files a/cover_3d.png and b/cover_3d.png differ diff --git a/cover_cn.pdn b/cover_cn.pdn new file mode 100644 index 0000000..1cc88c5 Binary files /dev/null and b/cover_cn.pdn differ diff --git a/cover_lulu.png b/cover_lulu.png index 6708b5d..5efe921 100644 Binary files a/cover_lulu.png and b/cover_lulu.png differ diff --git a/cover_small.jpg b/cover_small.jpg index 8527c67..f19e0e4 100644 Binary files a/cover_small.jpg and b/cover_small.jpg differ