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#里如何简单的校验时间格式的文章就介绍到这了,更多相关C#校验时间格式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#时间格式转换为时间戳的方法步骤

    时间戳转换: /// <summary> /// C#时间格式转换为时间戳(互转) /// 时间戳定义为从格林威治时间 1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数. /// </summary> public class DateTime_TimeStamp : MonoBehaviour { protected int m_timestamp; /// <summary> /// 获取时间戳Timest

  • C# 校验帮助类正则表达式

    一.简介 很多时候我们都需要用到一些验证的方法,有时候需要用正则表达式校验数据时,往往需要到网上找很久,结果找到的还不是很符合自己想要的.所以我把自己整理的校验帮助类分享处理,在这里分享一下,给自己留了个底,也给各位需要的朋友们做个参考 二.校验类片段 2.1 邮箱验证 #region IsEmail(是否邮箱) /// <summary> /// 是否邮箱 /// </summary> /// <param name="value">邮箱地址<

  • C# string格式的日期时间字符串转为DateTime类型的方法

    方法一:Convert.ToDateTime(string) string格式有要求,必须是yyyy-MM-dd hh:mm:ss 方法二:Convert.ToDateTime(string, IFormatProvider) DateTime dt; DateTimeFormatInfo dtFormat = new System.GlobalizationDateTimeFormatInfo(); dtFormat.ShortDatePattern = "yyyy/MM/dd";

  • C# 当前系统时间获取及时间格式详解

    C# 当前系统时间获取及时间格式 最近学习C# 的知识,对获取系统时间和时间格式进行了总结,这是本文在网上整理的详细资料,大家看下! --DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 取当前年月日时分秒 currentTime=System.DateTime.Now; 取当前年 int 年=currentTime.Year; 取当前月 int 月=currentTime.Month; 取当前日 int 日=curr

  • C#实现常见时间格式

    string aa = DateTime.Now.ToShortDateString();//"2019/9/23" string bb = DateTime.Now.ToShortTimeString();//"上午 10:21" string ff = DateTime.Now.ToLongDateString();//2019年9月23日 string gg = DateTime.Now.ToLongTimeString();//上午 10:22:07 int

  • C#校验时间格式的场景分析

    目录 前言: 场景描述 前戏一 前戏二 正戏 尾戏 前言: 晚上打算睡觉的时候,群里反馈订单接收失败,开工排查问题,日志显示验签失败,发现一个蛮有意思的BUG,总算有了一个写作的素材 场景描述 本次的场景属于比较常见的收单API,对第三方的订单进行签名验证,然后持久化到数据库,签名规则大致是将参数key按照升序排序,然后根据key=value&进行字符串拼接,最后加上秘钥,按照指定的加密方式生成签名 前戏一 设计之初,肯定是怎么简单怎么来,粗略代码如下 [HttpPost] public asy

  • springAop实现权限管理数据校验操作日志的场景分析

    前言 作为一个写java的使用最多的轻量级框架莫过于spring,不管是老项目用到的springmvc,还是现在流行的springboot,都离不开spring的一些操作,我在面试的时候问的最多的spring的问题就是我们在平常的项目中使用spring最多的有哪几个点 在我看来无非就两个 spring的bean管理,说的高大上一点就是spring的ioc,di spring的AOP spring是一个很强大的轻量级框架,功能远不止这两点,但是我们用的最多的就是这两点. spring bean 管

  • jQuery中校验时间格式的正则表达式小结

    代码中用到了jQuery,传入的参数是jQuery选择的input对象.原理:先用正则匹配,再提取时分秒,看其是否在正常的范围内. 复制代码 代码如下: /** * 检测时间是否符合格式 * @param {Object} timeTextBox */function checkTime(timeTextBox){    var time = timeTextBox.val();    var regTime = /^([0-2][0-9]):([0-5][0-9]):([0-5][0-9])$

  • SpringBoot中@Pattern注解对时间格式校验方式

    目录 SpringBoot @Pattern注解对时间格式校验 1.需求背景 2.实现案例 @Pattern的用法 下面是常用的正则表达式 SpringBoot @Pattern注解对时间格式校验 1.需求背景 有一个需求,在前端传过来的时间格式的字符串进行校验,是否符合"yyyy-MM-dd HH:mm:ss",在SpringBoot中当然可以用@Datetimeformat注解来进行验证,但字段的属性得用Date类型,由于我的项目中该字段用了String类型,需要对类型进行转换不太

  • 一文教会你用正则表达式校验日期时间格式

    目录 日期部分校验 概念 验证YYYY年份: 验证MMDD月日: 时间部分校验 校验HHmmss 校验HH-mm-ss 校验日期+时间部分 校验yyyyMMddHHmmss 校验 yyyy-MM-dd HH:mm:ss 应用举例 总结 日期部分校验 概念 首先,我们先了解2个概念: 1.合法的日期范围: DateTime 值类型表示值范围在公元(基督纪元)0001 年 1 月 1 日午夜 12:00:00 到公元 (C.E.) 9999 年 12 月 31 日晚上 11:59:59 之间的日期和

  • Java ThreadLocal原理解析以及应用场景分析案例详解

    目录 ThreadLocal的定义 ThreadLocal的应用场景 ThreadLocal的demo TheadLocal的源码解析 ThreadLocal的set方法 ThreadLocal的get方法 ThreadLocalMap的结构 ThreadLocalMap的set方法 ThreadLocalMap的getEntry方法 ThreadLocal的内存泄露 如何避免内存泄露呢 应用实例 实际应用二 总结 ThreadLocal的定义 JDK对ThreadLocal的定义如下: The

  • Java验证时间格式是否正确方法类项目实战

    在很多场景中我们需要验证时间日期的是否属于正确的格式,验证时间是否符合常规的. 1.验证 yyyy-MM-dd HH:mm:dd 格式的日期 String date = "2020-01-25 12:36:45"; System.out.println("date "+isLegalDate(date.length(),date,"yyyy-MM-dd HH:mm:ss")); 2.验证 yyyy-MM-dd 格式的日期 String yearM

  • PHP使用gmdate实现将一个UNIX 时间格式化成GMT文本的方法

    本文实例讲述了PHP使用gmdate实现将一个UNIX 时间格式化成GMT文本的方法.分享给大家供大家参考.具体分析如下: 语法如下: string gmdate (string $Format) string gmdate (string $Format, int $Time) 演示代码 <?php echo "When this page was loaded,\n"; echo 'It was then ', gmdate ('r'), "\n"; ec

  • Javascript控制input输入时间格式的方法

    本文实例讲述了Javascript控制input输入时间格式的方法.分享给大家供大家参考.具体分析如下: 之前做了一个Javascript控制时间格式的输入,主要用到了keydown和keyup两个事件,但感觉写的很复杂而且还有bug. 今日了解了一下keypress事件与keydown和keyup的区别.大致如下(目前只了解这么多): keydown:按键按下的时候触发,通过event可以获取到keyCode,可以获取到文本框输入之前的值: keyup:按键弹出(松开)时触发,通过event可

  • php输出指定时间以前时间格式的方法

    本文实例讲述了php输出指定时间以前时间格式的方法.分享给大家供大家参考.具体分析如下: 比如说你需要在php中输出3天前,20分钟以前,可以参考下面的代码 function ago($time) { $time = strtotime($time); $delta = time() - $time; if ($delta < 60) { return 'less than a minute ago.'; } else if ($delta < 120) { return 'about a m

随机推荐