Browse Source

Added new sections to the asp.net core mvc tutorial.

pull/318/head
Halil ibrahim Kalkan 8 years ago
parent
commit
d69bd0ac49
  1. 7
      docs/Getting-Started-AspNetCore-MVC-Template.md
  2. 156
      docs/Tutorials/AspNetCore-Mvc/Part-I.md
  3. BIN
      docs/images/bookstore-swagger.png
  4. BIN
      docs/images/bookstore-test-js-proxy-getlist.png

7
docs/Getting-Started-AspNetCore-MVC-Template.md

@ -8,6 +8,13 @@ Go to [the template creation page](https://abp.io/Templates), enter a project na
When you click to the *create* button, a new Visual Studio solution is created and downloaded with the name you have provided.
#### Pre Requirements
The downloaded project requires;
* [Visual Studio 2017 (v15.7.0+)](https://visualstudio.microsoft.com/tr/downloads/)
* [.NET Core 2.1.1+](https://www.microsoft.com/net/download/dotnet-core/)
### The Solution Structure
Open the zip file downloaded and open in **Visual Studio 2017 (15.7.0+)**:

156
docs/Tutorials/AspNetCore-Mvc/Part-I.md

@ -1,11 +1,15 @@
## ASP.NET Core MVC Tutorial - Part I
> This tutorial assumes that you have created a new project, named `Acme.BookStore` from [the startup templates](https://abp.io/Templates).
### About the Tutorial
In this tutorial series, you will build an application that is used to manage a list of books & their authors. **Entity Framework Core** (EF Core) will be used as the ORM provider (as it comes pre-configured with the startup template).
You can download the **source code** of the application [from here](https://github.com/volosoft/abp/tree/master/samples/BookStore).
### Creating the Project
This tutorial assumes that you have created a new project, named `Acme.BookStore` from [the startup templates](https://abp.io/Templates).
### Solution Structure
This is the layered solution structure created from the startup template:
@ -101,4 +105,150 @@ PM> Update-Database
The next step is to create an [application service](../../Application-Services.md) to manage (create, list, update, delete...) books.
TODO...
#### BookDto
Create a DTO class named `BookDto` into the `Acme.BookStore.Application` project:
````C#
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore
{
public class BookDto : EntityDto<Guid>
{
[Required]
[StringLength(128)]
public string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
````
* **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.
#### IBookAppService
First, define an interface named `IBookAppService` for the book application service:
````C#
using System;
using Volo.Abp.Application.Services;
namespace Acme.BookStore
{
public interface IBookAppService : IAsyncCrudAppService<BookDto, Guid>
{
}
}
````
* 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.
* There are some variations of the `IAsyncCrudAppService`. In this sample, the first generic parameter, `BookDto`, is the DTO used for service methods and the second parameter, `Guid`, is the type of the primary key of the entity.
#### BookAppService
Implement the `IBookAppService` as named `BookAppService`:
````C#
using System;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookAppService : AsyncCrudAppService<Book, BookDto, Guid>, IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
}
}
}
````
* `BookAppService` is derived from `AsyncCrudAppService<Book, BookDto, Guid>` which implements all CRUD methods defined above.
* `BookAppService` injects `IRepository<Book, Guid>` which is the default repository created for the `Book` entity. See the [repository document](../../Repositories.md).
### 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.
#### 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:
![bookstore-swagger](../../images/bookstore-swagger.png)
You will see some built-in service endpoints as well as the `Book` service and its REST-style service endpoints.
### Dynamic JavaScript Proxies
It's common to call HTTP API endpoints via AJAX from the **JavaScript** side. You can use `$.ajax` or another tool to call the endpoints. However, ABP offers a better way.
ABP **dynamically** creates JavaScript **proxies** for all API endpoints. So, you can use any **endpoint** just like calling a **JavaScript function**.
#### 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:
````js
acme.bookStore.book.getList({}).done(function (result) { console.log(result); });
````
* `acme.bookStore` is the namespace of the `BookAppService` converted to [camelCase](https://en.wikipedia.org/wiki/Camel_case).
* `book` is the conventional name for the `BookAppService` (removed AppService postfix and converted to camelCase).
* `getList` is the conventional name for the `GetListAsync` method defined in the `AsyncCrudAppService` base class (removed Async postfix and converted to camelCase).
* `{}` argument is used to send an empty object to the `GetListAsync` method which normally expects an object of type `PagedAndSortedResultRequestDto` which is used to send paging and sorting options to the server.
* `getList` function returns a `promise`. So, you can pass a callback to the `done` (or `then`) function to get the result from the server.
Running this code produces such an output:
![bookstore-test-js-proxy-getlist](D:\Github\abp\docs\images\bookstore-test-js-proxy-getlist.png)
You can see the **book list** returned from the server.
Let's **create a new book** using the `create` function:
````js
acme.bookStore.book.create({
name: 'Foundation',
type: 7,
publishDate: '1951-05-24',
price: 21.5
}).done(function (result) {
console.log('successfully created the book with id: ' + result.id);
});
````
You should see a message in the console something like that:
````
successfully created the book with id: f3f03580-c1aa-d6a9-072d-39e75c69f5c7
````
Check the `books` table in the database to see the new book row. You can also try `get`, `update` and `delete` functions.
### Create the Book List Page
TODO...

BIN
docs/images/bookstore-swagger.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/images/bookstore-test-js-proxy-getlist.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Loading…
Cancel
Save