ABP(ASP.NET core Multi PageWeb Application) 根据官网给的例子做的简单的页面

时间:2021-09-05 18:00:38

根据官网给的https://aspnetboilerplate.com/Pages/Articles/Introduction-With-AspNet-Core-And-Entity-Framework-Core-Part-1/index.htmlhttps://aspnetboilerplate.com/Pages/Articles/Introduction-With-AspNet-Core-And-Entity-Framework-Core-Part-2/index.html写的demo

 

第一步在 MyABP.Core的Authorization文件夹下面创建一个文件夹Tasks,并新增两个类

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Timing;

namespace MyABP.Authorization.Tasks
{
    [Table("AppTasks")]
    public class Task : Entity, IHasCreationTime
    {
        public const int MaxTitleLength = 256;
        public const int MaxDescriptionLength = 64 * 1024; //64KB

        [ForeignKey(nameof(AssignedPersonId))]
        public Person AssignedPerson { get; set; }
        public Guid? AssignedPersonId { get; set; }

        [Required]
        [StringLength(MaxTitleLength)]
        public string Title { get; set; }

        [StringLength(MaxDescriptionLength)]
        public string Description { get; set; }

        public DateTime CreationTime { get; set; }

        public TaskState State { get; set; }

        public Task()
        {
            CreationTime = Clock.Now;
            State = TaskState.Open;
        }

        public Task(string title, string description = null, Guid? assignedPersonId = null)
            : this()
        {
            Title = title;
            Description = description;
            AssignedPersonId = assignedPersonId;
        }
    }

    public enum TaskState : byte
    {
        Open = 0,
        Completed = 1
    }
}
using Abp.Domain.Entities.Auditing;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace MyABP.Authorization.Tasks
{
    [Table("AppPersons")]
    public class Person : AuditedEntity<Guid>
    {
        public const int MaxNameLength = 32;

        [Required]
        [StringLength(MaxNameLength)]
        public string Name { get; set; }

        public Person()
        {

        }

        public Person(string name)
        {
            Name = name;
        }
    }
}

第二步  新增好类之后,在MyABP.EntityFrameworkCore项目的MyABPDbContext中,新增代码

 public DbSet<Task> Tasks { get; set; }
 public DbSet<Person> People { get; set; }

将MyABP.EntityFrameworkCore作为启动项目,在管理器控制台中输入Add-Migration "Initial"回车 (注意这里的Initial的命名每次都应该是不同的)更新需要迁移的,更新完成之后,继续输入update-database回车,这样就将数据表更新到数据中

第三步 在MyABP.Application层新增一个文件夹Tasks,接着新增一个接口服务ITaskAppService.cs

using MyABP.Tasks.DTO;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace MyABP.Application.Tasks
{
    public interface ITaskAppService : IApplicationService
    {
        Task<ListResultDto<TaskListDto>> GetAll(GetAllTasksInput input);//用于查询任务列表
        Task Create(CreateTaskInput input);//创建任务
    }
}

这是我们需要创建三个类TaskListDto、GetAllTasksInput和CreateTaskInput,则我们在Tasks文件夹下面新增一个文件夹DTO用于管理这些类

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Entities.Auditing;
using MyABP.Authorization.Tasks;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace MyABP.Tasks.DTO
{
    public class GetAllTasksInput
    {
        public TaskState? State { get; set; }
    }

    [AutoMapFrom(typeof(Task))]
    public class TaskListDto : EntityDto, IHasCreationTime
    {
        public string Title { get; set; }

        public string Description { get; set; }

        public DateTime CreationTime { get; set; }

        public TaskState State { get; set; }
        public Guid? AssignedPersonId { get; set; }

        public string AssignedPersonName { get; set; }
    }
    [AutoMapTo(typeof(Task))]
    public class CreateTaskInput
    {
        [Required]
        [StringLength(Task.MaxTitleLength)]
        public string Title { get; set; }

        [StringLength(Task.MaxDescriptionLength)]
        public string Description { get; set; }

        public Guid? AssignedPersonId { get; set; }
    }
}
View Code

接着在Tasks文件夹中创建TaskAppService.cs类来实现ITaskAppService的接口方法

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
 using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Castle.Core.Logging;
using Microsoft.EntityFrameworkCore; 
using MyABP.Tasks.DTO;

namespace MyABP.Application.Tasks
{
    public class TaskAppService : MyABPAppServiceBase, ITaskAppService
    {
        private readonly IRepository<Authorization.Tasks.Task> _taskRepository;
         public TaskAppService(IRepository<Authorization.Tasks.Task> taskRepository)
        {
            _taskRepository = taskRepository; 
        }

