我正在开发一个客户端/服务器数据驱动的应用程序,使用caliburn.micro作为前端,使用Asp.net WebApi 2作为后端。
public class Person
{
public int Id {get;set;}
public string FirstName{get;set;}
...
}
该应用程序包含一个名为“Person”的类。 “Person”对象被序列化(JSON)并使用简单的REST协议从客户端到服务器来回移动。解决方案工作正常,没有任何问题。
问题:
我为“Person”设置了一个父类“PropertyChangedBase”,以实现NotifyOfPropertyChanged()。
public class Person : PropertyChangedBase
{
public int Id {get;set;}
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
NotifyOfPropertyChange(() => FirstName);
}
}
...
}
但是这次“Person”类的属性在接收端有NULL值。
我猜序列化/反序列化存在问题。 这仅在实现PropertyChangedBase时发生。
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:5)
您需要将Person
类添加到[DataContract]
public class Person : PropertyChangedBase
{
[DataMember]
public int Id { get; set; }
private string _firstName;
[DataMember]
public string FirstName { get; set; }
}
类,并将[DataContract]
属性添加到您希望序列化的每个属性和字段中:
[DataContract]
您需要执行此操作,因为[DataMember]
基类caliburn.micro具有namespace Caliburn.Micro {
[DataContract]
public class PropertyChangedBase : INotifyPropertyChangedEx
{
}
}
属性:
Person
但为什么这有必要呢?从理论上讲,应用于基类的PropertyChangedBase
的存在不应影响派生的[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false,
AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute
类,因为DataContractAttribute
:
Inherited = false
但是,DataContractAttribute
sets AttributeUsageAttribute.Inherited = false
使用HttpClientExtensions.PostAsJsonAsync
的默认实例,JsonMediaTypeFormatter
和Json.NET不尊重DataContractAttribute
的{{1}}属性,因为解释by default uses the Json.NET library to perform serialization.
[Json.NET]检测基类上的DataContractAttribute并假定选择加入序列化。
(有关确认,请参阅here,确认Json.NET的此行为仍然符合预期。)
所以你需要添加这些属性。
或者,如果您不想在所有派生类中应用数据协定属性,可以按照此处的说明切换到DataContractJsonSerializer
:Question about inheritance behavior of DataContract #872:
如果您愿意,可以配置 JsonMediaTypeFormatter 类以使用 DataContractJsonSerializer 而不是Json.NET。为此,请将 UseDataContractJsonSerializer 属性设置为 true :
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; json.UseDataContractJsonSerializer = true;