【发布时间】:2014-11-22 15:10:05
【问题描述】:
我有一个用来表示身份的类,它包含一个字符串值。
然后我有另一个用于表示事件的类,这包括一个标识对象和一个字符串名称。
我可以很好地从对象序列化为 JSON 字符串,我得到了字符串:
{"Id":{"Value":"2e4146c2-66c9-4637-8936-29ccfc5df638"},"Name":"Jon Doe"}
但是,当我从上面的 JSON 转到对象时,在 MyIdentity 构造函数中,字符串 identityValue 以 "00000000-0000-0000-0000-000000000000" 的形式传入。
我还尝试为 MyIdentity 提供两个构造函数,一个用于字符串,一个用于 Guid,但结果相同。这背后的想法是将数据存储为字符串,但请记住,如果需要,我们可以转换为 Guid(因为身份将由字符串或 Guid 形成)。
public class MyEntityId : MyIdentity
{
public MyEntityId(Guid identityValue)
: base(identityValue)
{
}
}
public abstract class MyIdentity
{
protected readonly bool convertableAsGuid;
protected readonly string value;
public string Value { get { return this.value; } }
public MyIdentity(string identityValue)
{
this.value = identityValue;
Guid guid;
if(Guid.TryParse(identityValue, out guid)==false)
this.convertableAsGuid = false;
}
public MyIdentity(Guid identityValue)
{
this.value = identityValue.ToString();
this.convertableAsGuid = true;
}
}
static void Main(string[] args)
{
var evnt = new MyEvent(new MyEntityId(Guid.NewGuid()), "Jon Doe");
var eventHeaders = new Dictionary<string, object>
{
{"EventClrTypeName", evnt.GetType().AssemblyQualifiedName}
};
var serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None };
var metadata = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(eventHeaders, serializerSettings));
var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(evnt, serializerSettings));
string dataAsString = Encoding.UTF8.GetString(data);
var eventClrTypeName = JObject.Parse(Encoding.UTF8.GetString(metadata)).Property("EventClrTypeName").Value;
var obj = JsonConvert.DeserializeObject(dataAsString, Type.GetType((string)eventClrTypeName));
// stepping through the above, a zero initialised GUID string is passed in to MyIdentity constructor
}
正如@hvd 友好地评论的那样,它似乎是 Value 只有一个 get 属性,如果我添加一个 set 属性也可以工作(所以我相信构造函数字符串值实际上没有被使用)。我不想在标识上放置 setter 的原因是为了编程设计,它是一个标识,一旦创建就不应更改。
我可以在属性上使用公共获取和保护集,我尝试了关键字[JsonProperty] 并且它有效......但是我不想用这些属性装饰我的域对象 - 还有其他方法吗?
【问题讨论】:
-
问题可能是
Value属性没有setter,无法映射到构造函数参数,但这并不能真正帮助您修复它。 -
对于它的价值,在我的情况下,我使用受保护的属性设置器获得了每个 GUID 成为空 GUID 的行为。这就是我提出这个问题的方式。我最终不得不把我的财产变成一个完整的公共财产,从建筑的角度来看我也不喜欢它,但实际上,在我的特殊情况下还不错。
标签: c# json json.net json-deserialization