相关疑难解决方法(0)

无法使用Json.NET对具有多个构造函数的类进行反序列化

我有一个我不用多个构造函数控制的类型,相当于这个:

    public class MyClass
    {
        private readonly string _property;

        private MyClass()
        {
            Console.WriteLine("We don't want this one to be called.");
        }

        public MyClass(string property)
        {
            _property = property;
        }

        public MyClass(object obj) : this(obj.ToString()) {}

        public string Property
        {
            get { return _property; }
        }

    }
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试反序列化它时,将调用私有无参数构造函数,并且永远不会设置该属性.考试:

    [Test]
    public void MyClassSerializes()
    {
        MyClass expected = new MyClass("test");
        string output = JsonConvert.SerializeObject(expected);
        MyClass actual = JsonConvert.DeserializeObject<MyClass>(output);
        Assert.AreEqual(expected.Property, actual.Property);
    }
Run Code Online (Sandbox Code Playgroud)

给出以下输出:

We don't want this one to be called.

  Expected: "test"
  But …
Run Code Online (Sandbox Code Playgroud)

.net c# json json.net

12
推荐指数
1
解决办法
7046
查看次数

将JSON反序列化为多个C#子类之一

我有一个看起来像这样的json结构:

"list":[
  {
    "type":"link",
    "href":"http://google.com"
  },
  {
    "type":"image",
    "src":"http://google.com/logo.png"
  },
  {
    "type":"text",
    "text":"some text here"
  },
]
Run Code Online (Sandbox Code Playgroud)

我想将其反序列化为对象列表,其中每个对象都是基类的子类.列表中的每个项目都有不同的属性(href,src,text),因此我不能使用相同的类来获取一个.相反,我想要一个普通类的三个子类.JSON列表中每个项的type属性可用于决定使用哪个子类.例如,我可以拥有以下类

public Item{
  public string type {get; set;}
}
public LinkItem : Item {
  public string href {get; set;}
}
public ImageItem : Item {
  public string src {get; set;}
}
public TextItem : Item {
  public string text {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?或者是否有更好的方法来反序列化异构对象类型列表?

编辑:

我顺便使用json.net

c# inheritance json deserialization

10
推荐指数
1
解决办法
3013
查看次数

使用JsonConverter进行Json.NET自定义序列化 - 如何获取"默认"行为

我的类DataType有一个JsonConverter.当Json中使用的普通字符串作为DataType类型的属性值时,我想做一些特殊处理.在值是"完整"对象的情况下,我想进行"正常"反序列化.

这是我的尝试

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.Value != null && reader.ValueType == typeof (string))
    {
        return someSpecialDataTypeInstance;
    }
    else if (reader.TokenType == JsonToken.StartObject)
    {
        DataType dataType = serializer.Deserialize<DataType>(reader);
        return dataType;
    }
    else
    {
        throw new JsonSerializationException();
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为这一行:DataType dataType = serializer.Deserialize(reader); 导致无限递归.

这可以轻易地完成吗?(无需手动逐个财产)

c# serialization json json.net

10
推荐指数
1
解决办法
4833
查看次数

自定义反序列化器仅适用于json.NET的某些字段

我正在尝试反序列化一些JSON:

{ 
   "a":1,
   "b":25,
   "c":"1-7",
   "obj1":{ 
      "a1":10,
      "b1":45,
      "c1":60
   },
   "obj2":[ 
      { 
         "a2":100,
         "b2":15,
         "c2":50
      },
      { 
         "e2":"1,2,5-7",
         "f2":"1,3-5",
         "a2":25
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我想找到一种方法来定义仅针对某些字段的自定义反序列化.

在下面的代码中,我将需要注意的字段(自定义处理)和可以以某种方式自动完成的字段分开.

是否可以自动反序列化"正常"字段?(不需要任何特定的自定义处理)

[JsonConverter(typeof(ConfigurationSerializer))]
    public class Configuration
    {
        public int a { get; set; }
        public int b { get; set; }
        public Obj1 obj1 { get; set; }

        public int[] c { get; set; }
        public IList<Obj2> obj2 { get; set; }
    }

    public class ConfigurationSerializer : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, …
Run Code Online (Sandbox Code Playgroud)

c# json.net json-deserialization

9
推荐指数
1
解决办法
5749
查看次数

JSON.NET:反序列化包含从接口派生的对象列表的类

我在反序列化我的对象时遇到问题。它包含以下属性:

public List<IShape> Shapes { get; set; };
Run Code Online (Sandbox Code Playgroud)

JSON.NET 反序列化器总是告诉我,不可能实例化接口。

我有几个实现 IShape 接口的类,例如Polyline -> IPolyline -> IShape。我已经尝试了两种解决方案:

但我得到了同样的异常,即 IShape 无法实例化,被抛出。

TypeNameHandling.Auto我用,序列化对象TypeNameHandling.All也没有帮助,即使我使用上面链接的帖子中提到的转换器也是如此。

有谁知道这个问题的解决方案?如果需要一些代码,我很乐意发布它。

以下是生成的 JSON 示例。

"$type": "SketchModel.Layer, SketchModel",
        "Id": 57865477,
        "Shapes": {
          "$type": "System.Collections.Generic.List`1[[SketchModel.Shapes.AbstractShapes.IShape, SketchModel]], mscorlib",
          "$values": [
            {
              "$type": "SketchModel.Shapes.Polyline, SketchModel",
Run Code Online (Sandbox Code Playgroud)

该行负责解决这个问题:

"System.Collections.Generic.List`1[[SketchModel.Shapes.AbstractShapes.IShape, SketchModel]], mscorlib"
Run Code Online (Sandbox Code Playgroud)

它根本不知道如何实例化 IShape。如果我创建一个自定义转换器并让它为每个 IShape 返回一条折线,它可以工作,但不会创建任何其他形状(例如椭圆)。

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)自定义转换器中重写的方法中,如果我让我打印 objectType 的完整类型名称,它始终是 IShape,而不是其他任何内容......

c# json.net deserialization

6
推荐指数
1
解决办法
9437
查看次数

如何在不将转换器传递给DeserializeObject的情况下反序列化抽象项列表?

我有一些继承,需要一个自定义JsonConverter反序列化.我现在正在使用一种非常简单的方法,根据某些属性的存在来确定类型.

重要说明:在我的实际代码中,我无法触摸DeserializeObject调用,即我无法在那里添加自定义转换器.我知道这在某种程度上是一个XY问题,因此我的答案可能就是我想要的不可能.据我所知,这使我的问题与这个问题略有不同.

这是我的情况的一个副本:

abstract class Mammal { }
class Cat : Mammal { public int Lives { get; set; } }
class Dog : Mammal { public bool Drools { get; set; } }
class Person
{
    [JsonConverter(typeof(PetConverter))]
    public Mammal FavoritePet { get; set; }

    [JsonConverter(typeof(PetConverter))]
    public List<Mammal> OtherPets { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

这是自定义转换器:

public class PetConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) { return objectType == typeof(Mammal); …
Run Code Online (Sandbox Code Playgroud)

c# json abstract-class json.net

6
推荐指数
1
解决办法
317
查看次数

在将JSON解析为JToken时如何将所有键更改为小写

我有一个JSON字符串,键有大写和小写字符:

{"employees":[
    {"FIrstName":"John", "LASTname":"Doe"},
    {"FIRSTNAME":"Anna", "LaSTNaME":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}
Run Code Online (Sandbox Code Playgroud)

我想将它转换为一个JToken对象,并将所有键都设置JToken为小写.所以内部JToken应该如下:

{"employees":[
    {"firstname":"John", "lastname":"Doe"},
    {"firstname":"Anna", "lastname":"Smith"},
    {"firstname":"Peter", "lastname":"Jones"} 
]}
Run Code Online (Sandbox Code Playgroud)

以前我JToken json = JToken.Parse(jsonString);用来转换,但我不知道如何使键小写.有任何想法吗?

我需要这样做的原因是我的JsonSchema验证将不区分大小写.

c# json json.net jsonschema json-deserialization

6
推荐指数
1
解决办法
1625
查看次数

将JSON反序列化为子类

我有3个班:

class Person {
    public bool IsFemale { get; set; }
}

class Female : Person {
    public string FemaleSpecificProperty { get; set; }
}

class Male: Person { 
    public string MaleSpecificProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如何根据属性的值将给定的JSON字符串反序列化为特定的实例(FemaleMale)Person.IsFemale?(我不知道使用了哪种确切的类型,而且该属性是唯一的指示)

我看着雇用,CustomCreationConverter<T>但无法弄清楚如何使它在这里工作.

c# json.net

5
推荐指数
1
解决办法
3237
查看次数

使用JSON.NET与ExpandableObjectConverter的问题

我定义了以下类:

<TypeConverter(GetType(ExpandableObjectConverter))>
<DataContract()>
Public Class Vector3

   <DataMember()> Public Property X As Double
   <DataMember()> Public Property Y As Double
   <DataMember()> Public Property Z As Double

   Public Overrides Function ToString() As String

      Return String.Format("({0}, {1}, {2})",
                           Format(X, "0.00"),
                           Format(Y, "0.00"),
                           Format(Z, "0.00"))

   End Function

End Class
Run Code Online (Sandbox Code Playgroud)

使用DataContractJsonSerializer我按预期收到以下JSON:

{
  "Vector": {
    "X": 1.23,
    "Y": 4.56,
    "Z": 7.89
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,JSON.NET产生:

{
  "Vector": "(1.23, 4.56, 7.89)"
}
Run Code Online (Sandbox Code Playgroud)

如果我ExpandableObjectConverter从类中删除该属性,JSON.NET会按预期生成结果(与DataContractJsonSerializer相同).

不幸的是,我需要ExpandableObjectConverter这样,以便该类使用属性网格.

有没有办法告诉JSON.NET忽略ExpandableObjectConverters

我更喜欢使用JSON.NET,而不是DataContractJsonSerializer因为将枚举序列化为字符串表示更容易.

c# vb.net json typeconverter json.net

5
推荐指数
1
解决办法
1835
查看次数

Json.Net无法反序列化DateTime.MinValue

我尝试过DateTime.MinValue以各种可能的方式反序列化包含的Json字符串,但是当该set方法在我的对象上被调用时。日期总是从-01-01-01-更改为-01-01-02-。

被解析的Json明确包含

"inception_date": "0001-01-01T00:00:00+00:00"
Run Code Online (Sandbox Code Playgroud)

然后JsonConvert,我呼吁:

return JsonConvert.DeserializeObject<T>(json, deserializerSettings);
Run Code Online (Sandbox Code Playgroud)

T包含property:DateTime inception_date { get; set; }property 的基本结构在哪里。解串器设置如下:

deserializerSettings = new JsonSerializerSettings()
{
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DateParseHandling = Newtonsoft.Json.DateParseHandling.None,
    DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc
};
Run Code Online (Sandbox Code Playgroud)

然而,在Newtonsoft.Json.dll的肠子中,上述时间转换为以下时间jObject

"inception_date": "0001-01-02T00:00:00Z"
Run Code Online (Sandbox Code Playgroud)

我无法进入他们的代码,但是由于损坏已经在我的代码看到另一个调用之前完成了。ReadJson在JsonConverter中调用serializer.Populate(jObject.CreateReader(), target);where target是我的类的实例T,并且jObject已经以某种不正确的日期呈现了。

谁能弄清楚为什么会发生这种情况,或者我怎么能防止这种情况发生?创建jObject的方式似乎忽略了我的序列化程序设置,该设置程序明确表示不要使用日期字符串(DateParseHandling.None)。


我已经截屏了一下,以确切说明Newtonsoft的JsonConvert方法似乎失去了至关重要的配置价值的地方。

如您所见,这就是我调用JsonConvert的代码点:

在此处输入图片说明

dateParseHandling值设置为“无”,这就是它应该起作用的方式。

在下一步中,我跳了一些内部Newtonsoft调用,并进入了通用实现,该通用实现是JsonConverter我从公认的参考实现中借用的,以便能够了解发生了什么。在JsonReader突然传入已经失去了dateParseHandling价值:

在此处输入图片说明

由于此值已切换回DateTime-jObject的内部工作试图将其表示为内部本地化的DateTime,因为我的时区为负,所以该下溢发生了,我们已经表示了最小的DateTime值,导致转换回到UTC添加一整天。

c# json json.net deserialization

5
推荐指数
1
解决办法
5373
查看次数