解析带有datetimeoffset的json从PHP到c#会导致错误的数据



我有一个来自第三方的webhook调用,这是一个复杂的JSON对象,在这个对象中,有一些像2023-04-05T14:13:47+0200这样的日期时间字段,所以当我用c#解析这个JSON时,结果是2023-04-05T14:13:47+02:00,这在计算哈希码时导致一个问题。

这是JSON:
{
"message": "OK",
"code": 200,
"current_time": "2023-04-05T14:13:50+0200",
"order": {
"uuid": "45B32B3C-B01A-4D82-A03B-D5D9709DC92C",
"created": "2023-04-05T14:13:47+0200",
"created_from_client_timezone": "2023-04-05T14:13:47+0200",
"amount": 1000,
"currency": "978",
"paid": false, 
"status": "CREATED",
"safe": true,
"refunded": 0,
"additional": null,
"service": "REDSYSPSD2",
"service_uuid": "F9D76AE8-DDBB-4F17-8074-C2DABEE0A919",
"customer": "test2222",
"cof_txnid": null,
"transactions": [],
"token": "345e77cc5a2616030ef5965d5513e1088adbd087b637da99eefc80f0729c943a26ef5e3a45b454819c62015e3d74f3282ecd2e1ab0b99a34de46d8aa37106a3d",
"ip": null,
"urls": { 
"payment_card":"http://ws.paylands.loc/su/QY6cnT3MasUB",
"bizum":"http://ws.paylands.loc/su/0SWxTAvN0QkJ",
"3ds_tokenized":"http://ws.paylands.loc/su/3wEDqxIhjjsD"
},
"reference": null,
"dynamic_descriptor": "u00ebu00f1a,u00e1ds,u00f4 u00f2,",
"threeds_data": null
},
"client": {
"uuid":"42B8CF56-A7D7-4D4A-8349-4E27263CB2D5"
},
"validation_hash": "414c8190e6b15ac767ff3217e994ef8687368ec8ebe6ab9ad570799d2f746cb7"
}

validation_hash的计算方法如下:

var jsonDe = JsonConvert.DeserializeObject<dynamic>(requestBody);
var signatureData = JsonConvert.SerializeObject(new Dictionary<string, object>
{
{ "order", jsonDe.order },
{ "client", jsonDe.client },
});
var signature = CalculateSHA256Hash(signatureData + settings.Signature);
if (signature != dto.ValidationHash)
{
serviceResult.AddError(0, _localizationRepository.Get("The request is invalid."));
return serviceResult;
}
static string CalculateSHA256Hash(string input)
{
using (SHA256 sha256Hash = SHA256.Create())
{
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}

我已经测试了几个转换器,但没有一个可以解决不将:添加到DateTime字段的问题。

我修改了DeserializeObject后的字段,并删除了最后的:,但这不是我想要的,所以这个问题还有其他解决方案吗?

供参考,这是他们支持PHP的一个例子:https://onlinephp.io/c/4a0c8

如果您正在使用Newtonsoft的Json。. NET(有JsonConvert的)-然后简单地禁用自动DateTime处理(我还建议从使用dynamic切换到库公开的动态JSON处理类型):

var requestBody = """
{
"current_time": "2023-04-05T14:13:50+0200",
"order": {
"uuid": "45B32B3C-B01A-4D82-A03B-D5D9709DC92C",
"created": "2023-04-05T14:13:47+0200",
"created_from_client_timezone": "2023-04-05T14:13:47+0200",
}
}
""";
var jsonDe = JsonConvert.DeserializeObject<JToken>(requestBody, new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.None
});
Console.WriteLine(jsonDe["current_time"].ToString()); //2023-04-05T14:13:50+0200
Console.WriteLine(jsonDe["order"]["created_from_client_timezone"].ToString()); // 2023-04-05T14:13:47+0200
var signatureData = JsonConvert.SerializeObject(new Dictionary<string, object>
{
{ "order", jsonDe["order"] },
{ "client", jsonDe["client"] },
}); // {"order":{"uuid":"45B32B3C-B01A-4D82-A03B-D5D9709DC92C","created":"2023-04-05T14:13:47+0200","created_from_client_timezone":"2023-04-05T14:13:47+0200"},"client":null}

对于System.Text.Json(如果你决定切换)-使用类似的API,例如JsonNode(对我来说是开箱即用的,没有日期处理发生):

var jsonNode = JsonSerializer.Deserialize<JsonNode>(requestBody); // or JsonNode.Parse
Console.WriteLine(jsonNode["order"]["created_from_client_timezone"].ToString()); // 2023-04-05T14:13:47+0200

公立小学确保两边的缩进也以同样的方式处理。