简体   繁体   中英

How to use Json.NET for schemaless JSON?

How to use Json.NET for schemaless JSON? Example: {"x":"y"} and {"x":["y"]}. I dont know in advance if x is one element or several. You have to create a model class in C# to use Json.NET, but C# is a stronly typed language, so you have to say "string x" or "List x", but I dont know in advance what x is.

See this: https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing

You could JArray to manually go through your data and check whether it is an array or not.

[TestMethod]
public void JsonParseToStrongTypeTest()
{
    JArray albums = JArray.Parse(jsonString) as JArray;

    // pick out one album
    JObject jalbum = albums[0] as JObject;

    // Copy to a static Album instance
    Album album = jalbum.ToObject<Album>();

    Assert.IsNotNull(album);
    Assert.AreEqual(album.AlbumName,jalbum.Value<string>("AlbumName"));
    Assert.IsTrue(album.Songs.Count > 0);
}

Oh now i understand. You can write a Json Converter.

The Model:

using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace QuickType
{

    public partial class TheModel
    {
        [JsonProperty("x")]
        [JsonConverter(typeof(SingleValueArrayConverter<string>))]
        public List<string> X { get; set; }
    }
}

The Converter

using System;
using System.Collections.Generic;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using Regiocast.Dds.ApiClient.DdsApiModels;

namespace Regiocast.Dds.ApiClient.JsonConverterResolver
{
    internal class SingleValueArrayConverter<T> : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            object retVal = new Object();
            if (reader.TokenType == JsonToken.StartObject)
            {
                T instance = (T)serializer.Deserialize(reader, typeof(T));
                retVal = new List<T>() { instance };
            }
            else if (reader.TokenType == JsonToken.StartArray)
            {
                retVal = serializer.Deserialize(reader, objectType);
            }
            return retVal;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            List<T> listValues = (List<T>)value;

            if (listValues.Count == 1)
            {
                JToken token = JToken.FromObject(listValues[0], serializer);
                token.WriteTo(writer);
            } else
            {
                JToken token = JToken.FromObject(listValues, serializer);
                token.WriteTo(writer);
            }
        }
    }
}

The Useage:

var deserializedObj = 
    JsonConvert.DeserializeObject<TheModel>(File.ReadAllText(json-file-path.json));    

Not tested but should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM