116 lines
4.7 KiB
C#
116 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace Lskj.AgentBridge
|
|
{
|
|
public static class BridgeRequestParser
|
|
{
|
|
private static readonly ISet<string> AllowedProperties =
|
|
new HashSet<string>(new[]
|
|
{
|
|
"protocolVersion",
|
|
"requestId",
|
|
"correlationId",
|
|
"clientSessionId",
|
|
"sessionScopeToken",
|
|
"method",
|
|
"payload",
|
|
"uatGrant"
|
|
}, StringComparer.Ordinal);
|
|
|
|
public static BridgeRequest Parse(string json)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
throw new JsonSerializationException("桥请求 JSON 不能为空。");
|
|
JObject root;
|
|
using (StringReader text = new StringReader(json))
|
|
using (StrictJsonTextReader reader = new StrictJsonTextReader(text))
|
|
{
|
|
root = JObject.Load(reader, new JsonLoadSettings
|
|
{
|
|
CommentHandling = CommentHandling.Ignore,
|
|
LineInfoHandling = LineInfoHandling.Ignore,
|
|
DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error
|
|
});
|
|
if (reader.Read())
|
|
throw new JsonSerializationException("桥请求包含多个 JSON 根值。");
|
|
}
|
|
foreach (JProperty property in root.Properties())
|
|
{
|
|
if (!AllowedProperties.Contains(property.Name))
|
|
throw new JsonSerializationException(
|
|
"桥请求包含未知字段:" + property.Name);
|
|
}
|
|
RequireStringWhenPresent(root, "protocolVersion");
|
|
RequireStringWhenPresent(root, "requestId");
|
|
RequireStringWhenPresent(root, "correlationId");
|
|
RequireStringWhenPresent(root, "clientSessionId");
|
|
RequireStringWhenPresent(root, "sessionScopeToken");
|
|
RequireStringWhenPresent(root, "method");
|
|
JToken payload = root["payload"];
|
|
if (payload != null && payload.Type != JTokenType.Object)
|
|
throw new JsonSerializationException("桥请求 payload 必须是 JSON 对象。");
|
|
JToken uatGrant = root["uatGrant"];
|
|
if (uatGrant != null)
|
|
{
|
|
JObject grant = uatGrant as JObject;
|
|
if (grant == null)
|
|
throw new JsonSerializationException(
|
|
"桥请求 uatGrant 必须是 JSON 对象。");
|
|
ISet<string> grantFields = new HashSet<string>(
|
|
new[] { "authorizationId", "caseCode", "token" },
|
|
StringComparer.Ordinal);
|
|
foreach (JProperty property in grant.Properties())
|
|
{
|
|
if (!grantFields.Contains(property.Name))
|
|
throw new JsonSerializationException(
|
|
"桥请求 uatGrant 包含未知字段:"
|
|
+ property.Name);
|
|
}
|
|
if (grant.Properties().Count() != 3)
|
|
throw new JsonSerializationException(
|
|
"桥请求 uatGrant 必须完整包含三个字段。");
|
|
RequireStringWhenPresent(grant, "authorizationId");
|
|
RequireStringWhenPresent(grant, "caseCode");
|
|
RequireStringWhenPresent(grant, "token");
|
|
}
|
|
BridgeRequest request = root.ToObject<BridgeRequest>();
|
|
if (request == null)
|
|
throw new JsonSerializationException("桥请求无法反序列化。");
|
|
return request;
|
|
}
|
|
|
|
private static void RequireStringWhenPresent(JObject root, string name)
|
|
{
|
|
JToken value = root[name];
|
|
if (value != null && value.Type != JTokenType.String)
|
|
throw new JsonSerializationException(
|
|
"桥请求字段必须是字符串:" + name);
|
|
}
|
|
|
|
private sealed class StrictJsonTextReader : JsonTextReader
|
|
{
|
|
public StrictJsonTextReader(TextReader reader)
|
|
: base(reader)
|
|
{
|
|
DateParseHandling = DateParseHandling.None;
|
|
FloatParseHandling = FloatParseHandling.Decimal;
|
|
MaxDepth = 64;
|
|
SupportMultipleContent = false;
|
|
}
|
|
|
|
public override bool Read()
|
|
{
|
|
bool available = base.Read();
|
|
if (available && TokenType == JsonToken.Comment)
|
|
throw new JsonReaderException("桥请求不允许 JSON 注释。");
|
|
return available;
|
|
}
|
|
}
|
|
}
|
|
}
|