实现PropertyChangedBase时的caliburn.micro序列化问题

Rah*_*hul 5 c# wpf serialization json caliburn.micro

我正在开发一个客户端/服务器数据驱动的应用程序,使用caliburn.micro作为前端,使用Asp.net WebApi 2作为后端.

public class Person
{
    public int Id {get;set;}
    public string FirstName{get;set;}
    ...
}
Run Code Online (Sandbox Code Playgroud)

该应用程序包含一个名为"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);
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是这次"Person"类的属性在接收端有NULL值.

我猜序列化/反序列化存在问题.这仅在实现PropertyChangedBase时发生.

任何人都可以帮我解决这个问题吗?

dbc*_*dbc 7

您需要将[DataContract]属性添加到您的Person类,并将[DataMember]属性添加到您希望序列化的每个属性和字段:

[DataContract]
public class Person : PropertyChangedBase
{
    [DataMember]
    public int Id { get; set; }

    private string _firstName;

    [DataMember]
    public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

您需要这样做,因为caliburn.micro基类PropertyChangedBase具有以下[DataContract]属性:

namespace Caliburn.Micro {
    [DataContract]
    public class PropertyChangedBase : INotifyPropertyChangedEx
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

但为什么这有必要呢?理论上,DataContractAttribute应用于基类的存在不应该影响派生Person类,因为DataContractAttribute集合AttributeUsageAttribute.Inherited = false:

[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum, Inherited = false, 
AllowMultiple = false)]
public sealed class DataContractAttribute : Attribute
Run Code Online (Sandbox Code Playgroud)

但是,HttpClientExtensions.PostAsJsonAsync使用默认实例JsonMediaTypeFormatter,默认情况下使用Json.NET库执行序列化. 而Json.NET不尊重Inherited = false的属性DataContractAttribute,如解释在这里

[Json.NET]检测基类上的DataContractAttribute并假定选择加入序列化.

(有关确认,请参阅有关DataContract#872的继承行为的问题,该问题确认Json.NET的此行为仍然符合预期.)

所以你需要添加这些属性.

或者,如果您不希望在派生类中应用数据协定属性,则可以切换到DataContractJsonSerializer以下说明:ASP.NET Web API中的JSON和XML序列化:

如果您愿意,可以将JsonMediaTypeFormatter类配置为使用DataContractJsonSerializer而不是Json.NET.为此,请将UseDataContractJsonSerializer属性设置为true:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = true;
Run Code Online (Sandbox Code Playgroud)