ABP框架官网例子实践(1)(ASP.NET core+Multi Page Web Application)

第三步:开始在Application中进行编写代码

1、为app service定义一个接口ITaskAppService,在接口中使用GetAll方法来查询任务。ListResultDto是一个包含项目列表的简单类(我们可以直接返回List <TaskListDto>)。

using Abp.Application.Services;
using Abp.Application.Services.Dto;
using MPACore.Application.Tasks.Dto;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;namespace MPACore.Application.Tasks
{public interface ITaskAppService:IApplicationService{Task<ListResultDto<TaskListDto>> GetAll(GetAllTasksInput input);//用于查询任务列表}
}

2、在Tasks文件夹下创建Dto文件夹,在Dto文件夹下,

(1)创建一个GetAllTasksInput

GetAllTasksInput DTO定义了GetAll应用程序服务方法的输入参数。没有直接将状态定义为方法参数,而是将其添加到DTO对象中。因此,可以以后往DTO中添加其他参数,而不会破坏现有的客户机(我们可以直接向方法中添加一个状态参数)。

using Abp.Domain.Entities.Auditing;
using MPACore.Core.Tasks;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;namespace MPACore.Application.Tasks.Dto
{public class GetAllTasksInput{public TaskState? State { get; set; }}}

(2)创建一个TaskListDto

TaskListDto用于返回任务数据。它派生自EntityDto,后者只定义了一个id属性(我们可以将id添加到我们的Dto中,而不是派生自EntityDto)。我们定义了[AutoMapFrom]属性来创建从任务实体(Task)到TaskListDto的自动映射。这个属性是在 Abp.AutoMapper nuget包中定义的。

using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Entities.Auditing;
using MPACore.Core.Tasks;
using System;namespace MPACore.Application.Tasks.Dto
{[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; }}
}

3、在Tasks文件夹中创建TaskAppService来实现ITaskAppService的接口方法。

TaskAppService派生自启动模板中包含的MPACoreAppServiceBase(派生自ABP的ApplicationService类)。这不是必需的,应用程序服务可以是普通类。但是ApplicationService基类有一些预先注入的服务(如这里使用的ObjectMapper)。

使用依赖注入( dependency injection)来获得一个存储库( repository)。

存储库(Repositories)用于抽象实体的数据库操作。ABP为每个实体创建一个预定义的存储库(如IRepository<Task>)来执行通用任务。这里使用的IRepository.GetAll()返回一个用于查询实体的IQueritable。

WhereIf是ABP的扩展方法,用于简化IQueryable.Where方法的条件用法。

ObjectMapper(它来自ApplicationService基类,默认情况下通过AutoMapper实现)用于将Task对象的列表映射到TaskListDtos对象的列表。

using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using MPACore.Application.Tasks.Dto;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace MPACore.Application.Tasks
{public class TaskAppService: MPACoreAppServiceBase,ITaskAppService{private readonly IRepository<Core.Tasks.Task> _taskRepository;public TaskAppService(IRepository<Core.Tasks.Task> taskRepository){_taskRepository = taskRepository;}public async Task<ListResultDto<TaskListDto>> GetAll(GetAllTasksInput input){var tasks = await _taskRepository.GetAll().WhereIf(input.State.HasValue, t => t.State == input.State.Value).OrderByDescending(t => t.CreationTime).ToListAsync();return new ListResultDto<TaskListDto>(ObjectMapper.Map<List<TaskListDto>>(tasks));}}
}

注意:下面圈起来的部分,这个Task是我们创建的实体,要写清楚,不然会出错。

4、返回任务列表中指定的人员:更改TaskAppService以返回指定的人员信息

(1)在TaskListDto中添加两个属性

 public Guid? AssignedPersonId { get; set; }public string AssignedPersonName { get; set; }

(2)在TaskAppService中,添加Include行,将Task.AssignedPerson属性设置为查询

GetAll方法将返回分配给任务的人员信息。由于我们使用AutoMapper,新的属性也会自动复制到DTO。

到目前为止,程序已经能够运行了。

下面开始实现功能:

第 四步:在Web层,实现任务列表视图(创建一个页面来列出所有的任务)

1、在MPACoreNavigationProvider中添加新的菜单项(在首页添加菜单项)

.AddItem(new MenuItemDefinition("TaskList",L("TaskList"),url: "Tasks",icon: "tasks"))

