Files
lserp_cs_6.0/插件库/Lskj.AgentBridge/BridgeRequestParser.cs
T
2026-08-14 14:28:28 +08:00

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