Browse Source

Translating documents.

pull/1194/head
maliming 7 years ago
parent
commit
4f3f3a0bb2
  1. 2
      docs/docs-langs.json
  2. 4
      docs/zh-Hans/AspNetCore/Auto-API-Controllers.md
  3. 137
      docs/zh-Hans/CLI.md
  4. 3
      docs/zh-Hans/Data-Seeding.md
  5. 69
      docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md
  6. 92
      docs/zh-Hans/Index.md
  7. 8
      docs/zh-Hans/Startup-Templates/Index.md
  8. 6
      docs/zh-Hans/Startup-Templates/Mvc-Module.md
  9. 183
      docs/zh-Hans/Startup-Templates/Mvc.md
  10. 142
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md
  11. 66
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-II.md
  12. 89
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md
  13. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png
  14. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog.png
  15. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png
  16. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page.png
  17. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png
  18. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png
  19. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file.png
  20. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png
  21. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files.png
  22. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png
  23. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects.png
  24. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png
  25. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png
  26. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution.png
  27. 3
      docs/zh-Hans/Value-Types.md
  28. 4
      docs/zh-Hans/docs-nav.json
  29. BIN
      docs/zh-Hans/images/bookstore-user-management-v2.png
  30. BIN
      docs/zh-Hans/images/bookstore-user-management.png
  31. BIN
      docs/zh-Hans/images/bookstore-visual-studio-solution-v2.png
  32. BIN
      docs/zh-Hans/images/bookstore-visual-studio-solution-v3.png
  33. BIN
      docs/zh-Hans/images/bookstore-visual-studio-solution.png
  34. BIN
      docs/zh-Hans/images/db-migrator-app.png

2
docs/docs-langs.json

@ -6,7 +6,7 @@
"IsDefault": true
},
{
"DisplayName" : "Chinese",
"DisplayName" : "简体中文",
"Code" : "zh-Hans",
"IsDefault": false
}

4
docs/zh-Hans/AspNetCore/Auto-API-Controllers.md

@ -16,7 +16,9 @@ public class BookStoreWebModule : AbpModule
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(BookStoreApplicationModule).Assembly);
options
.ConventionalControllers
.Create(typeof(BookStoreApplicationModule).Assembly);
});
}
}

137
docs/zh-Hans/CLI.md

@ -0,0 +1,137 @@
# ABP CLI
ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions.
## Installation
ABP CLI is a [dotnet global tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools). Install it using a command line window:
````bash
dotnet tool install -g Volo.Abp.Cli
````
To update an existing installation:
````bash
dotnet tool update -g Volo.Abp.Cli
````
## Commands
### new
Generates a new solution based on the ABP [startup templates](Startup-Templates/Index.md).
Basic usage:
````bash
abp new <solution-name> [options]
````
Example:
````bash
abp new Acme.BookStore
````
* Acme.BookStore is the solution name here.
* Common convention is to name a solution is like *YourCompany.YourProject*. However, you can use different naming like *YourProject* (single level namespacing) or *YourCompany.YourProduct.YourModule* (three levels namespacing).
#### Options
* `--template` or `-t`: Specifies the template name. Default template name is `mvc`. Available templates:
* `mvc` (default): ASP.NET Core [MVC application template](Startup-Templates/Mvc.md). Additional options:
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
* `mvc-module`: ASP.NET Core [MVC module template](Startup-Templates/Mvc-Module.md). Additional options:
* `--no-ui`: Specifies to not include the UI. This makes possible to create service-only modules (a.k.a. microservices - without UI).
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
### add-package
Adds a new ABP package to a project by,
* Adding related nuget package as a dependency to the project.
* Adding `[DependsOn(...)]` attribute to the module class in the project (see the [module development document](Module-Development-Basics.md)).
> Notice that the added module may require additional configuration which is generally indicated in the documentation of the related package.
Basic usage:
````bash
abp add-package <package-name> [options]
````
Example:
````
abp add-package Volo.Abp.MongoDB
````
* This example adds the Volo.Abp.MongoDB package to the project.
#### Options
* `--project` or `-p`: Specifies the project (.csproj) file path. If not specified, CLI tries to find a .csproj file in the current directory.
### add-module
Adds a multi-package module to a solution by finding all packages of the module, finding related projects in the solution and adding each package to the corresponding project in the solution.
> A business module generally consists of several packages (because of layering, different database providr options or other reasons). Using `add-module` command dramatically simplifies adding a module to a solution. However, each module may require some additional configurations which is generally indicated in the documentation of the related module.
Basic usage:
````bash
abp add-module <module-name> [options]
````
Example:
```bash
abp add-module Volo.Blogging
```
* This example add the Volo.Blogging module to the solution.
#### Options
* `--solution` or `-s`: Specifies the solution (.sln) file path. If not specified, CLI tries to find a .sln file in the current directory.
* `--skip-db-migrations`: For EF Core database provider, it automatically adds a new code first migration (`Add-Migration`) and updates the database (`Update-Database`) if necessary. Specify this option to skip this operation.
### update
Updating all ABP related packages can be tedious since there are many packages of the framework and modules. This command automatically updates all ABP related packages in a solution or project to the latest versions.
Usage:
````bash
abp update [options]
````
* If you run in a directory with a .sln file, it updates all ABP related packages of the all projects of the solution to the latest versions.
* If you run in a directory with a .csproj file, it updates all ABP related packages of the project to the latest versions.
#### Options
* `--include-previews` or `-p`: Includes preview, beta and rc packages while checking the latest versions.
### help
Writes basic usage information of the CLI.
Usage:
````bash
abp help [command-name]
````
Examples:
````bash
abp help # Shows a general help.
abp help new # Shows help about the "new" command.
````

3
docs/zh-Hans/Data-Seeding.md

@ -0,0 +1,3 @@
# Data Seeding
TODO

69
docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md

