You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

代码中如何解析此类JSON请求?结构化改写后输出不一致问题

问题分析与解决方案

差异原因

你的代码输出和初始请求不一致,核心是两个问题:

  1. 数据结构不匹配:初始请求的locations是字符串数组(每个元素是逗号分隔的经纬度字符串),而你定义的Request类中Locations是对象数组(每个元素包含Latitude和Longitude两个数值字段),序列化后自然生成对象结构的JSON,而非字符串数组。
  2. 命名规则不一致:初始JSON的键是小写的locations,但你的C#属性是大写的Locations,默认序列化会直接使用C#属性名作为JSON键名,导致键名大小写不匹配。

一、如何解析初始JSON请求

要把初始的字符串数组格式JSON解析为你的Request类对象,需要手动分割每个经纬度字符串,转换为Locations对象:

示例代码(使用Newtonsoft.Json)

// 初始JSON字符串
string originalJson = @"{""locations"" : [""53.44059300,-2.22992800"",""53.36246000,-2.26683200""]}";

// 解析JSON
var jObject = Newtonsoft.Json.Linq.JObject.Parse(originalJson);
var request = new Request();

foreach (string locString in jObject["locations"].Values<string>())
{
    // 分割经纬度字符串
    string[] coords = locString.Split(',');
    if (coords.Length == 2 
        && double.TryParse(coords[0], out double latitude) 
        && double.TryParse(coords[1], out double longitude))
    {
        request.Locations.Add(new Locations
        {
            Latitude = latitude,
            Longitude = longitude
        });
    }
}

二、如何生成与初始请求一致的输出

要将Request类对象序列化为字符串数组格式的JSON,需要自定义JSON序列化逻辑,覆盖默认的对象序列化行为:

方法1:自定义JsonConverter(推荐)

创建一个针对Request类的转换器,控制序列化和反序列化的逻辑:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

public class RequestConverter : JsonConverter<Request>
{
    // 序列化:将Request对象转为字符串数组格式的JSON
    public override void WriteJson(JsonWriter writer, Request value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("locations"); // 匹配初始JSON的小写键名
        writer.WriteStartArray();
        
        foreach (var location in value.Locations)
        {
            // 将Latitude和Longitude拼接为逗号分隔的字符串
            writer.WriteValue($"{location.Latitude},{location.Longitude}");
        }
        
        writer.WriteEndArray();
        writer.WriteEndObject();
    }

    // 反序列化:将字符串数组格式的JSON转为Request对象
    public override Request ReadJson(JsonReader reader, Type objectType, Request existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);
        var request = existingValue ?? new Request();
        
        foreach (string locString in jObject["locations"].Values<string>())
        {
            string[] coords = locString.Split(',');
            if (coords.Length == 2 
                && double.TryParse(coords[0], out double latitude) 
                && double.TryParse(coords[1], out double longitude))
            {
                request.Locations.Add(new Locations
                {
                    Latitude = latitude,
                    Longitude = longitude
                });
            }
        }
        
        return request;
    }
}

使用转换器序列化

var request = new Request();
// 假设已填充request.Locations的数据

var settings = new JsonSerializerSettings();
settings.Converters.Add(new RequestConverter());

// 生成与初始请求格式一致的JSON
string outputJson = JsonConvert.SerializeObject(request, settings);

方法2:临时修改类结构(简单场景)

如果只是临时生成对应格式,可以直接构造JSON字符串:

var locationsStrings = request.Locations.Select(loc => $"{loc.Latitude},{loc.Longitude}");
string outputJson = $"{{\"locations\": [{string.Join(",", locationsStrings.Select(s => $"\"{s}\""))}]}}";

补充:键名大小写匹配

如果不需要自定义转换器,仅需修正键名大小写,可以在Request类的属性上添加JsonProperty特性:

internal class Request : DerivedA
{
    [JsonProperty("locations")] // 指定JSON键名为小写
    public List<Locations> Locations { get; set; } = new List<Locations>();
}

内容的提问来源于stack exchange,提问作者lakykytik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 16:50:27