我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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#校验时间格式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

本文通过场景分析给大家讲解C#里如何简单的校验时间格式,本次的场景属于比较常见的收单API,对第三方的订单进行签名验证,然后持久化到数据库,需要的朋友跟随小编一起看看吧
2022-11-13

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

下面我介绍两种校验时间格式的正则表达式实例了,这个其实可以直接叫js了,因为正则功能jquery与js是一样的,下面看实例
2022-11-15

shell进度条追踪指令执行时间的场景分析

目录代码使用说明效果展示最近一两年,我经手了不少与shell相关的工作。在这个过程中,我越发觉得shell脚本在完成具体任务的同时,应该再给用户展示一个进度条,用以提示当前阶段还需要多少时间才能完成。 linux中的不少软件都有进度条,比如
2022-06-16

Nest.js参数校验和自定义返回数据格式的示例分析

这篇文章主要介绍Nest.js参数校验和自定义返回数据格式的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!0x0 参数校验参数校验大部分业务是使用 Nest.js 中的管道 方法实现,具体可以查阅文档 。不过
2023-06-14

Springboot中全局时间格式化操作的示例分析

这篇文章主要为大家展示了“Springboot中全局时间格式化操作的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Springboot中全局时间格式化操作的示例分析”这篇文章吧。时间格式
2023-06-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录