2、创建控制器和视图

(1)创建控制器TasksController,所在位置如图:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MPACore.Application.Tasks;
using MPACore.Application.Tasks.Dto;
using MPACore.Web.Models.Tasks;namespace MPACore.Web.Controllers
{public class TasksController : MPACore.Controllers.MPACoreControllerBase{private readonly ITaskAppService _taskAppService;public TasksController(ITaskAppService taskAppService){_taskAppService = taskAppService;}public async Task<ActionResult> Index(GetAllTasksInput input){var output = await _taskAppService.GetAll(input);var model = new IndexViewModel(output.Items);return View(model);}}
}

控制器派生自MPACoreAppControllerBase(它派生自AbpController),它包含这个应用程序中控制器的公共基代码。为了获得任务列表,注入了ITaskAppService。这里没有直接将GetAll方法的结果传递给视图,而是在Web项目中创建了一个IndexViewModel类。这个简单的视图模型在其构造函数中获取一个任务列表(由ITaskAppService提供)。它还具有GetTaskLabel方法,该方法将在视图中用于为给定的任务选择引导标签类。

(2)创建IndexViewModel

这个简单的视图模型在其构造函数中获取一个任务列表(由ITaskAppService提供)。它还具有GetTaskLabel方法,该方法将在视图中用于为给定的任务选择引导标签类。

位置如图:

using MPACore.Application.Tasks.Dto;
using MPACore.Core.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;namespace MPACore.Web.Models.Tasks
{public class IndexViewModel{public IReadOnlyList<TaskListDto> Tasks { get; }public IndexViewModel(IReadOnlyList<TaskListDto> task){Tasks = task;}public string GetTaskLabel(TaskListDto task){switch (task.State){case TaskState.Open:return "label-success";default:return "label-default";}}}
}

第五步:实现具体功能

1、创建任务列表页面

在控制器页面的Index上右击添加视图,自己选择应该存放的位置,然后Index视图就创建成功了,位置如下图

@model MPACore.Web.Models.Tasks.IndexViewModel
@{ViewBag.Title = L("TaskList");ViewBag.ActiveMenu = "TaskList";
}<h2>@L("TaskList")</h2><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>

这里只是使用给定的模型来使用Bootstrap的列表组组件呈现视图。在这里,使用IndexViewModel.GetTaskLabel()方法来获取任务的标签类型。渲染的页面将是这样的

2、本地化

从ABP框架的角度使用L方法。 它用于本地化字符串。

中文本地化如下所示:

3、筛选任务

TaskController实际上获得一个GetAllTasksInput,可用于过滤任务。因此,我们可以添加一个下拉列表视图来过滤任务。

(1)在视图中添加下拉菜单

在上面的Index.cshtml中添加代码如下图:

 <span class="pull-right">@Html.DropDownListFor(model => model.SelectedTaskState,Model.GetTasksStateSelectListItems(LocalizationManager),new{@class = "form-control",id = "TaskStateCombobox"})</span>

更改IndexViewModel,添加SelectedTaskState属性和GetTasksStateSelectListItems方法

直接在原有的代码中添加下面的代码(注意:MPACoreConsts根据框架的名字自己修改)

 public TaskState? SelectedTaskState { get; set; }public List<SelectListItem> GetTasksStateSelectListItems(ILocalizationManager localizationManager){var list = new List<SelectListItem>{new SelectListItem{Text = localizationManager.GetString(MPACoreConsts.LocalizationSourceName, "AllTasks"),Value = "",Selected = SelectedTaskState == null}};list.AddRange(Enum.GetValues(typeof(TaskState)).Cast<TaskState>().Select(state =>new SelectListItem{Text = localizationManager.GetString(MPACoreConsts.LocalizationSourceName, $"TaskState_{state}"),Value = state.ToString(),Selected = state == SelectedTaskState}));return list;}

可以在写的过程中同时本地化成中文

在控制器(TaskController)中设置SelectedTaskState

(2)实现筛选功能

编写一个简单的JavaScript代码实现

(function ($) {$(function () {var _$taskStateCombobox = $('#TaskStateCombobox');_$taskStateCombobox.change(function () {location.href = '/Tasks?state=' + _$taskStateCombobox.val();});});
})(jQuery);

