C#里如何简单的校验时间格式
前言:
晚上打算睡觉的时候,群里反馈订单接收失败,开工排查问题,日志显示验签失败,发现一个蛮有意思的BUG,总算有了一个写作的素材

场景描述
本次的场景属于比较常见的收单API,对第三方的订单进行签名验证,然后持久化到数据库,签名规则大致是将参数key按照升序排序,然后根据key=value&进行字符串拼接,最后加上秘钥,按照指定的加密方式生成签名
前戏一
设计之初,肯定是怎么简单怎么来,粗略代码如下
[HttpPost]
public async Task<IActionResult> TestSendOrder([FromBody] ReceiveOrderRequest request)
{
var secret_key = _options.Value.SecretKey;
var url = _options.Value.Host;
//1.将模型转成json格式字符串
var param = JsonConvert.SerializeObject(request);
//2.将json格式字符串,序列化成有序字典
SortedDictionary<string, string> dict = JsonConvert.DeserializeObject<SortedDictionary<string, string>>(param);
//3.循环字典,按规则拼接成待加密的明文字符串
var data = "";
foreach (var item in dict)
{
if (item.Key == "sign") continue;
data += $"{item.Key}={item.Value}&";
}
data += $"secret_key={secret_key}";
//4.生成签名
var sign = EncryptHelper.SHA1Encryption(data);
request.sign = sign;
//5.模拟订单推送
var res = await _httpClientHelper.PostData(url, JsonConvert.SerializeObject(request));
return Ok(res);
}
不出意外,肯定是要出意外的,联调的时候,发现与第三方待加密的明文字符串不一致,问题出在JsonConvert序列化上,这里有两个问题

1. DateTime格式不一致
如: DateTime dt = "2022-07-30 12:26:56"
序列化后 dt=2022-07-30T12:26:56
2. decimal小数点后自动补0
如: decimal price = 10
序列化后 price=10.0
针对第一个问题,很好解决,我们在序列化的时候,指定DateTime的格式即可
var iso = new IsoDateTimeConverter();
iso.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
var param = JsonConvert.SerializeObject(request, iso);
针对第二个问题,处理起来就比较麻烦了,要重写底层的一些东西(主要是我不会),这不符合"简单"的定义,得换个方案

前戏二
通过反射遍历对象,然后将属性名称与值,丢到有序字典里面,这里我写了个方法来判断值是否为时间,如果是时间类型,则格式化,代码如下
public string GetFmortDateTime(string strDate)
{
DateTime dt;
if (DateTime.TryParse(strDate, out dt))
{
return dt.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
return strDate;
}
}
不出意外,肯定是要出意外的,不然也不会有这个素材去水一篇博客了

正戏
有个字段的值是9.9,结果被序列化成了 2022-09-09 00:00:00,吃了一惊,看来是把这个数字格式化成月份日份了,真有意思,又GET到一个新姿势,发现问题解决问题就简单多了,因为定义了数据模型,我们直接在反射的时候,获取该值的类型做判断即可
public static async Task<bool> CheckSign(dynamic request, string secret)
{
SortedDictionary<string, string> dict = new SortedDictionary<string, string>();
foreach (PropertyInfo p in request.GetType().GetProperties())
{
var value = p.GetValue(request);
if (value == null)
{
dict[p.Name] = "";
}
else
{
var valueType = value.GetType();
if (valueType.Name == "DateTime")
{
dict[p.Name] = Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
dict[p.Name] = value.ToString();
}
}
}
var sign = dict["sign"];
dict.Remove("sign");
var data = "";
foreach (var item in dict)
{
data += $"{item.Key}={item.Value}&";
}
data += $"secret_key={secret}";
var new_sign = EncryptHelper.SHA1Encryption(data);
return new_sign.ToLower() == sign.ToLower();
}
尾戏
看到这里,可能就有小伙伴有话要说了,你这定义了一个模型,还要通过循环两次,才能生成待加密的明文字符串,不符合"简单",干脆直接用个有序字典去接收参数好了,这样只用循环一次

秒啊,秒啊,秒啊,妙蛙种子都没有你秒,这种做法不是不行,但是后面维护的人估计要抓狂了,按照规约,我们是不推荐这么干的,这次就破例这么干一次,抛出另一个问题,一个字符串,如何判断它是一个我们约定的时间格式,很显然9.9并不是约定的时间格式
这里推荐 DateTime.ParseExact方法,可以根据我们自定义的方式,来格式化时间,舒坦了...
public static string GetFmortDateTime(string strDate)
{
string[] format = { "yyyy-MM-ddTHH:mm:ss" };
DateTime dt;
if (DateTime.TryParseExact(strDate,format,CultureInfo.InvariantCulture,DateTimeStyles.None,out dt))
{
return dt.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
return strDate;
}
}
C#里如何简单的校验时间格式的更多相关文章
- java校验时间格式 HH:MM
package com; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Gerrard */ publ ...
- jQuery中校验时间格式的正则表达式小结
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- JS时间格式和时间戳的相互转换
时间戳转化为日期的方式 ; var newDate = new Date(); newDate.setTime(timestamp * ); // Mon May 28 2018 console.lo ...
- MySQL解决存入数据库和取出数据库时间格式问题
我们在往数据库里存数据时,时间格式正是我们想要的,然而取数据时去出现了这种情况 这明显不是我们想要的! 解决办法: 在我们配置mysql时添加一行代码: timezone:"08:00&qu ...
- Kendo Web UI Grid里时间格式转换
我和大家分享一下我的kendo的学习心得.如果不好的地方多多包含或者给我留言请看图 kendo里时间格式如图Oder Date列里的格式.但是我们想把时间转换成中国人习惯的格式.如Shipped Da ...
- 时间操作(JavaScript版)—最简单比較两个时间格式数据的大小
呵呵呵,在软件研发过程中假设遇到要比較两个时间的大小.你会怎么做.嗯嗯嗯,非常直观的做法就是把"-"去掉,再比較大小,真的有必要吗?看以下最简单的时间比較方式: <!DOCT ...
- 记录微信小程序里自带 时间格式 工具
微信小程序里面自己给了一个时间工具,是用来记录log日志,感觉可以记录下来,所以拿来自己用,以此记录: 直接传入 日期对象 进入 formatTime //得到下面格式的时间格式2017/07/22 ...
- 使用饿了么el-date-picker里及如何将后台给的时间戳js转化为时间格式
首先代码是这个样子的,使用v-model <el-date-picker v-model="formData.createTime" :disabled="true ...
- 时间格式的处理和数据填充和分页---laravel
时间格式文档地址:http://carbon.nesbot.com/docs/ 这是些时间格式,只需要我们这么做就可以 我们在模板层,找到对应的模型对象那里进行处理就可以啦 2018-11-08 16 ...
随机推荐
- JWT 访问令牌
JWT 访问令牌 更为详细的介绍jwt 在学习jwt之前我们首先了解一下用户身份验证 1 单一服务器认证模式 一般过程如下: 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户名,用户角色 ...
- 637. Average of Levels in Binary Tree - LeetCode
Question 637. Average of Levels in Binary Tree Solution 思路:定义一个map,层数作为key,value保存每层的元素个数和所有元素的和,遍历这 ...
- 好客租房43-react组件基础综合案例-4获取评论信息
获取评论信息 1使用受控组件方式创建表单 //导入react import React from 'react' import ReactDOM from 'react-dom' //导入组件 // ...
- 关于vue.config.js 的 proxy 配置
关于vue.config.js 的 proxy 配置有的同学不怎么明白项目里面有的配置了 pathRewrite 地址重写,有的又没有进行配置?/* * proxy代理配置的说明 * *接口例子:/z ...
- vue上传图片的3种方式
https://blog.csdn.net/q3254421/article/details/88250968?utm_medium=distribute.pc_relevant.none-task- ...
- 哈工大软件构造Lab2(2022)
(防扒小助手) 本人CSDN博客: https://blog.csdn.net/m0_61753302https://blog.csdn.net/m0_61753302本人博客园博客(同步CSDN): ...
- SpringCloud 服务治理
目录 1. Eureka 1.1 Eureka 介绍 1.2 Eureka 快速入门 父工程 Eureka Server(子工程) pom.xml 启动类 application.yml Eureka ...
- 将Hexo搭建到自己的服务器上
http://xybin.top/posts/9373.html 第一部分:服务器端的操作 1.安装git 和nginx yum install -y nginx git 2.添加一个git用户 #添 ...
- 2.如何正确理解古典概率中的条件概率《zobol的考研概率论教程》
写本文主要是帮助粉丝理解考研中的古典概率-条件概率的具体定义. "B事件发生的条件下,A事件发生的概率"? "在A集合内有多少B的样本点"? "在B约 ...
- UiPath参数介绍和使用
一.参数介绍 用于将数据从一个项目传递到另一个项目.在全局意义上,它们类似于变量,因为它们动态地存储数据并传递给它.变量在活动之间传递数据,而参数在自动化之间传递数据.因此,它们使你能够一次又一次地重 ...