Skip to content

Commit

Permalink
Some fixes on the tutorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalkan committed Jul 3, 2018
1 parent 922bd25 commit 35a2011
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 35 deletions.
22 changes: 11 additions & 11 deletions docs/Getting-Started-AspNetCore-MVC-Template.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ The downloaded project requires;

### The Solution Structure

Open the zip file downloaded and open in **Visual Studio 2017 (15.7.0+)**:
Extract the zip file downloaded and open in **Visual Studio 2017 (15.7.0+)**:

![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png)

The solution has a layered structure (based on Domain Driven Design) where;

* **.Domain** project is the domain layer.
* **.Application** project is the application layer.
* **.Web** project is the presentation layer.
* **.EntityFrameworkCore** project is the EF Core integration package.
* ``.Domain`` is the domain layer.
* ``.Application`` is the application layer.
* ``.Web`` is the presentation layer.
* ``.EntityFrameworkCore`` is the EF Core integration package.

The solution does also contain unit & integration test projects properly configured to work with **EF Core** & **SQLite in-memory** database.
The solution also contains unit & integration test projects properly configured to work with **EF Core** & **SQLite in-memory** database.

### Creating the Database

Check the **connection string** in the **appsettings.json** file under the **.Web** project:
Check the **connection string** in the `appsettings.json` file under the `.Web` project:

````json
{
Expand All @@ -42,17 +42,17 @@ Check the **connection string** in the **appsettings.json** file under the **.We
}
````