在将这个JavaScript文件包含到视图之前,使用Bundler & Minifier VS extension(这是在ASP.NET core中缩小文件的默认方式)来缩小脚本。

缩小脚本后,自动生成对应的min文件,自动配置好 bundleconfig.json

改变index.js中的内容,index.min.js也会自动重新生成。

使用这段代码,视图将在开发中使用index.js,在生产中使用index.min.js(缩小版)。这是ASP.NET core MVC中常用的方法。

现在,可以将JavaScript文件包含到页面(Index.cshtml)中

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

4、在“任务列表”页面中显示分配的人员名称

修改Index.cshtml 页面,显示  AssignedPersonName

5、创建任务(用于任务创建的新Application Service)

(1)创建CreateTaskInput类,位置如下图

创建方法自动将给定的输入映射到任务实体,并使用存储库将其插入到数据库中。 配置为将其映射到任务实体(使用AutoMapTo属性)并添加数据注释以应用验证。最大长度使用的是任务实体中定义的最大长度。

using Abp.AutoMapper;
using MPACore.Core.Tasks;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;namespace MPACore.Application.Tasks.Dto
{[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; }}
}

(2)在ITaskAppService接口中,添加一个创建(create)方法

(3)在TaskAppService中实现创建方法

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

6、创建一个添加任务的页面

(1)ILookupAppService是提供组合物品的,LookupAppService是实现ILookupAppService接口的类,创建位置如图:

using Abp.Application.Services;
using Abp.Application.Services.Dto;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;namespace MPACore.Application.Tasks
{public interface ILookupAppService:IApplicationService{Task<ListResultDto<ComboboxItemDto>> GetPeopleComboboxItems();}
}
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using MPACore.Core.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace MPACore.Application.Tasks
{public class LookupAppService : MPACoreAppServiceBase, 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());}}
}

ComboboxItemDto是一个简单的类(在ABP中定义),用于传输combobox项数据。TaskController.Create方法:简单地使用这个方法将返回的列表转换为SelectListItem列表(在Asp.Net Core中定义),并使用CreateTaskViewModel类传递给视图

(2)创建CreateTaskViewModel类

using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;namespace MPACore.Web.Models.People
{public class CreateTaskViewModel{public List<SelectListItem> People { get; set; }public CreateTaskViewModel(List<SelectListItem> people){People = people;}}
}

(3)在TaskController控制器中添加create操作

依赖注入了ILookupAppService服务,这个服务是用来给人们提供组合物品的。虽然可以在这里直接注入和使用IRepository<Person, Guid>,但这样做可以更好地实现分层和可重用性。

(截图里面少了一行代码,下面的代码是正确的)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using MPACore.Application.Tasks;
using MPACore.Application.Tasks.Dto;
using MPACore.Web.Models.People;
using MPACore.Web.Models.Tasks;namespace MPACore.Web.Controllers
{public class TasksController : MPACore.Controllers.MPACoreControllerBase{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));}}
}

(4) 创建create.js,然后的步骤和上面的index.js一样进行压缩

(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);

这个文件中jQuery实现了什么:

a、准备表单验证(使用jquery验证插件),并在单击Save按钮时进行验证。

b、使用jquery插件的serializeFormToObject (在解决方案中定义为jquery-extensions.js)将表单数据转换为JSON对象(将jquery-extensions.js包含到 _Layout.cshtml 中作为最后一个脚本文件)。

c、使用abp.services.task.create方法来调用TaskAppService.create方法。这是ABP的重要特性之一,我们可以从JavaScript代码中使用应用程序服务,就像在代码中调用JavaScript方法一样。

(5)创建视图(Create.cshtml)


@using MPACore.Web.Models.People
@model 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="@MPACore.Core.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="@MPACore.Core.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>

画框的部分要根据自己的情况进行修改

(6)添加一个按钮,在Index.cshtml 中实现

在任务列表页面中添加了一个“Add Task”按钮,以便导航到任务创建页面

到这里项目就完成啦!

