ABP框架官网例子实践(2)(ASP.NET core+Multi Page Web Application)
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)相关推荐
- ABP 框架官网学习资料
ABP是"ASP.NET Boilerplate Project (ASP.NET样板项目)"的简称. [新思想.新技术.新架构--更好更快的开发现代ASP.NET应用程序] AS ...
- OpenLayers 官网例子的中文详解
当你希望实现某种功能的时候,即使你对 openlayers 几乎一窍不通,照着官网的例子做,也可以很快的实现想要的效果. 问题在于,官网的例子都是英文啊,不能很快定位到想要的效果是在哪个例子里面!!( ...
- layer添加元素 openlayer_OpenLayers 官网例子的中文详解
当你希望实现某种功能的时候,即使你对 openlayers 几乎一窍不通,照着官网的例子做,也可以很快的实现想要的效果. 问题在于,官网的例子都是英文啊,不能很快定位到想要的效果是在哪个例子里面!!( ...
- 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 ...
- easyx官网例子初试
目录 基础 easyx简介 透明贴图和三元光栅操作 精确延时 程序 自由运动的点 冰封的EasyX 火焰效果 烟花 水波 迷宫 纪念披头士摇滚乐队 基础 easyx简介 在官网安装包里面有个easyx ...
- 根据官网例子一步步实现vueSSR(详细)
根据 官网例子一步步实现vue ssr 标题对应官网标题 文章目录 基本用法 模版插值 源码结构 使用 webpack 的源码结构(vue-cli3) 构建配置 服务端 路由和代码分割 图片未加载,引 ...
- C#建站框架官网:CSFramework.CMS内容管理系统
C#建站框架官网:CSFramework.CMS内容管理系统 产品详情:CSFramework.CMS内容管理系统-适用开发博客.论坛.文档知识库Web网站应用程序https://www.csfram ...
- Vue3官网-高级指南(十五)Vue 与 Web Components
Vue3官网-高级指南(十五)Vue 与 Web Components 文章目录 Vue3官网-高级指南(十五)Vue 与 Web Components 1. Vue 与 Web Components ...
- 【转载】从头编写 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的相 ...
最新文章
- python实训心得2000_实训总结万能版2000字五篇
- jQuery-EasyUI异步加载树形菜单
- Mysql 新建用户并分配所有权限
- 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像
- java optional 用法_Java 8中的Optional: 如何正确使用?
- Joomla2.5 JDate 时区日期运算
- 服务器管理安全(上)
- 第一家云创大数据产业学院在佛山职业技术学院挂牌
- 达梦数据库查看某个表的字段类型、常用数据库驱动类名以及URL
- php activerecord,Yii2 优雅的 Active Record
- mysql获取一行中多列的最大值_SQL 获取一行中多个字段的最大值
- td自动换行:设置table布局固定,td根据设定宽度自动换行
- Spark之UpdateStateByKey算子
- QQ是成年人的“不老神仙水”
- centos7 pe系统安装_CentOS 系统的安装
- 两个VB程序之交换数据的DDE工程
- linux进程线程-alarm闹钟函数
- 尚硅谷nodejs入门教程_笔记
- [SSL_CHX][2021-8-18]量身高
- 苹果手机性能测试用是么软件,怎么检测iPhone手机性能
热门文章
- 情商比智商更能决定人的一生
- K12教育小初高各个版本教材内的章节数据
- Python 实现按键精灵的功能,超简单详细(Windows版)
- Python按键精灵自动化
- Novavax向美国提交新冠疫苗紧急使用授权申请;西门子医疗发布最新业绩 | 医药健闻...
- mac机c4d更改语言,Win/Mac版:C4D R18 三维软件 Cinema 4D C4D R18 正式完整版 + 中文/英文注册机版...
- GitHub 上排名前 100 的 IOS 开源库介绍
- 侍魂服务器维护补偿,侍魂胧月传说:套路!花了15万元玩强化类氪金游戏总结出来的经验...
- CSP-2019day1题解报告
- 推荐系统 --- 推荐算法 --- 基于用户行为的推荐算法 - 协同过滤算法