The solution is configured to use **Entity Framework Core** with **MS SQL Server** (EF Core supports [various](https://docs.microsoft.com/en-us/ef/core/providers/) database providers, so you can use another DBMS if you want).
The solution is configured to use **Entity Framework Core** with **MS SQL Server**. EF Core supports [various](https://docs.microsoft.com/en-us/ef/core/providers/) database providers, so you can use another DBMS if you want.

Right click to the **.Web** project and select **Set as StartUp Project**:
Right click to the `.Web` project and select **Set as StartUp Project**:

![set-as-startup-project](images/set-as-startup-project.png)

Open the **Package Manager Console**, select **.EntityFrameworkCore** project as the **Default Project** and run the `Update-Database` command:
Open the **Package Manager Console**, select `.EntityFrameworkCore` project as the **Default Project** and run the `Update-Database` command:

![pcm-update-database](images/pcm-update-database.png)

This will create a new database with the name configured.
This will create a new database based on the configured connection string.

### Running the Application

Expand Down
47 changes: 23 additions & 24 deletions docs/Tutorials/AspNetCore-Mvc/Part-I.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ You can download the **source code** of the application [from here](https://gith

### Creating the Project

This tutorial assumes that you have created a new project, named `Acme.BookStore` from [the startup templates](https://abp.io/Templates).
Go to the [startup template page](https://abp.io/Templates) and download a new project named `Acme.BookStore`, create database and run the application by following the [template document](../../Getting-Started-AspNetCore-MVC-Template.md).

### Solution Structure

Expand Down Expand Up @@ -79,7 +79,7 @@ namespace Acme.BookStore

#### Add Book Entity to Your DbContext

EF Core requires to relate entities with your DbContext. The easiest way is to add a `DbSet` property to the `BookStoreDbContext` as shown below:
EF Core requires to relate entities with your DbContext. The easiest way is to add a `DbSet` property to the `BookStoreDbContext` class in the `Acme.BookStore.EntityFrameworkCore` project, as shown below:

````C#
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
Expand All @@ -89,11 +89,9 @@ public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
}
````

* `BookStoreDbContext` is located in the `Acme.BookStore.EntityFrameworkCore` project.
#### Add New Migration & Update the Database

#### Add new Migration & Update the Database

Startup template uses [EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to create and maintain the database schema. Open the **Package Manager Console (PMC)**, select the `Acme.BookStore.EntityFrameworkCore` as the **default project** and execute the following command:
Startup template uses [EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to create and maintain the database schema. Open the **Package Manager Console (PMC)** (under the *Tools/Nuget Package Manager* menu), select the `Acme.BookStore.EntityFrameworkCore` as the **default project** and execute the following command:

![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration.png)

Expand All @@ -105,13 +103,13 @@ PM> Update-Database

#### Add Sample Data

`Update-Database` command created the `Books` table in the database. Enter a few sample rows, so you can show them on the page:
`Update-Database` command created the `Books` table in the database. Open your database and enter a few sample rows, so you can show them on the page:

![bookstore-books-table](images/bookstore-books-table.png)

### Create the Application Service

The next step is to create an [application service](../../Application-Services.md) to manage (create, list, update, delete...) books.
The next step is to create an [application service](../../Application-Services.md) to manage (create, list, update, delete...) the books.

#### BookDto

Expand All @@ -138,14 +136,14 @@ namespace Acme.BookStore
}
````

* **DTO** classes are used to transfer data between the presentation layer and the application layer. See the [Data Transfer Objects document](../../Data-Transfer-Objects.md) for details.
* **DTO** classes are used to **transfer data** between the *presentation layer* and the *application layer*. See the [Data Transfer Objects document](../../Data-Transfer-Objects.md) for details.
* `BookDto` is used to transfer a book data to the presentation layer to show a book information on the UI.
* `BookDto` is derived from the `AuditedEntityDto<Guid>` which has audit properties just like the `Book` defined above.
* `[AutoMapFrom(typeof(Book))]` is used to create AutoMapper mapping from the `Book` class to the `BookDto` class. Thus, you can automatically convert `Book` objects to `BookDto` objects (instead of manually copy all properties).

#### CreateUpdateDto
#### CreateUpdateBookDto

Create a DTO class named `CreateUpdateDto` into the `Acme.BookStore.Application` project:
Create a DTO class named `CreateUpdateBookDto` into the `Acme.BookStore.Application` project:

````c#
using System;
Expand Down Expand Up @@ -174,9 +172,9 @@ namespace Acme.BookStore
}
````

* This DTO class is used to get book information from the user interface to create or update a book.
* It defines data annotation attributes (like `[Required]`) to define validations for the properties.
* Each property has a `[Display]` property which sets the label on UI forms for the related inputs. It's also integrated to the localization system. The same DTO will be used as View Model. That's why it defines that attribute. You may find incorrect to use DTOs as View Models. You could use a separated view model class, but we thought it's practical and makes the sample project less complex.
* This DTO class is used to get book information from the user interface while creating or updating a book.
* It defines data annotation attributes (like `[Required]`) to define validations for the properties. DTOs are automatically validated by ABP.
* Each property has a `[Display]` property which set the label text on UI forms for the related input (it's also integrated to the localization system). The same DTO will be used as View Model. That's why it defines that attribute. You may find incorrect to use DTOs as View Models. You could use a separated view model class, but we thought it's practical and makes the sample project less complex.

#### IBookAppService

Expand All @@ -200,11 +198,10 @@ namespace Acme.BookStore

}
}

````

* Defining interfaces for application services is <u>not required</u> by the framework. However, it's suggested as a good practice.
* `IAsyncCrudAppService` defines common **CRUD** methods: `GetAsync`, `GetListAsync`, `CreateAsync`, `UpdateAsync` and `DeleteAsync`. It's not required to extend it. Instead you could inherit from the empty `IApplicationService` interface and define your own methods.
* `IAsyncCrudAppService` defines common **CRUD** methods: `GetAsync`, `GetListAsync`, `CreateAsync`, `UpdateAsync` and `DeleteAsync`. It's not required to extend it. Instead, you could inherit from the empty `IApplicationService` interface and define your own methods.
* There are some variations of the `IAsyncCrudAppService` where you can use a single DTO or separated DTOs for each method.

#### BookAppService
Expand Down Expand Up @@ -235,21 +232,21 @@ namespace Acme.BookStore

* `BookAppService` is derived from `AsyncCrudAppService<...>` which implements all CRUD methods defined above.
* `BookAppService` injects `IRepository<Book, Guid>` which is the default repository created for the `Book` entity. ABP automatically creates repositories for each aggregate root (or entity). See the [repository document](../../Repositories.md).
* `BookAppService` uses `IObjectMapper` to convert `Book` objects to `BookDto` objects and `CreateUpdateBookDto` objects to `Book` objects. Startup template uses the [AutoMapper](http://automapper.org/) library as the mapping provider. You defined mappings using the `AutoMapFrom` and `AutoMapTo` attributes above. See the [AutoMapper integration document](../../AutoMapper-Integration.md) for details.
* `BookAppService` uses `IObjectMapper` to convert `Book` objects to `BookDto` objects and `CreateUpdateBookDto` objects to `Book` objects. Startup template uses the [AutoMapper](http://automapper.org/) library as object mapping provider. You defined mappings using the `AutoMapFrom` and the `AutoMapTo` attributes above. See the [AutoMapper integration document](../../AutoMapper-Integration.md) for details.

### Auto API Controllers

You normally create **Controllers** to expose application services as **HTTP API** endpoints. Thus, browser or 3rd-party clients can call via AJAX.

ABP can automatically configures your application services as MVC API Controllers by convention.
ABP can **automagically** configures your application services as MVC API Controllers by convention.

#### Swagger UI

The startup template is configured to run the [swagger UI](https://swagger.io/tools/swagger-ui/) using the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) library. Run the application and enter `http://localhost:53929/swagger/` as URL on your browser:
The startup template is configured to run the [swagger UI](https://swagger.io/tools/swagger-ui/) using the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) library. Run the application and enter `http://localhost:53929/swagger/` as URL on your browser.

![bookstore-swagger](images/bookstore-swagger.png)
You will see some built-in service endpoints as well as the `Book` service and its REST-style endpoints:

You will see some built-in service endpoints as well as the `Book` service and its REST-style endpoints.
![bookstore-swagger](images/bookstore-swagger.png)

### Dynamic JavaScript Proxies

Expand All @@ -259,7 +256,7 @@ ABP **dynamically** creates JavaScript **proxies** for all API endpoints. So, yo

#### Testing in the Browser Developer Console

You can just test the JavaScript proxy using your Browser's Developer Console now. Open your browser's **developer tools** (shortcut: F12 key), switch to the **Console** tab, type the following code and press enter:
You can just test the JavaScript proxy using your favorite browser's **Developer Console** now. Run the application again, open your browser's **developer tools** (shortcut: F12), switch to the **Console** tab, type the following code and press enter:

````js
acme.bookStore.book.getList({}).done(function (result) { console.log(result); });
Expand All @@ -275,7 +272,9 @@ Running this code produces such an output:

![bookstore-test-js-proxy-getlist](images/bookstore-test-js-proxy-getlist.png)

You can see the **book list** returned from the server.
You can see the **book list** returned from the server. You can also check the **network** tab of the developer tools to see the client to server communication:

![bookstore-test-js-proxy-getlist-network](images/bookstore-test-js-proxy-getlist-network.png)

Let's **create a new book** using the `create` function:

Expand All @@ -293,7 +292,7 @@ Check the `books` table in the database to see the new book row. You can try `ge

### Create the Books Page

It's time to create something visible! Instead of classic MVC, we will use the new [Razor Pages UI](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) approach which is recommended by Microsoft.
It's time to create something visible and usable! Instead of classic MVC, we will use the new [Razor Pages UI](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) approach which is recommended by Microsoft.

Create a new `Books` folder under the `Pages` folder of the `Acme.BookStore.Web` project and add a new Razor Page named `Index.html`:

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 35a2011

Please sign in to comment.