ABP框架官网例子实践(2)(ASP.NET core+Multi Page Web Application)相关推荐

  1. ABP 框架官网学习资料

    ABP是"ASP.NET Boilerplate Project (ASP.NET样板项目)"的简称. [新思想.新技术.新架构--更好更快的开发现代ASP.NET应用程序] AS ...

  2. OpenLayers 官网例子的中文详解

    当你希望实现某种功能的时候,即使你对 openlayers 几乎一窍不通,照着官网的例子做,也可以很快的实现想要的效果. 问题在于,官网的例子都是英文啊,不能很快定位到想要的效果是在哪个例子里面!!( ...

  3. layer添加元素 openlayer_OpenLayers 官网例子的中文详解

    当你希望实现某种功能的时候,即使你对 openlayers 几乎一窍不通,照着官网的例子做,也可以很快的实现想要的效果. 问题在于,官网的例子都是英文啊,不能很快定位到想要的效果是在哪个例子里面!!( ...

  4. abp .net core linux,Abp vNext框架 从空项目开始 使用ASP.NET Core Web Application-笔记

    参考 abp vnext框架 从空项目开始 使用asp.net core web application rynowak的回答 migrate from asp.net core 2.2 to 3.0 ...

  5. easyx官网例子初试

    目录 基础 easyx简介 透明贴图和三元光栅操作 精确延时 程序 自由运动的点 冰封的EasyX 火焰效果 烟花 水波 迷宫 纪念披头士摇滚乐队 基础 easyx简介 在官网安装包里面有个easyx ...

  6. 根据官网例子一步步实现vueSSR(详细)

    根据 官网例子一步步实现vue ssr 标题对应官网标题 文章目录 基本用法 模版插值 源码结构 使用 webpack 的源码结构(vue-cli3) 构建配置 服务端 路由和代码分割 图片未加载,引 ...

  7. C#建站框架官网:CSFramework.CMS内容管理系统

    C#建站框架官网:CSFramework.CMS内容管理系统 产品详情:CSFramework.CMS内容管理系统-适用开发博客.论坛.文档知识库Web网站应用程序https://www.csfram ...

  8. Vue3官网-高级指南(十五)Vue 与 Web Components

    Vue3官网-高级指南(十五)Vue 与 Web Components 文章目录 Vue3官网-高级指南(十五)Vue 与 Web Components 1. Vue 与 Web Components ...

  9. 【转载】从头编写 asp.net core 2.0 web api 基础框架 (1)

    工具: 1.Visual Studio 2017 V15.3.5+ 2.Postman (Chrome的App) 3.Chrome (最好是) 关于.net core或者.net core 2.0的相 ...

最新文章

  1. python实训心得2000_实训总结万能版2000字五篇
  2. jQuery-EasyUI异步加载树形菜单
  3. Mysql 新建用户并分配所有权限
  4. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
  5. java optional 用法_Java 8中的Optional: 如何正确使用?
  6. Joomla2.5 JDate 时区日期运算
  7. 服务器管理安全(上)
  8. 第一家云创大数据产业学院在佛山职业技术学院挂牌
  9. 达梦数据库查看某个表的字段类型、常用数据库驱动类名以及URL
  10. php activerecord,Yii2 优雅的 Active Record
  11. mysql获取一行中多列的最大值_SQL 获取一行中多个字段的最大值
  12. td自动换行:设置table布局固定,td根据设定宽度自动换行
  13. Spark之UpdateStateByKey算子
  14. QQ是成年人的“不老神仙水”
  15. centos7 pe系统安装_CentOS 系统的安装
  16. 两个VB程序之交换数据的DDE工程
  17. linux进程线程-alarm闹钟函数
  18. 尚硅谷nodejs入门教程_笔记
  19. [SSL_CHX][2021-8-18]量身高
  20. 苹果手机性能测试用是么软件,怎么检测iPhone手机性能

热门文章

  1. 情商比智商更能决定人的一生
  2. K12教育小初高各个版本教材内的章节数据
  3. Python 实现按键精灵的功能,超简单详细(Windows版)
  4. Python按键精灵自动化
  5. Novavax向美国提交新冠疫苗紧急使用授权申请;西门子医疗发布最新业绩 | 医药健闻...
  6. mac机c4d更改语言,Win/Mac版:C4D R18 三维软件 Cinema 4D C4D R18 正式完整版 + 中文/英文注册机版...
  7. GitHub 上排名前 100 的 IOS 开源库介绍
  8. 侍魂服务器维护补偿,侍魂胧月传说:套路!花了15万元玩强化类氪金游戏总结出来的经验...
  9. CSP-2019day1题解报告
  10. 推荐系统 --- 推荐算法 --- 基于用户行为的推荐算法 - 协同过滤算法