ASP.NET Core MVC / Razor页面教程-第1部分 列表展示(根据官网教程)

目录

 

1、创建书籍实体

2、将书籍实体添加到DbContext

3、配置Book实体

4、添加新的迁移并更新数据库

5、添加初始(样本)数据

6、创建应用程序服务

7、在浏览器的开发人员控制台中进行测试

8、创建书籍页面

9、将书籍页面添加到主菜单

10、本地化菜单项

11、图书清单


1、创建书籍实体

启动模板中的域层分为两个项目:

  • ABPBookStore.Domain包含您的实体域服务和其他核心域对象。
  • ABPBookStore.Domain.Shared包含那些能够与客户共享的constantsenums或其他领域相关的对象。

在解决方案的域层Acme.BookStore.Domain 项目)中定义实体。应用程序的主要实体是Book。在Acme.BookStore.Domain项目中创建一个名为 Book的类,如下所示:

using System;
using Volo.Abp.Domain.Entities.Auditing;

namespace  ABPBookStore
{
    public class Book : AuditedAggregateRoot<Guid>
    {
        public string Name { get; set; }

        public BookType Type { get; set; }

        public DateTime PublishDate { get; set; }

        public float Price { get; set; }

        protected Book()
        {

        }

        public Book(Guid id, string name, BookType type, DateTime publishDate, float price) :
            base(id)
        {
            Name = name;
            Type = type;
            PublishDate = publishDate;
            Price = price;
        }
    }
}

  • ABP对于实体有2个基本基类:AggregateRoot(聚合根Entity聚合根域驱动设计(DDD)概念之一。
  • Book实体继承AuditedAggregateRoot它在AggregateRoot类顶部增加了一些审核性质(CreationTimeCreatorIdLastModificationTime...等)。
  • GuidBook实体的主键类型

BookType枚举

ABPBookStore.Domain.Shared项目中创建枚举BookType:

namespace  ABPBookStore
{
    public enum BookType
    {
        Undefined,
        Adventure,
        Biography,
        Dystopia,
        Fantastic,
        Horror,
        Science,
        ScienceFiction,
        Poetry
    }
}

2、将书籍实体添加到DbContext

EF Core要求将实体与您的DbContext关联。最简单的方法是在ABPBookStore.EntityFrameworkCore项目的ABPBookStoreDbContext类中添加一个DbSet属性,如下所示:

public DbSet<Book> Books { get; set; }

3、配置Book实体

ABPBookStore.EntityFrameworkCore项目中打开ABPBookStoreDbContextModelCreatingExtensions.cs文件,并将以下代码添加到ConfigureBookStore方法的末尾以配置Book实体:

builder.Entity<Book>(b =>
            {
                b.ToTable(ABPBookStoreConsts.DbTablePrefix + "Books", ABPBookStoreConsts.DbSchema);
                b.ConfigureByConvention(); //auto configure for the base class props
                b.Property(x => x.Name).IsRequired().HasMaxLength(128);
            });

并添加相应引用

4、添加新的迁移并更新数据库

启动模板使用EF Core Code First Migrations来创建和维护数据库架构。在菜单>工具> NuGet软件包管理器下打开软件包管理器控制台(PMC)

选择ABPBookStore.EntityFrameworkCore.DbMigrations作为默认项目并执行以下命令:

Add-Migration "Created_Book_Entity"

这将在ABPBookStore.EntityFrameworkCore.DbMigrations项目的Migrations文件夹内创建一个新的迁移类。然后执行Update-Database命令以更新数据库架构:

5、添加初始(样本)数据

Update-Database命令已在数据库中创建AppBooks表。打开数据库并输入一些示例行,这样就可以在列表页面上显示它们。

INSERT INTO AppBooks (Id,CreationTime,Name,Type,PublishDate,Price) VALUES

('f3c04764-6bfd-49e2-859e-3f9bfda6183e', '2018-07-01', '1984',3,'1949-06-08','19.84');

INSERT INTO AppBooks (Id,CreationTime,Name,Type,PublishDate,Price) VALUES

('13024066-35c9-473c-997b-83cd8d3e29dc', '2018-07-01', 'The Hitchhiker`s Guide to the Galaxy',7,'1995-09-27','42');

INSERT INTO AppBooks (Id,CreationTime,Name,Type,PublishDate,Price) VALUES

('4fa024a1-95ac-49c6-a709-6af9e4d54b54', '2018-07-02', 'Pet Sematary',5,'1983-11-14','23.7');

6、创建应用程序服务

下一步是创建一个应用程序服务来管理图书,这将使我们具有四个基本功能:创建,阅读,更新和删除。应用程序层分为两个项目:

  • ABPBookStore.Application.Contracts主要包含您的DTO和应用程序服务接口。
  • ABPBookStore.Application 包含您的应用程序服务的实现。

BookDto

ABPBookStore.Application.Contracts项目中创建一个命名为BookDto的DTO类:

namespace ABPBookStore
{
    public class BookDto : AuditedEntityDto<Guid>
    {
        public string Name { get; set; }

        public BookType Type { get; set; }

        public DateTime PublishDate { get; set; }

        public float Price { get; set; }
    }
}

  • DTO类用于在表示层应用程序层之间传输数据。有关更多详细信息,请参见“ 数据传输对象”文档
  • BookDto 用于将书籍数据传输到表示层,以便在UI上显示书籍信息。
  • BookDtoAuditedEntityDto<Guid>派生,其具有审核属性,就像上面定义的Book类一样。

在将书籍返回到表示层时,需要将Book实体映射到BookDto对象。当您定义正确的映射时,AutoMapper库可以自动执行此转换。启动模板配置了AutoMapper,因此您只需在ABPBookStore.Application项目的ABPBookStoreApplicationAutoMapperProfile类中定义映射即可:

public ABPBookStoreApplicationAutoMapperProfile()
        {
            CreateMap<Book, BookDto>();
          
        }


CreateUpdateBookDto

ABPBookStore.Application.Contracts项目中创建一个名为CreateUpdateBookDto的DTO类:

public class CreateUpdateBookDto
    {
        [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; }
    }

  • 此类DTO用于在创建或更新书籍时从用户界面获取书籍信息。
  • 它定义了数据注释属性(如[Required])来定义对属性的验证。DTO会由ABP框架自动验证

接下来,使用以下命令添加ABPBookStoreApplicationAutoMapperProfileCreateUpdateBookDto对象到Book实体的映射CreateMap<CreateUpdateBookDto, Book>();

public ABPBookStoreApplicationAutoMapperProfile()
        {
            CreateMap<Book, BookDto>();
            CreateMap<CreateUpdateBookDto, Book>();
        }

IBookAppService

ABPBookStore.Application.Contracts项目中创建一个名为IBookAppService的接口:

using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;

namespace ABPBookStore
{
    public interface IBookAppService :
        ICrudAppService< //Defines CRUD methods
            BookDto, //Used to show books
            Guid, //Primary key of the book entity
            PagedAndSortedResultRequestDto, //Used for paging/sorting on getting a list of books
            CreateUpdateBookDto, //Used to create a new book
            CreateUpdateBookDto> //Used to update a book
    {

    }
}

  • 框架不需要为应用程序服务定义接口。但是,建议将其作为最佳实践。
  • ICrudAppService定义了通用CRUD方法:GetAsyncGetListAsyncCreateAsyncUpdateAsyncDeleteAsync。不需要扩展。相反,您可以从空IApplicationService接口继承并手动定义自己的方法。
  • ICrudAppService对于每种方法,可以在其中使用单独的DTO 有所不同。

BookAppService

在Acme.BookStore.Application项目中以BookAppService实现IBookAppService

using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ABPBookStore
{
    public class BookAppService :
         CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto,
                        CreateUpdateBookDto, CreateUpdateBookDto>,
         IBookAppService
    {
        public BookAppService(IRepository<Book, Guid> repository)
            : base(repository)
        {

        }
    }
}

  • BookAppService派生自CrudAppService<...>,它实现了上面定义的所有CRUD(创建,读取,更新,删除)方法。
  • BookAppService注入IRepository<Book, Guid>这是Book实体的默认存储库。ABP自动为每个聚合根(或实体)创建默认存储库。
  • BookAppService使用IObjectMapper,Book对象映射到BookDto对象以及将CreateUpdateBookDto对象映射到Book对象。启动模板使用AutoMapper库作为对象映射提供程序。我们之前已经定义了映射,因此它将按预期工作。

7、在浏览器的开发人员控制台中进行测试

您可以使用喜欢的浏览器的开发者控制台轻松测试JavaScript代理。运行应用程序,打开浏览器的开发人员工具Chrome的快捷方式是F12),切换到“ 控制台”选项卡,键入以下代码,然后按Enter:

aBPBookStore.book.getList({}).done(function (result) { console.log(result); });

  • aBPBookStoreBookAppService的命名空间转换为camelCase的名称空间。
  • book是的常规名称BookAppService(删去AppService后缀并转换为camelCase)。
  • getListAsyncCrudAppService基类中GetListAsync定义的方法的常规名称(删除Async后缀并转换为camelCase)。
  • {}参数用于将空对象发送到GetListAsync方法,该方法通常需要一个PagedAndSortedResultRequestDto用于将分页和排序选项发送到服务器的类型的对象(所有属性都是可选的,因此您可以发送空对象)。
  • getList函数返回一个promise。您可以将回调传递给done(或then)函数,以从服务器获取结果。

让我们使用create函数创建一本新书

检查Books数据库中的表以查看新书行。可以试试getupdatedelete功能。

8、创建书籍页面

这时候应该创建可见的和可用的东西了!代替经典的MVC,我们将使用Microsoft建议的新的Razor Pages UI方法。

ABPBookStore.Web项目Pages文件夹下创建文件夹Books。右键单击“ Books”文件夹,然后选择“ 添加”>“ Razor页面”菜单项,以添加新的Razor页面。命名为Index,打开Index.cshtml并更改整个内容,如下所示

@page
@using ABPBookStore.Web.Pages.Books
@inherits ABPBookStore.Web.Pages.ABPBookStorePage
@model IndexModel

<h2>Books</h2>