        public async Task<ListResultDto<TaskListDto>> GetAll(GetAllTasksInput input)
        {
            var tasks = await _taskRepository
                .GetAll()
                .Include(t => t.AssignedPerson)
                .WhereIf(input.State.HasValue, t => t.State == input.State.Value)
                .OrderByDescending(t => t.CreationTime)
                .ToListAsync();

            return new ListResultDto<TaskListDto>(
                ObjectMapper.Map<List<TaskListDto>>(tasks)
            );
        }

        public async Task Create(CreateTaskInput input)
        {
            var task = ObjectMapper.Map<Authorization.Tasks. Task>(input);
            await _taskRepository.InsertAsync(task); 
        }


    }
}
View Code

 由于在官方文档的pass II部分创建了任务,还将任务指派给其他人,所以还需要做一个下拉框来装AppPersons表的查询出来的人员列表,则我们在Tasks文件夹中还需要定义一个ILookupAppService.cs接口

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using System.Threading.Tasks;

namespace MyABP.Application.Tasks
{
    public interface ILookupAppService : IApplicationService

    {
        Task<ListResultDto<ComboboxItemDto>> GetPeopleComboboxItems();
    } 
}
View Code

创建LookupAppService.cs来实现ILookupAppService的接口方法

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using MyABP.Authorization.Tasks;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace MyABP.Application.Tasks
{
    public class LookupAppService : MyABPAppServiceBase, ILookupAppService
    {
        private readonly IRepository<Person, Guid> _personRepository;

        public LookupAppService(IRepository<Person, Guid> personRepository)
        {
            _personRepository = personRepository;
        }

        public async Task<ListResultDto<ComboboxItemDto>> GetPeopleComboboxItems()
        {
            var people = await _personRepository.GetAllListAsync();
            return new ListResultDto<ComboboxItemDto>(
                people.Select(p => new ComboboxItemDto(p.Id.ToString("D"), p.Name)).ToList()
            );
        }


    }
}
View Code

第四步 在MyABP.Web.Mvc项目的Controllers控制器文件夹中新增一个TasksController.cs控制室

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using MyABP.Application.Tasks;
using MyABP.Controllers; 
using MyABP.Tasks.DTO;
using MyABP.Web.Models.Tasks;

namespace MyABP.Web.Controllers
{
    public class TasksController : MyABPControllerBase
    {
        private readonly ITaskAppService _taskAppService;
        private readonly ILookupAppService _lookupAppService;

        public TasksController(ITaskAppService taskAppService,
            ILookupAppService lookupAppService)
        {
            _taskAppService = taskAppService;
            _lookupAppService = lookupAppService;
        }

        public async Task<ActionResult> Index(GetAllTasksInput input)
        {
            var output = await _taskAppService.GetAll(input);
            var model = new IndexViewModel(output.Items)
            {
                SelectedTaskState = input.State
            };
            return View(model);
        }
        public async Task<ActionResult> Create()
        {
            var peopleSelectListItems = (await _lookupAppService.GetPeopleComboboxItems()).Items
                .Select(p => p.ToSelectListItem())
                .ToList();

            peopleSelectListItems.Insert(0, new SelectListItem { Value = string.Empty, Text = L("Unassigned"), Selected = true });

            return View(new CreateTaskViewModel(peopleSelectListItems));
        }
    }
}
View Code

这是我们需要在Models文件夹中新增类IndexViewModel和CreateTaskViewModel,则我们在Models文件夹下面新增一个文件夹Tasks用于管理这些类

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using Abp.Localization;
using Microsoft.AspNetCore.Mvc.Rendering;
using MyABP.Authorization.Tasks;
using MyABP.Tasks.DTO;
using System;
using System.Collections.Generic;
using System.Linq; 

namespace MyABP.Web.Models.Tasks
{
    public class IndexViewModel
    {
        public IReadOnlyList<TaskListDto> Tasks { get; }

        public IndexViewModel(IReadOnlyList<TaskListDto> tasks)
        {
            Tasks = tasks;
        }

        public string GetTaskLabel(TaskListDto task)
        {
            switch (task.State)
            {
                case TaskState.Open:
                    return "label-success";
                default:
                    return "label-default";
            }
        }


        public TaskState? SelectedTaskState { get; set; }