@ -2,37 +2,42 @@
### 创建新项目
访问[模板创建页面](https://abp.io/Templates), 输入项目名称并创建项目, 如下所示:
本教程使用 **ABP CLI** 创建一个新项目. 更多选项, 请参阅[入门](https://cn.abp.io/get-started)页面.
![bookstore-create--template](images/bookstore-create-template.png)
如果你之前未安装,请使用命令行安装ABP CLI:
单击 *create* 按钮时,将使用你提供的名称创建一个新的Visual Studio解决方案并开始下载.
````bash
dotnet tool install -g Volo.Abp.Cli
````
在空文件夹中使用 `abp new` 命令来创建项目:
````
abp new Acme.BookStore
````
> 你可以使用不同级别的命名空间; 例如BookStore, Acme.BookStore或Acme.Retail.BookStore.
`new` 命令创建**分层MVC应用程序**, **Entity Framework Core**作为数据库提供程序. 但是,它还有其他选择. 有关所有可用选项,请参见[CLI文档](CLI.md)
#### 预先要求
下载的项目需要:
创建项目的要求:
* [Visual Studio 2017 (v15.9.0+)](https://visualstudio.microsoft.com/tr/downloads/)
* [.NET Core 2.1.1+](https://www.microsoft.com/net/download/dotnet-core/)
* [.NET Core 2.2+](https://www.microsoft.com/net/download/dotnet-core/)
### 解决方案结构
下载后解压文件并在 **Visual Studio 2017(15.7.0 +)** 中打开:
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
该解决方案具有分层结构(基于域驱动设计), 其中:
在**Visual Studio**中打开解决方案:
* ``.Domain`` 为领域层.
* ``.Application`` 为应用层.
* ``.Web`` 为是表示层.
* ``.EntityFrameworkCore`` 是EF Core集成.
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v3.png)
EF Core 数据库迁移被分离到名为`.EntityFrameworkCore.DbMigrations`项目中.
该解决方案具有分层结构(基于[Domain Driven Design](Domain-Driven-Design.md)), 并包含配置好的的单元&集成测试项目,可与**EF Core**和**SQLite**数据库内存一起使用.
解决方案还包含配置好的的单元&集成测试项目, 以便与 **EF Core****SQLite内存中** 数据库配合使用.
> 请参阅[MVC应用程序模板文档](Startup-Templates/Mvc.md)以详细了解解决方案结构.
### 创建数据库
### 数据库连接字符串
查看`.Web`项目下`appsettings.json`文件中的 **连接字符串**:
@ -44,9 +49,29 @@ EF Core 数据库迁移被分离到名为`.EntityFrameworkCore.DbMigrations`项
}
````
解决方案使用 **Entity Framework Core****MS SQL Server**. EF Core支持[各种](https://docs.microsoft.com/en-us/ef/core/providers/)数据库提供程序,因此你可以根据实际需要使用其他DBMS.
解决方案使用 **Entity Framework Core****MS SQL Server**. EF Core支持[各种](https://docs.microsoft.com/en-us/ef/core/providers/)数据库提供程序,因此你可以根据实际需要使用其他DBMS. 如果需要,请更改连接字符串.
### 创建数据库并应用数据库迁移
你有两个选项来创建数据库.
右键单击`.Web`项目并**设置启动项目**
#### 使用DbMigrator应用程序
该解决方案包含一个控制台应用程序(在此示例中名为`Acme.BookStore.DbMigrator`),可以创建数据库,应用迁移和初始化数据. 它对开发和生产环境都很有用.
> `.DbMigrator`项目有自己的`appsettings.json`. 因此,如果你更改了上面的连接字符串,则还应更改此字符串.
右键单击`.DbMigrator`项目并选择 **设置为启动项目**:
![set-as-startup-project](images/set-as-startup-project.png)
按F5(或Ctrl + F5)运行应用程序. 它将具有如下所示的输出:
![set-as-startup-project](images/db-migrator-app.png)
#### 使用EF Core Update-Database命令
Ef Core具有`Update-Database`命令, 可根据需要创建数据库并应用挂起的迁移. 右键单击`.Web`项目并选择**设置为启动项目**:
![set-as-startup-project](images/set-as-startup-project.png)
@ -56,6 +81,8 @@ EF Core 数据库迁移被分离到名为`.EntityFrameworkCore.DbMigrations`项
这将基于配置的连接字符串创建新数据库.
> 使用`.Migrator`工具是建议的方法, 因为它还能初始化初始数据能够正确运行Web应用程序.
### 运行应用程序
你现在可以运行应用程序,它将会打开**home**页面:
@ -64,9 +91,9 @@ EF Core 数据库迁移被分离到名为`.EntityFrameworkCore.DbMigrations`项
单击 **登录** 按钮, 输入用户名`admin`, 密码`1q2w3E*`, 登录应用程序.
启动模板包括 **身份管理(identity management)** 模块. 登录后将提供身份管理菜单,你可以在其中管理**角色**,**用户**及其**权限**.
启动模板包括**身份管理**和**租户管理**模块. 登录后,将显示"管理"菜单, 你可以在其中管理**租户**,**角色**,**用户**和**权限**. 用户管理页面如下所示:
![bookstore-user-management](images/bookstore-user-management.png)
![bookstore-user-management](images/bookstore-user-management-v2.png)
### 下一步是什么?

92
docs/zh-Hans/Index.md

@ -1,68 +1,32 @@
# ABP 文档
> 翻译来自[cnAbp](https://github.com/cnabp)组织,中文网会持续跟进翻译,目前Abp vNext的英文文档还未完成,大家对整体框架没有深入的理解,翻译难免存在一些问题.敬请见谅.😀
> 中文文档翻译来自[cnAbp](https://github.com/cnabp)组织,Abp中文网会持续跟进翻译,目前Abp vNext的英文文档还未完成,大家对整体框架没有深入的理解,翻译难免存在一些问题.敬请见谅.😀
## 目录
ABP是一个**开源应用程序框架**,专注于基于ASP.NET Core的Web应用程序开发,但也支持开发其他类型的应用程序.
* 入门
* 从启动模板开始
* [ASP.NET Core MVC 模板](Getting-Started-AspNetCore-MVC-Template.md)
* 从空项目开始
* [使用Console Application](Getting-Started-Console-Application.md)
* [使用 ASP.NET Core Web Application](Getting-Started-AspNetCore-Application.md)
* 教程
* 应用开发
* [使用 ASP.NET Core MVC](Tutorials/AspNetCore-Mvc/Part-I.md)
* 基础知识
* [依赖注入](Dependency-Injection.md)
* AutoFac 集成
* [虚拟文件系统](Virtual-File-System.md)
* [本地化](Localization.md)
* [异常处理](Exception-Handling.md)
* 验证
* 授权
* 缓存
* 审计
* 设置管理
* 对象映射
* AutoMapper 集成
* 事件
* 本地 Event Bus
* 分布式 Event Bus
* RabbitMQ 集成
* 服务
* 对象序列化
* JSON序列化
* 邮件
* GUIDs
* 线程
* 定时
* [多租户](Multi-Tenancy.md)
* 模块开发
* [基础](Module-Development-Basics.md)
* 模块插件
* [最佳实践](Best-Practices/Index.md)
* 领域驱动设计
* 领域层
* [实体&聚合根](Entities.md)
* 值对象
* [仓储](Repositories.md)
* 领域服务
* 规约
* 应用服务层
* 应用服务
* 数据传输对象(DTO)
* 工作单元
* ASP.NET Core MVC
* API 版本控制
* 用户界面
* [客户端包管理](AspNetCore/Client-Side-Package-Management.md)
* [捆绑&压缩](AspNetCore/Bundling-Minification.md)
* [Tag Helpers](Tag-Helpers.md)
* [主题](AspNetCore/Theming.md)
* 后台服务
* [后台作业](Background-Jobs.md)
* 数据访问
* [Entity Framework Core 集成](Entity-Framework-Core.md)
* [MongoDB 集成](MongoDB.md)
* 测试
浏览左侧导航菜单以深入了解文档.
## 项目状态
ABP是开源[ASP.NET Boilerplate](https://aspnetboilerplate.com/)框架的**下一代框架**, 它目前处于早期预览阶段,尚未准备好在生产中使用. 文档仍在进行中,远未完成.
对于短期和生产级应用程序, 建议使用[ASP.NET Boilerplate](https://aspnetboilerplate.com/)框架,该框架具有丰富的功能集,成熟,积极维护和最新.
## 入门
使用ABP开发新项目的最简单方法是使用启动模板:
* [ASP.NET Core MVC 模板](Getting-Started-AspNetCore-MVC-Template.md)
如果您想从头开始(使用空项目),请手动安装ABP框架并使用以下教程:
* [控制台应用程序](Getting-Started-Console-Application.md)
* [ASP.NET Core Web 应用程序](Getting-Started-AspNetCore-Application.md)
## 源码
ABP托管在GitHub上, 参见[源代码](https://github.com/abpframework/abp).
## 贡献代码
ABP是一个社区驱动的开源项目.如果你想成为该项目的一部分,请参阅[贡献指南](Contribution/Index.md).

8
docs/zh-Hans/Startup-Templates/Index.md

@ -0,0 +1,8 @@
# 启动模板
虽然你可以从一个空项目开始并手动添加所需的包,但启动模板可以非常轻松,舒适地使用ABP框架启动新的解决方案.
单击下面列表中的名称以查看相关启动模板的文档:
* [**mvc**](Mvc.md): ASP.NET Core MVC应用程序模板.
* [**mvc-module**](Mvc-Module.md): ASP.NET Core MVC模块/服务模板.

6
docs/zh-Hans/Startup-Templates/Mvc-Module.md

@ -0,0 +1,6 @@
# MVC Module 启动模板
TODO

183
docs/zh-Hans/Startup-Templates/Mvc.md

@ -0,0 +1,183 @@
# MVC Application Startup Template
## Introduction
This template provides a layered (or tiered, based on the preference) application structure based on the [Domain Driven Design](../Domain-Driven-Design.md) (DDD) practices.
## How to Start With
You can use the [ABP CLI](../CLI.md) to create a new project using this startup template. Alternatively, you can directly create & download from the [Get Started](https://abp.io/get-started) page. CLI approach is used here.
First, install the ABP CLI as described in [its document](../CLI.md). Then use the `abp new` command in an empty folder to create a new solution:
````bash
abp new Acme.BookStore -t mvc
````
* `Acme.BookStore` is the solution name, like *YourCompany.YourProduct*. See the [CLI document](../CLI.md) for different naming styles.
* This example specified the template name (`-t` or `--template` option). However, `mvc` is the default template and used even if you don't specify it.
### Specify Database Provider
This template supports the following database providers:
- `ef`: Entity Framework Core (default)
- `mongodb`: MongoDB
Use the `-d` (or `--database-provider`) to specify the database provider:
````bash
abp new Acme.BookStore -t mvc -d mongodb
````
### Create a Tiered Solution
`--tiered` option is used to create a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
````bash
abp new Acme.BookStore --tiered
````
See the "Tiered Structure" section below for the tiered approach.
## Solution Structure
Based on the options you've specified, you will get a slightly different solution structure.
### Default Structure
If you don't specify any option, you will have a solution like shown below:
![bookstore-visual-studio-solution-v3](../images/bookstore-visual-studio-solution-v3.png)
Projects are organized in `src` and `test` folders. `src` folder contains the actual application which is layered based on [DDD](../Domain-Driven-Design.md) principles as mentioned before.
--------------------
**TODO: Add a graphic to illustrate dependencies between projects.**
------------------
Each section below will explain the related project.
#### .Domain Project
This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value types](../Value-Types.md), [repository interfaces](../Repositories.md) and other domain objects of the solution.
A `Book` entity and a `IBookRepository` interface are good candidates for this project.
* Depends on the `.Domain.Shared` because it uses constants, enums and other objects defined in that project.
#### .Domain.Shared Project
This project contains constants, enums and other objects these are actually a part of the domain layer, but needed to be used by all layers/projects in the solution.
A `BookType` enum and a `BookConts` class (which may have some constant fields for the `Book` entity, like `MaxNameLength`) are good candidates for this project.
This project has no dependency to other projects in the solution.
#### .Application.Contracts Project
This project mainly contains [application service](../Application-Services.md) **interfaces** and [Data Transfer Objects](../Data-Transfer-Objects.md) (DTO) of the application layer. It does exists to separate interface & implementation of the application layer. In this way, the interface project can be shared to the clients as a contract package.
* Depends on the `.Domain.Shared` because it may use constants, enums and other shared objects in the application service interfaces and DTOs.
#### .Application Project
This project contains the [application service](../Application-Services.md) implementations of the interfaces defined in the `.Application.Contracts` project.
* Depends on the `.Application.Contracts` project to be able to implement the interfaces and use the DTOs.
* Depends on the `.Domain` project to be able to use domain objects (entities, repository interfaces... etc.) to perform the application logic.
#### .EntityFrameworkCore Project.
This is the integration project for the EF Core. It defines the `DbContext` and implements repository interfaces defined in the `.Domain` project.
* Depends on the `.Domain` project to be able to reference to entities and repository interfaces.
> This project is available only if you are using EF Core as the database provider.
#### .EntityFrameworkCore.DbMigrations Project
Contains EF Cor database migrations for the solution. It has a separated `DbContext` to dedicated to manage migrations.
ABP is a modular framework and with an ideal design, each module has its own `DbContext` class. This is where the migration `DbContext` comes into play and unifies all `DbContext` configurations into a single model to maintain a single database schema.
Notice that the migration `DbContext` is only used for database migrations and *not used on runtime*.
* Depends on the `.EntityFrameworkCore` project since it re-uses the configuration defined for the `DbContext` of the application.
> This project is available only if you are using EF Core as the database provider.
#### .DbMigrator Project
This is a console application which simplifies to execute database migrations on development and production environments. When you this application;
* Creates the database if necessary.
* Applies database migrations.
* Seeds initial data.
> This project has its own `appsettings.json` file. So, if you want to change the database connection string, remember to change this file.
Especially, seeding initial data is important at this point. ABP has a modular data seed infrastructure. See [its documentation](../Data-Seeding.md) for more about the data seeding.
While creating database & applying migrations seems only necessary for relational databases, this projects comes even if you choose a NoSQL database provider (like MongoDB). In that case, it still seeds initial data which is necessary for the application.
* Depends on the `.EntityFrameworkCore.DbMigrations` project (for EF Core) since it needs to access to the migrations.
* Depends on the `.Application.Contracts` project to be able to access permission definitions, because initial data seeder grants permissions for the admin user.
#### .HttpApi Project
This project is used to define your API Controllers.
Most of time you don't need to manually define API Controllers since ABP's [Auto API Controllers](../AspNetCore/Auto-API-Controllers.md) feature creates them automagically based on your application layer. However, in case of you need to write API controllers, this is the best place to do it.
* Depends on the `.Application.Contracts` project to be able to inject the application service interfaces.
#### .HttpApi.Client Project
This is a project that defines C# client proxies to use the HTTP APIs of the solution. You can share this library to 3rd-party clients, so they can easily consume your HTTP APIs in their Dotnet applications.
`.HttpApi.Client.ConsoleTestApp` project is a console application created to demonstrate the usage of the client proxies.
Most of time you don't need to manually create C# client proxies, thanks to ABP's [Cynamic C# API Clients](../AspNetCore/Dynamic-CSharp-API-Clients.md) feature.
* Depends on the `.Application.Contracts` project to be able to share the same application service interfaces and DTOs with the remote service.
#### .Web Project
This project contains the User Interface (UI) of the application. It contains razor pages, javascript files, css files, images and so on...
* Depends on the `.HttpApi` since UI layer needs to use APIs and application service interfaces of the solution.
> If you check the source code of the `.Web.csproj` file, you will see the references to the `.Application` and the `.EntityFrameworkCore.DbMigrations` projects.
>
> These references are actually not needed on development, because UI layer normally doesn't depend on the EF Core or the Application implementation. This startup templates are ready for the tiered deployment, where API layer is hosted in a separate server than the UI layer.
>
> However, if you don't choose the `--tiered` option, these references will be in the .Web project to be able to host the Web, API and application layers in a single application endpoint.
>
> This gives you to ability to use domain entities in your presentation layer. However, this is considered as a bad practice according to the DDD.
#### Test Projects
The solution has multiple test projects, one for each layer:
* `.Domain.Tests` is used to test the domain layer.
* `.Application.Tests` is used to test the application layer.
* `.EntityFrameworkCore.Tests` is used to test EF Core configuration and custom repositories.
* `.Web.Tests` is used to test the UI.
* `.TestBase` is a base (shared) project for all tests.
In addition, `.HttpApi.Client.ConsoleTestApp` is a console application (not an automated test project) which demonstrate the usage of HTTP APIs from a Dotnet application.
### Tiered Structure
TODO
### Other Database Providers
TODO
#### MongoDB
TODO

142
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md

@ -2,7 +2,7 @@
### 关于本教程
本教程中,你会创建一个用于管理书籍和书籍作者的程序.会用到 **Entity Framework Core** (EF Core)作为ORM([启动模板](https://abp.io/Templates)中预配置的ORM).
在本系列教程中, 你将构建一个用于管理书籍及其作者列表的应用程序. **Entity Framework Core**(EF Core)将用作ORM提供者,因为它是默认数据库提供者.
这是本教程所有章节中的第一章,下面是所有的章节:
@ -10,35 +10,37 @@
- [Part II: 创建,编辑,删除书籍](Part-II.md)
- [Part III: 集成测试](Part-III.md)
你可以从[这里](https://github.com/volosoft/abp/tree/master/samples/BookStore)下载本程序的源码.
你可以从[GitHub存储库](https://github.com/volosoft/abp/tree/master/samples/BookStore)访问应用程序的**源代码**.
### 创建项目
打开[启动模板页](https://abp.io/Templates)并下载一个新的项目叫做`Acme.BookStore`.根据[模板文档](../../Getting-Started-AspNetCore-MVC-Template.md)创建数据库并运行这个程序.
创建一个名为`Acme.BookStore`的新项目, 创建数据库并按照[入门文档](../../Getting-Started-AspNetCore-MVC-Template.md)运行应用程序.
### 解决方案的结构
下面的图片展示了从启动模板创建的项目是如何分层的.
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v3.png)
> 你可以查看[MVC应用程序模板文档](../../Startup-Templates/Mvc.md)以详细了解解决方案结构.但是,你将通过本教程了解基础知识.
### 创建Book实体
**领域层** 定义[实体](../../Entities.md)(`Acme.BookStore.Domain` 项目中).这个项目最主要的实体就是`Book`:
启动模板中的域层分为两个项目:
- `Acme.BookStore.Domain`包含你的[实体](../../Entities.md), [领域服务](../../Domain-Services.md)和其他核心域对象.
- `Acme.BookStore.Domain.Shared`包含可与客户共享的常量,枚举或其他域相关对象.
在解决方案的**领域层**(`Acme.BookStore.Domain`项目)中定义[实体](../../Entities.md). 该应用程序的主要实体是`Book`. 在`Acme.BookStore.Domain`项目中创建一个名为`Book`的类,如下所示:
````C#
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore
{
[Table("Books")]
public class Book : AuditedAggregateRoot<Guid>
{
[Required]
[StringLength(128)]
public string Name { get; set; }
public BookType Type { get; set; }
@ -50,8 +52,8 @@ namespace Acme.BookStore
}
````
* ABP有两个基本的实体基类: `AggregateRoot``Entity`.**Aggregate Root**是 **领域驱动设计(DDD)** 的概念之一.更多信息和最佳实践请查看[实体文档](../../Entities.md).
* `Book`实体继承了`AuditedAggregateRoot`,`AuditedAggregateRoot`类在`AggregateRoot`类的基础上添加了一些审计属性(`CreationTime`, `CreatorId`, `LastModificationTime`....).
* ABP为实体提供了两个基本的基类: `AggregateRoot`和`Entity`. **Aggregate Root**是**域驱动设计(DDD)** 概念之一. 有关详细信息和最佳做法,请参阅[实体文档](../../Entities.md).
* `Book`实体继承了`AuditedAggregateRoot`,`AuditedAggregateRoot`类在`AggregateRoot`类的基础上添加了一些审计属性(`CreationTime`, `CreatorId`, `LastModificationTime` 等).
* `Guid`是`Book`实体的主键类型.
* 使用 **数据注解** 为EF Core添加映射.或者你也可以使用 EF Core 自带的[fluent mapping API](https://docs.microsoft.com/en-us/ef/core/modeling).
@ -62,10 +64,10 @@ namespace Acme.BookStore
````C#
namespace Acme.BookStore
{
public enum BookType : byte
public enum BookType
{
Undefined,
Advanture,
Adventure,
Biography,
Dystopia,
Fantastic,
@ -91,14 +93,15 @@ public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
#### 配置你的Book实体
从`Acme.BookStore.EntityFrameworkCore` 项目中打开 BookStoreDbContextModelCreatingExtensions.cs 文件, 在 ConfigureBookStore 方法最后添加如下代码来配置Book实体:
在`Acme.BookStore.EntityFrameworkCore`项目中打开`BookStoreDbContextModelCreatingExtensions.cs`文件,并将以下代码添加到`ConfigureBookStore`方法的末尾以配置Book实体:
````C#
builder.Entity<Book>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
b.ConfigureExtraProperties();
});
builder.Entity<Book>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
b.ConfigureAuditedAggregateRoot(); //auto configure for the base class props
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
});
````
#### 添加新的Migration并更新数据库
@ -115,26 +118,27 @@ PM> Update-Database
#### 添加示例数据
`Update-Database`命令会在数据库中创建`Books`表.打开这个表添加几行数据,然后就可以把这些数据展示到页面上:
`Update-Database`命令在数据库中创建了`AppBooks`表. 打开数据库并输入几个示例行,以便在页面上显示它们:
![bookstore-books-table](images/bookstore-books-table.png)
### 创建应用服务
下一步是创建[应用服务](../../Application-Services.md)来管理(创建,列出,更新,删除...)书籍.
下一步是创建[应用服务](../../Application-Services.md)来管理(创建,列出,更新,删除)书籍. 启动模板中的应用程序层分为两个项目:
* `Acme.BookStore.Application.Contracts`主要包含你的DTO和应用程序服务接口.
* `Acme.BookStore.Application`包含应用程序服务的实现.
#### BookDto
在`Acme.BookStore.Application`项目中添加一个名为`BookDto`的DTO类:
在`Acme.BookStore.Application.Contracts`项目中创建一个名为`BookDto`的DTO类:
````C#
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AutoMapper;
namespace Acme.BookStore
{
[AutoMapFrom(typeof(Book))]
public class BookDto : AuditedEntityDto<Guid>
{
public string Name { get; set; }
@ -151,7 +155,23 @@ namespace Acme.BookStore
* **DTO**类被用来在 **表示层****应用层** **传递数据**.查看[DTO文档](../../Data-Transfer-Objects.md)查看更多信息.
* 为了在页面上展示书籍信息,`BookDto`被用来将书籍数据传递到表示层.
* `BookDto`继承自 `AuditedEntityDto<Guid>`.跟上面定义的`Book`类一样具有一些审计属性.
* `[AutoMapFrom(typeof(Book))]`用来创建从`Book`类到`BookDto`的AutoMapper映射.使用这种方法.你可以将`Book`对象自动转换成`BookDto`对象(而不是手动复制所有的属性).
在将书籍返回到表示层时,需要将`Book`实体转换为`BookDto`对象. [AutoMapper](https://automapper.org)库可以在定义了正确的映射时自动执行此转换. 启动模板配置了AutoMapper,因此你只需在`Acme.BookStore.Application`项目的`BookStoreApplicationAutoMapperProfile`类中定义映射:
````csharp
using AutoMapper;
namespace Acme.BookStore
{
public class BookStoreApplicationAutoMapperProfile : Profile
{
public BookStoreApplicationAutoMapperProfile()
{
CreateMap<Book, BookDto>();
}
}
}
````
#### CreateUpdateBookDto
@ -184,11 +204,17 @@ namespace Acme.BookStore
````
* 这个DTO类被用于在创建或更新书籍的时候从用户界面获取图书信息.
* 类中的属性定义了数据注解(如`[Required]`)用来定义有效性验证.ABP会自动校验DTO的数据有效性.
* 它定义了数据注释属性(如`[Required]`)来定义属性的验证. DTO由ABP框架[自动验证](../../Validation.md).
就像上面的`BookDto`一样,创建一个从`CreateUpdateBookDto`对象到`Book`实体的映射:
````csharp
CreateMap<CreateUpdateBookDto, Book>();
````
#### IBookAppService
为应用服务定义一个名为 `IBookAppService` 的接口:
在`Acme.BookStore.Application.Contracts`项目中定义一个名为`IBookAppService`的接口:
````C#
using System;
@ -210,15 +236,14 @@ namespace Acme.BookStore
}
````
* 为应用服务定义接口不是必须的,不过,这是推荐的最佳实践.
* `IAsyncCrudAppService`中定义了基础的 **CRUD**方法:`GetAsync`, `GetListAsync`, `CreateAsync`, `UpdateAsync``DeleteAsync`.不需要扩展它.取而代之,你可以继承空的`IApplicationService`接口定义你自己的方法.
* `IAsyncCrudAppService`有一些变体,你可以为每一个方法使用单个或者多个的DTO.(译者注:意思是类似EntityDto和UpdateEntityDto可以用同一个,也可以分别单独指定
)
* 框架定义应用程序服务的接口<u>不是必需的</u>. 但是,它被建议作为最佳实践.
* `IAsyncCrudAppService`定义了常见的**CRUD**方法:`GetAsync`,`GetListAsync`,`CreateAsync`,`UpdateAsync`和`DeleteAsync`. 你可以从空的`IApplicationService`接口继承并手动定义自己的方法.
* `IAsyncCrudAppService`有一些变体, 你可以在每个方法中使用单独的DTO,也可以分别单独指定.
#### BookAppService
创建 `BookAppService` 并实现 `IBookAppService`接口:
在`Acme.BookStore.Application`项目中实现名为`BookAppService`的`IBookAppService`:
````C#
using System;
@ -243,23 +268,23 @@ namespace Acme.BookStore
````
* `BookAppService`继承了`AsyncCrudAppService<...>`.`AsyncCrudAppService<...>`实现了上面定义的CRUD方法.
* `BookAppService`注入`IRepository<Book, Guid>`,`IRepository<Book, Guid>`是默认为`Book`创建的仓储.ABP会自动为每一个聚合根(或实体)创建仓储.参考[仓储文档](../../Repositories.md).
* `BookAppService`使用了 `IObjectMapper` 将`Book`转换成`BookDto`,将`CreateUpdateBookDto`转换成`Book`.启动模板中使用了[AutoMapper](http://automapper.org/)作为对象映射提供程序.你可以像上面那样使用`AutoMapFrom` 和 `AutoMapTo`定义映射.查看[AutoMapper集成文档](../../AutoMapper-Integration.md)获取更多信息.
* `BookAppService`注入`IRepository <Book,Guid>`,这是`Book`实体的默认仓储. ABP自动为每个聚合根(或实体)创建默认仓储. 请参阅[仓储文档](../../Repositories.md)
* `BookAppService`使用`IObjectMapper`将`Book`对象转换为`BookDto`对象, 将`CreateUpdateBookDto`对象转换为`Book`对象. 启动模板使用[AutoMapper](http://automapper.org/)库作为对象映射提供程序. 你之前定义了映射, 因此它将按预期工作.
### 自动生成API Controllers
你通常需要创建 **Controllers** 将应用服务暴露为 **HTTP API**.这样浏览器或第三方客户端可以通过AJAX的方式访问它们.
ABP可以通过约定[**自动**](../../AspNetCore/Auto-API-Controllers.md)将应用服务转换成MVC API Controllers.
你通常创建**Controller**以将应用程序服务公开为**HTTP API**端点. 因此允许浏览器或第三方客户端通过AJAX调用它们. ABP可以[**自动**](../../AspNetCore/Auto-API-Controllers.md)按照惯例将你的应用程序服务配置为MVC API控制器.
#### Swagger UI
启动模板使用[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)库配置了[swagger UI](https://swagger.io/tools/swagger-ui/).运行程序并在浏览器中输入`http://localhost:53929/swagger/`.
启动模板配置为使用[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)运行[swagger UI](https://swagger.io/tools/swagger-ui/). 运行应用程序并在浏览器中输入`https://localhost:XXXX/swagger/`(用您自己的端口替换XXXX)作为URL.
你会看到一些内置的接口和`Book`的接口,它们都是REST风格的:
![bookstore-swagger](images/bookstore-swagger.png)
Swagger有一个很好的UI来测试API. 你可以尝试执行`[GET] /api/app/book` API来获取书籍列表.
### 动态JavaScript代理
在Javascript端通过AJAX的方式调用HTTP API接口是很常见的,你可以使用`$.ajax`或这其他的工具来调用接口.当然,ABP中提供了更好的方式.
@ -270,6 +295,8 @@ ABP **自动** 为所有的API接口创建了JavaScript **代理**.因此,你可
你可以使用你钟爱的浏览器的 **开发者控制台** 中轻松测试JavaScript代理.运行程序,并打开浏览器的 **开发者工具**(快捷键:F12),切换到 **Console** 标签,输入下面的代码并回车:
你现在可以使用自己喜欢的浏览器的**开发者控制台**轻松测试JavaScript代理. 运行应用程序, 打开浏览器的**开发者工具**(快捷键:F12),切换到**Console**选项卡,输入以下代码并按回车键.
````js
acme.bookStore.book.getList({}).done(function (result) { console.log(result); });
````
@ -277,7 +304,7 @@ acme.bookStore.book.getList({}).done(function (result) { console.log(result); })
* `acme.bookStore`是`BookAppService`的命名空间,转换成了[驼峰命名](https://en.wikipedia.org/wiki/Camel_case).
* `book`是`BookAppService`转换后的名字(去除了AppService后缀并转成了驼峰命名).
* `getList`是定义在`AsyncCrudAppService`基类中的`GetListAsync`方法转换后的名字(去除了Async后缀并转成了驼峰命名).
* `{}`参数用来传递一个空的对象给`GetListAsync`方法.GetListAsync期望的参数是`PagedAndSortedResultRequestDto`类型的对象,`PagedAndSortedResultRequestDto`类型中定义了分页和排序选项.
* `{}`参数用于将空对象发送到`GetListAsync`方法,该方法通常需要一个类型为`PagedAndSortedResultRequestDto`的对象,用于向服务器发送分页和排序选项(所有属性都是可选的,所以你可以发送一个空对象).
* `getList`方法返回了一个`promise`.因此,你可以传递一个回调函数到`done`(或者`then`)方法中来获取服务返回的结果.
运行这段代码会产生下面的输出:
@ -300,7 +327,7 @@ acme.bookStore.book.create({ name: 'Foundation', type: 7, publishDate: '1951-05-
successfully created the book with id: f3f03580-c1aa-d6a9-072d-39e75c69f5c7
````
检查数据库表`books`中的数据,你会发现多了一行新数据,你也可以尝试`get`, `update``delete`方法.
检查数据库中的`Books`表以查看新书. 你可以自己尝试`get`,`update`和`delete`功能.
### 创建书籍页面
@ -309,20 +336,21 @@ successfully created the book with id: f3f03580-c1aa-d6a9-072d-39e75c69f5c7
`Acme.BookStore.Web`项目的`Pages`文件夹下创建一个新的文件夹叫`Books`并添加一个名为`Index.cshtml`的Razor Page.
![bookstore-add-index-page](images/bookstore-add-index-page.png)
![bookstore-add-index-page](images/bookstore-add-index-page-v2.png)
打开`Index.cshtml`并把内容修改成下面这样:
````html
@page
@using Acme.BookStore.Pages.Books
@inherits Acme.BookStore.Pages.BookStorePageBase
@using Acme.BookStore.Web.Pages.Books
@inherits Acme.BookStore.Web.Pages.BookStorePageBase
@model IndexModel
<h2>Books</h2>
````
* 修改Razor View Page Model的默认继承,使页面 **继承** 自`BookStorePageBase`类(代替`PageModel`).`BookStorePageBase`类来自于启动模板,它提供了一些公开的可以被所有的页面使用的属性/方法.
* 此代码更改了Razor View Page Model的默认继承,因此它从`BookStorePageBase`类(而不是`PageModel`)继承.启动模板附带的`BookStorePageBase`类,提供所有页面使用的一些共享属性/方法.
* 确保`IndexModel`(Index.cshtml.cs)具有`Acme.BookStore.Pages.Books`命名空间,或者在`Index.cshtml`中更新它.
#### 将Books页面添加到主菜单
@ -337,17 +365,16 @@ context.Menu.AddItem(
#### 本地化菜单
本地化的文本在`Acme.BookStore.Domain`项目的`Localization/BookStore`文件夹中.
本地化文本位于`Acme.BookStore.Domain.Shared`项目的`Localization/BookStore`文件夹下:
![bookstore-localization-files](images/bookstore-localization-files.png)
![bookstore-localization-files](images/bookstore-localization-files-v2.png)
打开`en.json`文件,为`Menu:BookStore` 和 `Menu:Books`添加本地化文本:
打开`en.json`文件,将`Menu:BookStore`和`Menu:Books`键的本地化文本添加到文件末尾:
````json
{
"culture": "en",
"texts": {
//...
"Menu:BookStore": "Book Store",
"Menu:Books": "Books"
}
@ -355,9 +382,9 @@ context.Menu.AddItem(
````
* ABP的本地化功能建立在[ASP.NET Core's standard localization]((https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization))之上并增加了一些扩展.查看[本地化文档](../../Localization.md).
* 本地化中key的名字是随便定义的,你可以随意命名.我们喜欢为菜单添加`Menu`命名空间,以区别于其他的文本.如果文本没有在本地化文件中定义,就会 **返回** 本地的化的key(ASP.NET Core的标准做法).
* 本地化key是任意的. 你可以设置任何名称. 我们更喜欢为菜单项添加`Menu:`前缀以区别于其他文本. 如果未在本地化文件中定义文本,则它将**返回**到本地化的key(ASP.NET Core的标准行为).
运行程序就会看到菜单已经添加到了顶部:
运行该应用程序,看到新菜单项已添加到顶部栏:
![bookstore-menu-items](images/bookstore-menu-items.png)
@ -365,17 +392,16 @@ context.Menu.AddItem(
#### 书籍列表
我们会在页面上使用JQuery插件[Datatables.net](https://datatables.net/)来展示列表.Datatables可以完全通过AJAX工作,所以它很快而且有良好的用户体验.启动模板中已经配置好了Datatables插件,因此你可以在你的页面中直接使用,不需要引用样式和脚本文件.
我们将使用[Datatables.net](https://datatables.net/)JQuery插件来显示页面上的表格列表. 数据表可以完全通过AJAX工作,速度快,并提供良好的用户体验. Datatables插件在启动模板中配置,因此你可以直接在任何页面中使用它,而需要在页面中引用样式和脚本文件.
##### 修改Index.cshtml
##### Index.cshtml
将`Pages/Books/Index.cshtml`改成下面的样子:
````html
@page
@using Acme.BookStore.Pages.Books
@inherits Acme.BookStore.Pages.BookStorePageBase
@model IndexModel
@inherits Acme.BookStore.Web.Pages.BookStorePageBase
@model Acme.BookStore.Web.Pages.Books.IndexModel
@section scripts
{
<abp-script src="/Pages/Books/index.js" />
@ -408,7 +434,7 @@ context.Menu.AddItem(
在`Pages/Books/`文件夹中创建 `index.js`文件
![bookstore-index-js-file](images/bookstore-index-js-file.png)
![bookstore-index-js-file](images/bookstore-index-js-file-v2.png)
`index.js`的内容如下:
@ -430,7 +456,7 @@ $(function () {
* `abp.libs.datatables.createAjax`是帮助ABP的动态JavaScript API代理跟Datatable的格式相适应的辅助方法.
* `abp.libs.datatables.normalizeConfiguration`是另一个辅助方法.不是必须的, 但是它通过为缺少的选项提供常规值来简化数据表配置.
* `acme.bookStore.book.getList`是获取书籍列表的方法(上面已经介绍过了)
* 查看 [Datatable's 文档](https://datatables.net/manual/) 了解更多配置项.
* 查看 [Datatable文档](https://datatables.net/manual/) 了解更多配置项.
最终的页面如下:

66
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-II.md

@ -2,13 +2,13 @@
### 关于本教程
这是本教程所有章节中的第二章.下面是所有的章节:
这是ASP.NET Core MVC教程系列的第二章. 查看其它章节
* [Part I: 创建项目和书籍列表页面](Part-I.md)
* **Part II: 创建,编辑,删除书籍(本章)**
* [Part III: 集成测试](Part-III.md)
你可以从 [这里](https://github.com/volosoft/abp/tree/master/samples/BookStore) 下载本程序的**源码**.
你可以从[GitHub存储库](https://github.com/volosoft/abp/tree/master/samples/BookStore)访问应用程序的**源代码**.
### 新增 Book 实体
@ -20,7 +20,7 @@
`Acme.BookStore.Web` 项目的 `Pages/Books` 目录下新建一个 `CreateModal.cshtml` Razor页面:
![bookstore-add-create-dialog](images/bookstore-add-create-dialog.png)
![bookstore-add-create-dialog](images/bookstore-add-create-dialog-v2.png)
##### CreateModal.cshtml.cs
@ -30,7 +30,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Acme.BookStore.Pages.Books
namespace Acme.BookStore.Web.Pages.Books
{
public class CreateModalModel : BookStorePageModelBase
{
@ -63,9 +63,9 @@ namespace Acme.BookStore.Pages.Books
````html
@page
@inherits Acme.BookStore.Pages.BookStorePageBase
@inherits Acme.BookStore.Web.Pages.BookStorePageBase
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model Acme.BookStore.Pages.Books.CreateModalModel
@model Acme.BookStore.Web.Pages.Books.CreateModalModel
@{
Layout = null;
}
@ -138,12 +138,12 @@ $('#NewBookButton').click(function (e) {
展开 `EditModal.cshtml`,打开 `EditModal.cshtml.cs` 文件( `EditModalModel` 类) 并替换成以下代码:
````C#
````csharp
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Acme.BookStore.Pages.Books
namespace Acme.BookStore.Web.Pages.Books
{
public class EditModalModel : BookStorePageModelBase
{
@ -180,38 +180,26 @@ namespace Acme.BookStore.Pages.Books
* 在 `OnGetAsync` 方法中,将 `BookAppService.GetAsync` 方法返回的 `BookDto` 映射成 `CreateUpdateBookDto` 并赋值给Book属性.
* `OnPostAsync` 方法直接使用 `BookAppService.UpdateAsync` 来更新实体.
#### CreateUpdateBookDto
#### BookDto到CreateUpdateBookDto对象映射
为了执行`BookDto``CreateUpdateBookDto` 的对象映射, 按如下所示修改 `CreateUpdateBookDto`:
为了执行`BookDto`到`CreateUpdateBookDto`对象映射,请打开`Acme.BookStore.Web`项目中的`BookStoreWebAutoMapperProfile.cs`并更改它,如下所示:
````C#
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.AutoMapper;
````csharp
using AutoMapper;
namespace Acme.BookStore
namespace Acme.BookStore.Web
{
[AutoMapTo(typeof(Book))]
[AutoMapFrom(typeof(BookDto))]
public class CreateUpdateBookDto
public class BookStoreWebAutoMapperProfile : Profile
{
[Required]
[StringLength(128)]
public string Name { get; set; }
[Required]
public BookType Type { get; set; } = BookType.Undefined;
[Required]
public DateTime PublishDate { get; set; }
[Required]
public float Price { get; set; }
public BookStoreWebAutoMapperProfile()
{
CreateMap<BookDto, CreateUpdateBookDto>();
}
}
}
````
* 仅添加 `[AutoMapFrom(typeof(BookDto))]` 特性就可以创建上述映射关系.
* 刚刚添加了`CreateMap<BookDto, CreateUpdateBookDto>();`作为映射定义.
#### EditModal.cshtml
@ -219,8 +207,8 @@ namespace Acme.BookStore
````html
@page
@inherits Acme.BookStore.Pages.BookStorePageBase
@using Acme.BookStore.Pages.Books
@inherits Acme.BookStore.Web.Pages.BookStorePageBase
@using Acme.BookStore.Web.Pages.Books
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model EditModalModel
@{
@ -231,7 +219,7 @@ namespace Acme.BookStore
<abp-modal-header title="@L["Update"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Id" />
<abp-form-content/>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
@ -240,8 +228,8 @@ namespace Acme.BookStore
这个页面内容和 `CreateModal.cshtml` 非常相似,除了以下几点:
* 此页面包含了一个 `abp-input` 以保存所编辑book实体的 `Id` 属性值.
* 此页面指定的post地址是 `Books/EditModal` ,并用文本 *Update* 作为 modal 标题.
* 它包含`id`属性的`abp-input`, 用于存储编辑书的id(它是隐藏的Input)
* 此页面指定的post地址是`Books/EditModal`, 并用文本 *Update* 作为 modal 标题.
#### 为表格添加 "操作(Actions)" 下拉菜单
@ -420,6 +408,12 @@ $(function () {
});
````
打开`Acme.BookStore.Domain.Shared`项目中的`en.json`并添加以下行:
````json
"BookDeletionConfirmationMessage": "Are you sure to delete the book {0}?"
````
运行程序并尝试删除一个book实体.
### 下一章

89
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md

@ -2,23 +2,21 @@
### 关于本教程
这是本教程所有章节中的第三章.下面是所有的章节:
这是ASP.NET Core MVC教程系列的第三章. 查看其它章节
- [Part I: 创建项目和书籍列表页面](Part-I.md)
- [Part II: 创建,编辑,删除书籍](Part-II.md)
- **Part III: 集成测试(本章)**
你可以从 [这里](https://github.com/volosoft/abp/tree/master/samples/BookStore) 下载本程序的**源码**.
你可以从[GitHub存储库](https://github.com/volosoft/abp/tree/master/samples/BookStore)访问应用程序的**源代码**.
### 解决方案中的测试项目
本解决方案中有两个测试项目:
解决方案中有多个测试项目:
![bookstore-test-projects-v2](images/bookstore-test-projects-v2.png)
* `Acme.BookStore.Application.Tests` 项目用于单元测试和集成测试.你可以在这个项目中为Application Service方法写测试代码.这个项目使用了 **EF Core SQLite in-memory** 数据库.
* `Acme.BookStore.Web.Tests` 项目用于包含Web层的完整集成测试.所以,你也可以在这里写关于UI页面的测试.
测试项目使用了以下库:
每个项目用于测试相关的应用程序项目.测试项目使用以下库进行测试:
* [xunit](https://xunit.github.io/) 作为主测试框架.
* [Shoudly](http://shouldly.readthedocs.io/en/latest/) 作为断言库.
@ -26,79 +24,39 @@
### 添加测试用数据
起始模板在 `Acme.BookStore.Application.Tests` 项目中包含了 `BookStoreTestDataBuilder` 类,用于创建一些测试用数据. 相关代码如下所示:
````C#
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Threading;
namespace Acme.BookStore
{
public class BookStoreTestDataBuilder : ITransientDependency
{
private readonly IIdentityDataSeeder _identityDataSeeder;
public BookStoreTestDataBuilder(IIdentityDataSeeder identityDataSeeder)
{
_identityDataSeeder = identityDataSeeder;
}
public void Build()
{
AsyncHelper.RunSync(BuildInternalAsync);
}
public async Task BuildInternalAsync()
{
await _identityDataSeeder.SeedAsync("1q2w3E*");
}
}
}
````
* 这里直接使用了identity模块实现的 `IIdentityDataSeeder` 接口,创建了一个admin角色和admin用户.你可以在测试代码中使用它们.
* 你可以在 `BuildInternalAsync` 方法中添加你自己的测试数据.
按下方所示修改 `BookStoreTestDataBuilder` 类:
启动模板包含`Acme.BookStore.TestBase`项目中的`BookStoreTestDataSeedContributor`类,它创建一些数据来运行测试.
更改`BookStoreTestDataSeedContributor`类如下所示:
````C#
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Threading;
using Volo.Abp.Guids;
namespace Acme.BookStore
{
public class BookStoreTestDataBuilder : ITransientDependency
public class BookStoreTestDataSeedContributor
: IDataSeedContributor, ITransientDependency
{
private readonly IIdentityDataSeeder _identityDataSeeder;
private readonly IRepository<Book, Guid> _bookRepository;
private readonly IGuidGenerator _guidGenerator;
public BookStoreTestDataBuilder(
IIdentityDataSeeder identityDataSeeder,
IRepository<Book, Guid> bookRepository)
public BookStoreTestDataSeedContributor(
IRepository<Book, Guid> bookRepository,
IGuidGenerator guidGenerator)
{
_identityDataSeeder = identityDataSeeder;
_bookRepository = bookRepository;
_guidGenerator = guidGenerator;
}
public void Build()
public async Task SeedAsync(DataSeedContext context)
{
AsyncHelper.RunSync(BuildInternalAsync);
}
public async Task BuildInternalAsync()
{
await _identityDataSeeder.SeedAsync("1q2w3E*");
await _bookRepository.InsertAsync(
new Book
{
Id = Guid.NewGuid(),
Id = _guidGenerator.Create(),
Name = "Test book 1",
Type = BookType.Fantastic,
PublishDate = new DateTime(2015, 05, 24),
@ -109,7 +67,7 @@ namespace Acme.BookStore
await _bookRepository.InsertAsync(
new Book
{
Id = Guid.NewGuid(),
Id = _guidGenerator.Create(),
Name = "Test book 2",
Type = BookType.Science,
PublishDate = new DateTime(2014, 02, 11),
@ -121,7 +79,8 @@ namespace Acme.BookStore
}
````
* 通过构造函数注入 `IRepository<Book, Guid>`,在 `BuildInternalAsync` 方法中用它创建两个book实体.
* 注入`IRepository<Book,Guid>`并在`SeedAsync`中使用它来创建两个书实体作为测试数据.
* 使用`IGuidGenerator`服务创建GUID. 虽然`Guid.NewGuid()`非常适合测试,但`IGuidGenerator`在使用真实数据库时还有其他特别重要的功能(参见[Guid生成文档](../../Guid-Generation.md)了解更多信息).
### 测试 BookAppService
@ -211,6 +170,8 @@ public async Task Should_Not_Create_A_Book_Without_Name()
* 由于 `Name` 是空值, ABP 抛出一个 `AbpValidationException` 异常.
### 测试 Web 页面
打开**测试资源管理器**(测试 -> Windows -> 测试资源管理器)并**执行**所有测试:
![bookstore-appservice-tests](images/bookstore-appservice-tests.png)
TODO
恭喜, 绿色图标表示测试已成功通过!

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

3
docs/zh-Hans/Value-Types.md

@ -0,0 +1,3 @@
## Value Types
TODO

4
docs/zh-Hans/docs-nav.json

@ -41,6 +41,10 @@
}
]
},
{
"text": "CLI",
"path": "CLI.md"
},
{
"text": "基础知识",
"items": [

BIN
docs/zh-Hans/images/bookstore-user-management-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/zh-Hans/images/bookstore-user-management.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/zh-Hans/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/zh-Hans/images/bookstore-visual-studio-solution-v3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/zh-Hans/images/bookstore-visual-studio-solution.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

BIN
docs/zh-Hans/images/db-migrator-app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Loading…
Cancel
Save