注:这个地方不知道为什么没有自动生成的ABPBookStorePage类,所以在ABPBookStore.Web项目Pages文件夹下创建ABPBookStorePage.cs,修改代码如下

using ABPBookStore.Localization;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;

namespace ABPBookStore.Web.Pages
{
    public abstract class ABPBookStorePage : AbpPage
    {
        [RazorInject]
        public IHtmlLocalizer<ABPBookStoreResource> L { get; set; }
    }
}

 

  • 此代码更改了Razor视图页面模型的默认继承,因此它继承ABPBookStorePage该类(而不是PageModel)。ABPBookStorePage启动模板随附的类提供了所有页面使用的一些共享属性/方法。

  •  在Index.cshtml.cs中IndexModel的命名空间设置为ABPBookStore.Pages.Books

using Microsoft.AspNetCore.Mvc.RazorPages;

namespace ABPBookStore.Web.Pages.Books
{
    public class IndexModel : PageModel
    {
        public void OnGet()
        {

        }
    }
}

9、将书籍页面添加到主菜单

打开文件夹Menus中的ABPBookStoreMenuContributor类,并将以下代码添加到ConfigureMainMenuAsync方法的末尾:

context.Menu.AddItem(
                new ApplicationMenuItem("BooksStore", l["Menu:BookStore"])
                    .AddItem(
                        new ApplicationMenuItem("BooksStore.Books", l["Menu:Books"], url: "/Books")
                    )
            );

10、本地化菜单项

本地化文本位于ABPBookStore.Domain.Shared项目的Localization/ABPBookStore文件夹下:

 

打开en.json文件,并将以下本地化文本添加到文件末尾:

{
  "culture": "en",
  "texts": {
    "Menu:Home": "Home",
    "Welcome": "Welcome",
    "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.",
   
    "Menu:BookStore": "Book Store",
    "Menu:Books": "Books",
    "Actions": "Actions",
    "Edit": "Edit",
    "PublishDate": "Publish date",
    "NewBook": "New book",
    "Name": "Name",
    "Type": "Type",
    "Price": "Price",
    "CreationTime": "Creation time",
    "AreYouSureToDelete": "Are you sure you want to delete this item?"
  }
}

  • ABP的本地化系统基于ASP.NET Core的标准本地化系统,并以多种方式进行了扩展。
  • 本地化关键字名称是任意的。您可以设置任何名称。作为最佳实践,我们希望Menu:为菜单项添加前缀以区别于其他文本。如果未在本地化文件中定义文本,则文本将回退到本地化键(作为ASP.NET Core的标准行为)。

11、图书清单

我们将使用Datatables.net jQuery插件显示图书清单。数据表可以通过AJAX完全工作,它快速,流行并且提供了良好的用户体验。Datatables插件是在启动模板中配置的,因此您可以在任何页面中直接使用它,而无需在页面中包含任何样式或脚本文件。


Index.cshtml

更改Pages/Books/Index.cshtml如下:

@page
@inherits ABPBookStore.Web.Pages.ABPBookStorePage
@model ABPBookStore.Web.Pages.Books.IndexModel
@section scripts
{
    <abp-script src="/Pages/Books/index.js" />
}
<abp-card>
    <abp-card-header>
        <h2>@L["Books"]</h2>
    </abp-card-header>
    <abp-card-body>
        <abp-table striped-rows="true" id="BooksTable">
            <thead>
                <tr>
                    <th>@L["Name"]</th>
                    <th>@L["Type"]</th>
                    <th>@L["PublishDate"]</th>
                    <th>@L["Price"]</th>
                    <th>@L["CreationTime"]</th>
                </tr>
            </thead>
        </abp-table>
    </abp-card-body>
</abp-card>

  • abp-script 标记帮助程序用于将外部脚本添加到页面。与标准script标签相比,它具有许多其他功能。它处理缩小版本控制
  • abp-cardabp-table是Twitter Bootstrap card组件的标签帮助器。ABP中还有其他有用的标签帮助程序,可以轻松使用大多数引导程序组件。您也可以使用常规HTML标记代替这些标记帮助器,但是使用标记帮助器可以减少HTML代码并通过IntelliSense和编译时类型检查来防止错误。
  • 您可以像上面的菜单项一样在本地化文件中本地化列名。

添加脚本文件

在该Pages/Books/文件夹下创建JavaScript文件index.js

index.js 内容如下所示:

$(function () {
    var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
        ajax: abp.libs.datatables.createAjax(aBPBookStore.book.getList),
        columnDefs: [
            { data: "name" },
            { data: "type" },
            { data: "publishDate" },
            { data: "price" },
            { data: "creationTime" }
        ]
    }));
});

  • abp.libs.datatables.createAjax是帮助ABP的动态JavaScript API代理适应Datatable格式的辅助函数。
  • abp.libs.datatables.normalizeConfiguration是另一个助手功能。不需要使用它,但是它通过为丢失的选项提供常规值来简化Datatables配置。
  • aBPBookStore.book.getList是获取图书清单的功能(如动态JavaScript代理中所述)。
  • 这部分到此结束。这项工作的最终用户界面如下所示:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值