        public List<SelectListItem> GetTasksStateSelectListItems(ILocalizationManager localizationManager)
        {
            var list = new List<SelectListItem>
        {
            new SelectListItem
            {
                Text = localizationManager.GetString( MyABPConsts.LocalizationSourceName, "AllTasks"),
                Value = "",
                Selected = SelectedTaskState == null
            }
        };

            list.AddRange(Enum.GetValues(typeof(TaskState))
                    .Cast<TaskState>()
                    .Select(state =>
                        new SelectListItem
                        {
                            Text = localizationManager.GetString(MyABPConsts.LocalizationSourceName, $"TaskState_{state}"),
                            Value = state.ToString(),
                            Selected = state == SelectedTaskState
                        })
            );

            return list;
        }
    }
}
View Code ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyABP.Web.Models.Tasks
{
    public class CreateTaskViewModel
    {
        public List<SelectListItem> People { get; set; }

        public CreateTaskViewModel(List<SelectListItem> people)
        {
            People = people;
        }
    }
}
View Code

转回到Tasks控制器中,我们需要在Index方法里面右击鼠标,添加视图Index,接着我们进入Index.cshtml编写代码如下

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
@model MyABP.Web.Models.Tasks.IndexViewModel

@{
    ViewBag.Title = L("TaskList");
    ViewBag.ActiveMenu = "TaskList"; //Matches with the menu name in SimpleTaskAppNavigationProvider to highlight the menu item
}

    <h2>
        @L("TaskList")
        <span class="pull-right">
            @Html.DropDownListFor(
               model => model.SelectedTaskState,
               Model.GetTasksStateSelectListItems(LocalizationManager),
               new
               {
                   @class = "form-control",
                   id = "TaskStateCombobox"
               })
        </span>
    </h2>
    <a class="btn btn-primary btn-sm" asp-action="Create">@L("AddNew")</a>
<div class="row">
    <div>
        <ul class="list-group" id="TaskList">
            @foreach (var task in Model.Tasks)
            {
                <li class="list-group-item">
                    <span class="pull-right label @Model.GetTaskLabel(task)">@L($"TaskState_{task.State}")</span>
                    <h4 class="list-group-item-heading">@task.Title</h4>
                    <div class="list-group-item-text">
                        @task.CreationTime.ToString("yyyy-MM-dd HH:mm:ss")
                    </div>
                </li>
            }
        </ul>
    </div>
</div>
View Code

在Create方法里面右击鼠标,添加视图Create,接着我们进入Create.cshtml编写代码如下

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
@model MyABP.Web.Models.Tasks.CreateTaskViewModel

@section scripts
{
    <environment names="Development">
        <script src="~/view-resources/Views/Tasks/create.js"></script>
    </environment>
    
    <environment names="Staging,Production">
        <script src="~/view-resources/Views/Tasks/create.min.js"></script>
    </environment>
}

<h2>
    @L("NewTask")
</h2>

<form id="TaskCreationForm">

    <div class="form-group">
        <label for="Title">@L("Title")</label>
        <input type="text" name="Title" class="form-control" placeholder="@L("Title")" required maxlength="@MyABP.Authorization.Tasks.Task.MaxTitleLength">
    </div>

    <div class="form-group">
        <label for="Description">@L("Description")</label>
        <input type="text" name="Description" class="form-control" placeholder="@L("Description")" maxlength="@MyABP.Authorization.Tasks.Task.MaxDescriptionLength">
    </div>

    <div class="form-group">
        @Html.Label(L("AssignedPerson"))
        @Html.DropDownList(
            "AssignedPersonId",
            Model.People,
            new
            {
                @class = "form-control",
                id = "AssignedPersonCombobox"
            })
    </div>

    <button type="submit" class="btn btn-default">@L("Save")</button>

</form>
View Code

这里我们需要创建一个js,在wwwroot文件夹的view-resources的Views中新增一个Tasks文件夹 ,创建create.js  代码如下

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面
(function ($) {
    $(function () {

        var _$form = $(#TaskCreationForm);

        _$form.find(input:first).focus();

        _$form.validate();

        _$form.find(button[type=submit])
            .click(function (e) {
                e.preventDefault();

                if (!_$form.valid()) {
                    return;
                }

                var input = _$form.serializeFormToObject();
                abp.services.app.task.create(input)
                    .done(function () {
                        location.href = /Tasks;
                    });
            });
    });
})(jQuery);
View Code

第五步 在MyABP.Web.Mvc项目的Startup文件夹的MyABPNavigationProvider.cs中的SetNavigation方法中插入代码

.AddItem(
                new MenuItemDefinition(
                    "TaskList",
                    L("TaskList"),
                    url: "Tasks",
                    icon: "info"//图标
// requiredPermissionName: PermissionNames.Pages_Roles权限
                    )
            )

最后,在AppPersons中新增两个人名,这样下拉框就有数据了,运行代码则可以看到

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面

 

 点击Add New

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面

 

 保存之后,js代码中写了自动返回Tasks页面

ABP(ASP.NET core  Multi PageWeb Application) 根据官网给的例子做的简单的页面