到目前为止,我已经使用Microsoft的DataContractJsonSerializer将我的业务对象序列化和反序列化为格式化为JSON的数据传输对象(DTO)。 DTO标有DataContract属性。一个小例子:
[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; }
}
这被序列化为:
"geometry":{"__type":"Point:myContract.com/dto","x":23133.75569999963,"y":21582.385849999264}
由于性能问题,我改用了Newtonsoft Json.NET。使用它时,JSON字符串如下所示:
"geometry":{"$type":"A.B.C.Point, A.B.C","x":23133.75569999963,"y":21582.385849999264}
是否有可能使用“__type”和契约名称空间而不是“$ type”和类组装组合将使用Json.NET的对象序列化为符合Microsoft的JSON字符串? 我正在使用.NET 3.5。
提前致谢!
答案 0 :(得分:0)
不幸的是,似乎无法调整属性名称,因为它在内部 JsonTypeReflector.cs class中声明为:
public const string TypePropertyName = "$type";
注意:另一方面,可以自定义类型属性值, SerializationBinder Class旨在实现此目的,this example演示了如何指定自定义类型属性值。
我建议使用以下解决方案来编写自定义类型属性。首先,我们需要引入具有type属性的基本实体类(或修改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
class:
[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; }
}