提问人:cyclingLinguist 提问时间:10/5/2023 更新时间:10/5/2023 访问量:69
为什么使用 Newtonsoft 在 JSON 中反序列化字符串化 JSON 模式时出错?
Why an Error Deserializing Stringified JSON Schema in JSON with Newtonsoft?
问:
我正在从表示 ChaptGPT api 请求中的函数的客户端接收数据,可在此处查看:https://platform.openai.com/docs/api-reference/chat/create。
我希望收到的 JSON 由 Newtonsoft.Json 解析,然后在 JSON 解析期间进行 JSchema 解析,但似乎 JSchema 解析可能在正常的 JSON 解析之前发生,并且具有讽刺意味的是,我的属性被 JSchema 解析忽略了。[JsonIgnore]
以下是我的主要问题:
- 为什么在下面的for循环中处理会导致错误?
json1
- 当 ParametersJson 的类型为字符串时,为什么 JSchema 解析器需要对象或布尔值?
- 难道没有一种实用的方法可以像我一样对 JSON 进行编码,并按照我的期望对其进行全部反序列化,而不会出错吗?我想在客户端上将 JSON 架构表示为字符串。
json1
这是错误:Unhandled exception. Newtonsoft.Json.Schema.JSchemaReaderException: Unexpected token encountered when reading schema. Expected StartObject, Boolean, got String. Path 'parameters', line 7, position 9. at Newtonsoft.Json.Schema.Infrastructure.JSchemaReader.EnsureToken(JsonReader reader, String name, List`1 tokenTypes, String errorMessage)
下面是 .NET Fiddle:https://dotnetfiddle.net/GE8OMP
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Schema;
public class Program
{
public static void Main()
{
string json0 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}
}".Replace("'", "\"");
string json1 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
'{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}'
}".Replace("'", "\"");
var arr = new[]{json0, json1};
foreach (var json in arr)
{
Function deserializedFunction = JsonConvert.DeserializeObject<Function>(json);
Console.WriteLine($"Name: {deserializedFunction.Name}");
Console.WriteLine($"Description: {deserializedFunction.Description}");
Console.WriteLine($"Parameters: {deserializedFunction.Parameters}");
Console.WriteLine("-------------");
}
}
}
#nullable enable
public class Function
{
/// <summary>
/// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description of what the function does, used by the model to choose when and how to call the function.
/// </summary>
public string? Description { get; set; }
/// <summary>
/// The parameters the functions accepts, described as a JSON Schema object.
/// <br></br>
/// <br></br>
/// To describe a function that accepts no parameters, provide the value {"type": "object", "properties": { } }.
/// </summary>
// Need to convert from string coming from client to the JSchema object.
[JsonIgnore]
public JSchema Parameters { get; set; }
[JsonProperty("parameters")]
public string ParametersJson { get => Parameters.ToString(); set => Parameters = JSchema.Parse(value); }
public Function(string name, string? description, JSchema parameters)
{
Name = name;
Description = description;
Parameters = parameters;
}
}
答:
恕我直言,您需要修复 json1
string json1 = @"
{
'Name': 'TestFunction',
'Description': 'This is a test function.',
'parameters':
'{
'type': 'object',
'properties':
{
'prop1':
{
'type': 'string'
}
}
}'
}".Replace("'{", "{").Replace("}'", "}").Replace("'", "\"");
第一件事是你的第二个JSON无效:
值中的引号需要转义 ()。
parameters
\"
字符串值不能在 JSON 中包含多行。
正确的 JSON 应为:
{
"Name": "TestFunction",
"Description": "This is a test function.",
"parameters": "{\"type\": \"object\", \"properties\": {\"prop1\": {\"type\": \"string\"}}}"
}
假设你已经修复了JSON问题,对于构造函数,你应该用多种类型来处理:parameters
在构造函数中将类型更改为 以允许多种类型的值。
parameters
JToken
处理不同的 (, )。
parameters.Type
JTokenType
String
Object
public Function(string name, string? description, JToken parameters)
{
Name = name;
Description = description;
if (parameters.Type == JTokenType.String)
{
Parameters = JSchema.Parse(parameters.ToString());
}
else if (parameters.Type == JTokenType.Object)
{
Parameters = parameters.ToObject<JSchema>();
}
}
注意,处理不同的语句也可以简化为:if-else
JTokenType
Parameters = JSchema.Parse(parameters.ToString());
评论
parameters
parameters
JsonSchema