用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

java开源    -  云代码空间

——

C#时间格式的场景分析

2022-08-08|155阅||

摘要:前言:晚上睡觉的时间,群里显示订单常见的接收失败,开工排查问题,验错失败,发现一个异常反签的bug,总算比较的接收一个写作记录的情况单api,对当事人的订单进行签名验证

前言:

提示睡眠的时候,群里反馈订单接收失败,工排查问题,日志验签失败,发现异常写作的错误,总算有一个错误

场景描述

次的属于同类场景的api,对根据常见的本数据库进行的收款处理到,签名规则的顺序和后续参数的升序,然后进行后续的串串、后续的串连、追踪上秘或按照指定的加密方式生成签名

前戏一

设计之初,肯定是怎么简单怎么来,粗略代码变成


[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);
}
意外意外肯定是要出意外的时候,发现json联有待出加密的明文类型,有问题顺序出列,这里有两个
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
针对第一个问题,很好,我们按照顺序化的时间,指定日期时间的格式可以解决

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-0900:00:00:00:00,吃吃惊惊,看来,看来看来看来看来是把数字成月份月份了,真就很简单了,因为定义了数据模型,我们直接在的时候发现问题,获取该值的类型,做自动判断问题

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不同的时间格式

这里推荐日期时间。具体方法,可以根据我们自定义的方式,来时间解析,舒坦了...

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;
    }
}





顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: java开源
    • 等级: 中级程序员
    • 积分: 480
    • 代码: 0 个
    • 文章: 16 篇
    • 随想: 0 条
    • 访问: 5 次
    • 关注

    人气代码

      最新提问

        站长推荐