简体   繁体   English

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

[英]caliburn.micro serialization issue when implementing PropertyChangedBase

I'm developing a client/server data driven application using caliburn.micro for frontend and Asp.net WebApi 2 for backend.我正在开发一个客户端/服务器数据驱动的应用程序,前端使用 caliburn.micro,后端使用 Asp.net WebApi 2。

public class Person
{
    public int Id {get;set;}
    public string FirstName{get;set;}
    ...
}

The application contains a class called "Person".该应用程序包含一个名为“Person”的类。 A "Person" object is serialized (JSON) and moved back and forth from client to server using simple REST protocal. “Person”对象被序列化 (JSON) 并使用简单的 REST 协议从客户端来回移动到服务器。 The solution works fine without any problem.该解决方案工作正常,没有任何问题。

Problem:问题:

I have set a parent class "PropertyChangedBase" for "Person" in order to implement NotifyOfPropertyChanged().为了实现 NotifyOfPropertyChanged(),我为“Person”设置了一个父类“PropertyChangedBase”。

public class Person : PropertyChangedBase
{
    public int Id {get;set;}

    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            _firstName = value;
            NotifyOfPropertyChange(() => FirstName);
        }
    }
    ...
}

But this time the properties of class "Person" has NULL values at receiving end.但是这次“Person”类的属性在接收端有 NULL 值。

I guess there is a problem with serialization / deserialization.我猜序列化/反序列化有问题。 This is only happens when implementing PropertyChangedBase.这仅在实现 PropertyChangedBase 时发生。

Can anyone help me to overcome this issue?谁能帮我解决这个问题?

You need to add the [DataContract] attribute to your Person class and the [DataMember] attribute to every property and field you wish to serialize:您需要将[DataContract]属性添加到您的Person类,并将[DataMember]属性添加到您希望序列化的每个属性和字段:

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

    private string _firstName;

    [DataMember]
    public string FirstName { get; set; }
}

You need to do this because the caliburn.micro base class PropertyChangedBase has the [DataContract] attribute:您需要这样做是因为caliburn.micro基类PropertyChangedBase具有[DataContract]属性:

namespace Caliburn.Micro {
    [DataContract]
    public class PropertyChangedBase : INotifyPropertyChangedEx
    {
    }
}

But why should this be necessary?但为什么这是必要的呢? In theory, the presence of the DataContractAttribute applied to the base class should not affect your derived Person class, because DataContractAttribute sets AttributeUsageAttribute.Inherited = false :理论上,应用于基类的DataContractAttribute的存在不应影响您派生的Person类,因为DataContractAttribute设置AttributeUsageAttribute.Inherited = false

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

However, HttpClientExtensions.PostAsJsonAsync uses the default instance of JsonMediaTypeFormatter , which by default uses the Json.NET library to perform serialization.但是, HttpClientExtensions.PostAsJsonAsync使用JsonMediaTypeFormatter的默认实例,默认情况下它使用 Json.NET 库来执行序列化。 And Json.NET does not respect the Inherited = false attribute of DataContractAttribute , as is explained here并且 Json.NET 不尊重DataContractAttributeInherited = false属性,如解释here

[Json.NET] detects the DataContractAttribute on the base class and assumes opt-in serialization. [Json.NET] 检测基类上的 DataContractAttribute 并假定选择加入序列化。

(For confirmation see Question about inheritance behavior of DataContract #872 which confirms this behavior of Json.NET continues to be as intended.) (有关确认,请参阅有关 DataContract #872 的继承行为的问题,该问题确认 Json.NET 的这种行为继续符合预期。)

So you need to add those attributes after all.所以你毕竟需要添加这些属性。

Alternatively, if you do not want to have to apply data contract attributes all over your derived classes, you could switch to DataContractJsonSerializer following the instructions here: JSON and XML Serialization in ASP.NET Web API :或者,如果您不想在所有派生类中应用数据协定属性,您可以按照以下说明切换到DataContractJsonSerializerASP.NET Web API 中的 JSON 和 XML 序列化

If you prefer, you can configure the JsonMediaTypeFormatter class to use the DataContractJsonSerializer instead of Json.NET.如果您愿意,可以将JsonMediaTypeFormatter类配置为使用DataContractJsonSerializer而不是 Json.NET。 To do so, set the UseDataContractJsonSerializer property to true :为此,请将UseDataContractJsonSerializer属性设置为true

 var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; json.UseDataContractJsonSerializer = true;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM