(De-) Serialize known types similar to Microsoft

So far, I have used the Microsoft DataContractJsonSerializer to serialize and deserialize my business objects into data transfer objects (DTOs) formatted as JSON, DTOs are marked with the DataContract attribute . A small example:

[DataContract(Name = "Geometry", Namespace = "myContract.com/dto")]
[KnownType(typeof(Point))]
[KnownType(typeof(Line))]
public class Geometry
{
}

[DataContract(Name = "Point", Namespace = "myContract.com/dto")]
public class Point : Geometry
{
    [DataMember(Name = "x")]
    public double X { get; set; }

    [DataMember(Name = "y")]
    public double Y { get; set; }
}

[DataContract(Name = "Line", Namespace = "myContract.com/dto")]
public class Line: Geometry
{
    [DataMember(Name = "start")]
    public Point Start { get; set; }

    [DataMember(Name = "end")]
    public Point End { get; set; }
}

It serializes as:

"geometry":{"__type":"Point:myContract.com/dto","x":23133.75569999963,"y":21582.385849999264}

Due to performance issues, I switched to Newtonsoft Json.NET. When using JSON strings look like this:

"geometry":{"$type":"A.B.C.Point, A.B.C","x":23133.75569999963,"y":21582.385849999264}

Is it possible to serialize an object with Json.NET into a Microsoft compatible JSON string using "__type" and the contract namespace instead of "$ type" and a combination of classes? I am using .NET 3.5.

Thanks in advance!

+4
source share
1

, , JsonTypeReflector.cs :

public const string TypePropertyName = "$type";

: , type , SerializationBinder Class , this , .


, . -, ( Geometry) ,

[DataContract(Name = "Entity", Namespace = "myContract.com/dto")]
public abstract class Entity
{
    [DataMember(Name = "__type", Order = 0)]
    public string EntityTypeName
    {

        get
        {
            var typeName = GetType().Name;
            if (Attribute.IsDefined(GetType(), typeof(DataContractAttribute)))
            {
                var attribute = GetType().GetCustomAttributes(typeof(DataContractAttribute), true).FirstOrDefault() as DataContractAttribute;
                if (attribute != null) typeName = typeName + ":" + attribute.Namespace;
            }
            return typeName;
        }
    }
}

Geometry :

[DataContract(Name = "Geometry", Namespace = "myContract.com/dto")]
[KnownType(typeof(Point))]
[KnownType(typeof(Line))]
public class Geometry : Entity
{
}

, JsonSerializerSettings.TypeNameHandling TypeNameHandling.None, $type.

  var point = new Point { X = 23133.75569999963, Y = 21582.385849999264 };

  var jsonPoint = JsonConvert.SerializeObject(point, new JsonSerializerSettings
  {
       TypeNameHandling = TypeNameHandling.None,   //do not write type property(!)
  });
  Console.WriteLine(jsonPoint);

{\"__type\":\"Point:myContract.com/dto\",\"x\":23133.75569999963,\"y\":21582.385849999264}

P.S.

, DataMember.Order, :

[DataContract(Name = "Point", Namespace = "myContract.com/dto")]
public class Point : Geometry
{
    [DataMember(Name = "x",Order = 1)]
    public double X { get; set; }

    [DataMember(Name = "y", Order = 2)]
    public double Y { get; set; }
}

[DataContract(Name = "Line", Namespace = "myContract.com/dto")]
public class Line : Geometry
{
    [DataMember(Name = "start", Order = 1)]
    public Point Start { get; set; }

    [DataMember(Name = "end", Order = 2)]
    public Point End { get; set; }
}
0

Source: https://habr.com/ru/post/1588951/


All Articles