C# 是否可以将对象序列化为与使用Json.Net反序列化不同的方式?
以下是我的例子: JSON请求字符串:C# 是否可以将对象序列化为与使用Json.Net反序列化不同的方式?,c#,serialization,json.net,C#,Serialization,Json.net,以下是我的例子: JSON请求字符串: { entity: '09f7cb28-0464-41c8-a20d-1b05eb1cda0a' } 我的请求对象: public class Request { public Request() { } [JsonProperty("entity")] private string EntityIdentifier { get; set; } public EntityObject Entity { get
{
entity: '09f7cb28-0464-41c8-a20d-1b05eb1cda0a'
}
我的请求对象:
public class Request {
public Request() { }
[JsonProperty("entity")]
private string EntityIdentifier { get; set; }
public EntityObject Entity { get; set; }
}
我已经完成了这项工作,因此字符串被传递到EntityIdentifier,这很好,然后在我的代码中,我使用entity identifier属性找到实际的实体,用找到的实体填充entity属性,但这是我序列化对象时得到的结果:
{
entity: '09f7cb28-0464-41c8-a20d-1b05eb1cda0a',
Entity: {
// my object's properties
}
}
当我真正想要的是:
{
entity: {
// my object's properties
}
}
现在,我知道我可以把它分成两个不同的类,我可能不得不这样做,但是如果有一种方法可以把它都放在同一个类中,那就太棒了,可以节省我大量的编码时间
澄清一下,因为我似乎没有很好地解释我想要什么:
免责声明:这不存在(AFAIK),但这是我想要的:
public class Request {
public Request() { }
[JsonProperty("entity", OnlyWhen=Deserializing)]
private string EntityIdentifier { get; set; }
[JsonProperty("entity", OnlyWhen=Serializing)]
public EntityObject Entity { get; set; }
}
这是我真正想要实现的,但就我所能看到的而言,我能实际放置这类代码的唯一地方是在自定义转换器中,但不幸的是,在使用转换器时,我似乎无法确定它是用于序列化还是反序列化。我相信您只需要用[ScriptIgnore]和/或[JsonIgnore]标记实体,如下所示:
[ScriptIgnore]
[JsonIgnore]
public EntityObject Entity { get; set; }
我听说杰索尼诺有时不工作。两者都使用可能是你最好的选择
另外,我相信你在描述问题时的措辞是不正确的。您声明:“这是我在反序列化对象时得到的结果”——实际上,我相信您的意思是“序列化”
如果需要在设置EntityIdentifier时填充实体,请将EntityIdentifier的代码替换为以下代码:
string _eId;
[JsonProperty("entity")]
private string EntityIdentifier
{
get{return _eId;}
set
{
_eId = value;
Entity = someMethodToRetrieveTheEntityById(_eId);
}
}
使用JsonIgnore属性如何
public class Request
{
public Request() { }
[JsonIgnore]
private string EntityIdentifier { get; set; }
[JsonProperty("entity")]
public EntityObject Entity { get; set; }
}
这里的问题可能是你试图强迫一个班级做两个班级的工作。为什么不:
// Deserialize requests into this.
public class EntityRequest
{
[JsonProperty("entity")]
private string EntityIdentifier { get; set; }
}
// Serialize these to file/etc.
public class EntityData
{
[JsonProperty("entity")]
public EntityObject Entity { get; set; }
}
然后将请求反序列化为EntityRequest对象,使用EntityRequest和其他一些逻辑加载EntityData对象,然后将EntityData对象序列化为文件。这里的JsonProperty属性意味着请求和输出实体都被称为“实体”,就像在OP中一样。这似乎就是您所追求的工作流
将所有内容塞进一个类会使问题变得比需要的更复杂。您可以使用自定义的
JsonConverter
解决此问题,类似于:
public class RequestConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Request));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// On deserialization, the JSON has an entity identifier (GUID)
// so use it to retrieve the actual object from the database.
JToken token = JToken.Load(reader);
Request req = new Request();
req.Entity = RetrieveFromDatabase(token["entity"].ToString());
return req;
}
private EntityObject RetrieveFromDatabase(string entityIdentifier)
{
// Implement this method to retrieve the actual EntityObject from the DB.
// (Return null if the object is not found.)
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// On serialization, write out just the entity object properties
Request req = (Request)value;
JObject obj = new JObject();
obj.Add("entity", JToken.FromObject(req.Entity));
obj.WriteTo(writer);
}
}
要使用转换器,只需使用[JsonConverter]
属性修饰请求
类,如下所示。请注意,您可以删除privateEntityIdentifier
属性,因为不再需要它。转换器负责根据JSON中的标识符从数据库中检索EntityObject
[JsonConverter(typeof(RequestConverter))]
public class Request
{
public Request() { }
public EntityObject Entity { get; set; }
}
注意,如果您不想让转换器负责填充实体对象,您仍然可以使用转换器的思想。在这种情况下,让
ReadJson
方法在请求上设置EntityIdentifier
属性。但是,由于您已将此属性设置为私有属性,因此您需要使用反射来完成此操作,将属性设置为公共属性,或者为转换器可以使用标识符实例化的请求设置构造函数。也许您只需要确定JSON.Net无法序列化EntityObject的原因(例如无限递归)您是否只需要将您的实体
属性标记为未序列化?如果这是检索正确项的方式,则需要序列化id。当您反序列化时,只需从结果返回实体(对象),而不是整个请求?这并不是我不希望实体属性序列化,或者存在错误……简单地说,我想要的是“当仅反序列化写入[EntityIdentifier]时,当仅序列化[Entity]时,但这两个属性都作为[entity]“,这更有意义吗?您或我的术语有误。仅将id用作名称您可以反序列化您的对象,并且您不必担心它?对不起,是的,我的意思是序列化,现在将更改它。不起作用,因为当我序列化它时,entity将是字符串而不是对象,这不符合我在下指定的内容“当我真正想要的是:"。如果您阅读了我在最初帖子下的评论,这可能也会为您澄清这一点。因此-反序列化时,您只想查看实体ID,但序列化时,您想输出所有实体属性?这没有多大意义。实际上,实体应该知道自己的ID-并且在请求sho中为其指定单独的属性不需要。请参阅我的编辑,实体ID位于请求对象上,实体对象位于请求对象上。我不是在实体对象上指定实体ID,而是在请求对象上指定实体ID,然后运行一些代码,使用请求对象上的实体ID填充实体对象。希望这是有意义的。但是当我现在反序列化字符串时,这将不起作用,因为字符串无法转换为EntityObject。谢谢,但我在最初的帖子中已经说过,我可以拆分这些内容,但如果有其他方法,那会更好(对我来说),否则我将不得不走这条路。像这样拆分实体将是一种干净、快速、可读和可维护的方式,可以让您想要的数据进出您的系统。您的OP是一个很好的问题,因为它突出了在常见用例中使用JSON.NET可以和不能做什么,但感觉您正在尝试适应一个正方形当你有一个圆钉可用时,把它钉在一个圆孔里。