ASP.NET Core搭建多层网站架构【8.1-使用ViewModel注解验证】
2020/01/29, ASP.NET Core 3.1, VS2019
摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构【8.1-使用ViewModel注解验证】
使用ViewModel注解验证字段合法性,将ViewModel的字段验证写在了ViewModel类内部
本章节介绍了使用ASP.NET Core自带的注解验证前端提交的参数
确认MS.Models
类库已引用MS.Component.Jwt
、MS.DbContexts
两个项目
添加业务操作枚举和返回值定义
在MS.WebCore
类库中新建Core文件夹,在该文件夹中新建ExecuteResult.cs
、ExecuteType.cs
类:
ExecuteResult.cs
namespace MS.WebCore.Core
{
/// <summary>
/// 执行返回结果
/// </summary>
public class ExecuteResult
{
public virtual ExecuteResult Set(bool isSucceed, string message)
{
IsSucceed = isSucceed;
Message = message;
return this;
}
/// <summary>
/// 设定错误信息
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public virtual ExecuteResult SetFailMessage(string message)
{
return Set(false, message);
}
public virtual ExecuteResult SetFail()
{
return Set(false, string.Empty);
}
public ExecuteResult(bool isSucceed, string message)
{
Set(isSucceed, message);
}
/// <summary>
/// 如果是给字符串,表示有错误信息,默认IsSucceed=false
/// </summary>
/// <param name="message"></param>
public ExecuteResult(string message)
{
Set(false, message);
}
/// <summary>
/// 如果是空的,没有信息,默认IsSucceed=true
/// </summary>
public ExecuteResult()
{
}
/// <summary>
/// 执行是否成功
/// 默认为True
/// </summary>
public bool IsSucceed { get; set; } = true;
/// <summary>
/// 执行信息(一般是错误信息)
/// 默认置空
/// </summary>
public string Message { get; set; } = string.Empty;
}
/// <summary>
/// 执行返回结果
/// </summary>
/// <typeparam name="T"></typeparam>
public class ExecuteResult<T> : ExecuteResult
{
public ExecuteResult<T> Set(bool isSucceed, string message, T result)
{
IsSucceed = isSucceed;
Message = message;
Result = result;
return this;
}
public ExecuteResult<T> SetData(T data)
{
return Set(true, string.Empty, data);
}
public new ExecuteResult<T> SetFail()
{
return Set(false, string.Empty, default);
}
/// <summary>
/// 设定错误信息
/// 如果T正好也是string类型,可能set方法会存在用错的时候,所以取名SetMessage更明确
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public new ExecuteResult<T> SetFailMessage(string message)
{
return Set(false, message, default);
}
public ExecuteResult()
{
}
public ExecuteResult(string message)
{
Set(false, message);
}
public ExecuteResult(bool isSucceed, string message)
{
Set(isSucceed, message);
}
public ExecuteResult(T result)
{
SetData(result);
}
public T Result { get; set; }
}
}
这个类是定义了业务相关方法调用的返回值结果,包含了是否成功、错误信息,也可以拓展泛型夹带其他内容
ExecuteType.cs
namespace MS.WebCore.Core
{
/// <summary>
/// 表示操作数据库类型
/// </summary>
public enum ExecuteType
{
/// <summary>
/// 读取资源
/// </summary>
Retrieve,
/// <summary>
/// 创建资源
/// </summary>
Create,
/// <summary>
/// 更新资源
/// </summary>
Update,
/// <summary>
/// 删除资源
/// </summary>
Delete
}
}
这个枚举定义了业务操作的类型,对应数据库的CRUD
新建ViewModel
在MS.Models
类库中新建ViewModel文件夹,在该文件夹中新建RoleViewModel.cs
类:
using MS.DbContexts;
using MS.Entities;
using MS.UnitOfWork;
using MS.WebCore.Core;
using System.ComponentModel.DataAnnotations;
namespace MS.Models.ViewModel
{
public class RoleViewModel
{
public long Id { get; set; }
[Display(Name = "角色名称")]
[Required(ErrorMessage = "{0}必填")]
[StringLength(16, ErrorMessage = "不能超过{0}个字符")]
[RegularExpression(@"^[a-zA-Z0-9_]{4,16}$", ErrorMessage = "只能包含字符、数字和下划线")]
public string Name { get; set; }
[Display(Name = "角色显示名")]
[Required(ErrorMessage = "{0}必填")]
[StringLength(50, ErrorMessage = "不能超过{0}个字符")]
public string DisplayName { get; set; }
[Display(Name = "备注")]
[StringLength(4000, ErrorMessage = "不能超过{0}个字符")]
public string Remark { get; set; }
public ExecuteResult CheckField(ExecuteType executeType, IUnitOfWork<MSDbContext> unitOfWork)
{
ExecuteResult result = new ExecuteResult();
var repo = unitOfWork.GetRepository<Role>();
//如果不是新增角色,操作之前都要先检查角色是否存在
if (executeType != ExecuteType.Create && !repo.Exists(a => a.Id == Id))
{
return result.SetFailMessage("角色不存在");
}
//针对不同的操作,检查逻辑不同
switch (executeType)
{
case ExecuteType.Delete:
//删除角色前检查角色下还没有员工
if (unitOfWork.GetRepository<User>().Exists(a => a.RoleId == Id))
{
return result.SetFailMessage("还有员工正在使用该角色,无法删除");
}
break;
case ExecuteType.Update:
//如果存在Id不同,角色名相同的实体,则返回报错
if (repo.Exists(a => a.Name == Name && a.Id != Id))
{
return result.SetFailMessage($"已存在相同的角色名称:{Name}");
}
break;
case ExecuteType.Create:
default:
//如果存在相同的角色名,则返回报错
if (repo.Exists(a => a.Name == Name))
{
return result.SetFailMessage($"已存在相同的角色名称:{Name}");
}
break;
}
return result;//没有错误,默认返回成功
}
}
}
说明
- Display是该字段的显示名称
- Required注解标记该字段必填,不可为空
- StringLength注解标记该字段长度
- RegularExpression注解是正则表达式验证
- 还有个Range注解特性是验证值的范围的,这里没用到
除了注解,我把对象字段的逻辑验证写在了ViewModel中,没有把它放在业务层是因为,我认为对象字段本身的合法性和对象是强相关的,就和注解直接写在ViewModel中而不是Service中一样,所以把字段的验证也写在了ViewModel里
对象字段的逻辑验证我区分了操作类型,新增时检查角色名是否有重复;删除时检查是否还有用户使用该角色;更新时检查用户提交的角色是否存在于数据库中
新建Controller
在MS.WebApi
应用程序中,Controllers文件夹下新建RoleController.cs
:
using Microsoft.AspNetCore.Mvc;
using MS.Models.ViewModel;
using MS.WebCore.Core;
using System.Threading.Tasks;
namespace MS.WebApi.Controllers
{
[Route("[controller]")]
[ApiController]
public class RoleController : ControllerBase
{
[HttpPost]
public async Task<ExecuteResult> Post(RoleViewModel viewModel)
{
return new ExecuteResult();
}
}
}
删除WeatherForecastController.cs
和WeatherForecast.cs
两个类
完成后,启动项目,打开Postman
按之前的方法,在MSDemo集合中添加一个新的POST请求Role,URL为http://localhost:5000/role
切换到Body选项卡,选择raw,切换为json格式数据:
{
"Name": "",
"DisplayName": ""
}
点击发送,可以看到提示字段必填了
输入正确后,能返回true
Name输入超过16个字符错误,验证正则表达式等不再演示
以上便是ViewModel注解验证的使用
项目完成后,如下图所示
ASP.NET Core搭建多层网站架构【8.1-使用ViewModel注解验证】的更多相关文章
- ASP.NET Core搭建多层网站架构【0-前言】
2020/01/26, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构 目录 0-前言 1-项目结构分层建立 2-公共基 ...
- ASP.NET Core搭建多层网站架构【1-项目结构分层建立】
2020/01/26, ASP.NET Core 3.1, VS2019 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[1-项目结构分层建立] 文章目录 此分支项目代码 ...
- ASP.NET Core搭建多层网站架构【2-公共基础库】
2020/01/28, ASP.NET Core 3.1, VS2019,Newtonsoft.Json 12.0.3, Microsoft.AspNetCore.Cryptography.KeyDe ...
- ASP.NET Core搭建多层网站架构【3-xUnit单元测试之简单方法测试】
2020/01/28, ASP.NET Core 3.1, VS2019, xUnit 2.4.0 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[3-xUnit单元测试 ...
- ASP.NET Core搭建多层网站架构【4-工作单元和仓储设计】
2020/01/28, ASP.NET Core 3.1, VS2019, Microsoft.EntityFrameworkCore.Relational 3.1.1 摘要:基于ASP.NET Co ...
- ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】
2020/01/29, ASP.NET Core 3.1, VS2019, EntityFrameworkCore 3.1.1, Microsoft.Extensions.Logging.Consol ...
- ASP.NET Core搭建多层网站架构【6-注册跨域、网站核心配置】
2020/01/29, ASP.NET Core 3.1, VS2019, NLog.Web.AspNetCore 4.9.0 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站 ...
- ASP.NET Core搭建多层网站架构【7-使用NLog日志记录器】
2020/01/29, ASP.NET Core 3.1, VS2019, NLog.Web.AspNetCore 4.9.0 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站 ...
- ASP.NET Core搭建多层网站架构【8.2-使用AutoMapper映射实体对象】
2020/01/29, ASP.NET Core 3.1, VS2019, AutoMapper.Extensions.Microsoft.DependencyInjection 7.0.0 摘要:基 ...
随机推荐
- scw——01 java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMake
错误: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.Mock ...
- util之ArrayList
Java之ArrayList 方法: add(o: E): void 在list的末尾添加一个元素o add(index: int, o: E): void 在指定的index处插入元素o clear ...
- 不能暴露服务给外部环境,因为nginx-ingress-control启动失败
不能暴露服务给外部环境,因为nginx-ingress-control启动失败 待办 rancher 和k8s中的端口冲突,nginx-ingress-control都需要使用80端口 以及443端口 ...
- SpringMVC项目使用elastic search搜索
项目需要,引入了elastic search(后续简称es),后面将介绍本地对es的安装,使用以及java连接es查询的整个过程. 1.es索引字段建立与修改,以curl新增一个索引字段示例 curl ...
- 【C语言】移动指针
移动指针 #include<stdio.h> int main() { char *s="哈哈哈哈哈哈"; for(*s;s!="\0";s++) ...
- Nginx可以做什么
Nginx能做什么 ——反向代理 ——负载均衡 ——HTTP服务器(动静分离) ——正向代理 反向代理 反向代理应该是Nginx做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理(R ...
- DFT 问答 II
1. Boundary Scan A:Boundary scan 顾名思义,是附加在芯片I/O 周边的扫描测试链,它通过专门的测试端口(TAP)访问.在测试模式下,边界扫描链会接管功能逻辑,对I/O进 ...
- python 序列 倒着取元素
当要倒着取元素时,用s[-2]只能取一个, 如果取多个时用s[-9:-1],注意,最后一个-1是不取出来的. 此时要用s[-9:] 最后一个空着就可以取出来了.
- linux 下查看Tomcat的状态,以及开启停止服务命令
1.首先进入你的tomcat 的bin目录下 cd /你的安装目录/tomcat/bin 查看服务启动情况 ps -ef|grep java 此条命令具体含义 ps:将某个进程显示出来 -A 显示所有 ...
- 剑指offer 面试题36.二叉搜索树与双向链表
中序递归,一个pre节点记录前一个节点 /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; Tre ...