Nested [DataContract]'s not serialising throug

2019-05-30 10:51发布

问题:

I'm having an issue where a class decorated with the [DataContract] attribute and appropriate [DataMember] attributes on properties is not serialising nested [DataContract] classes.

This is the class i'm trying to serialise:

[DataContract(Namespace = "http://foo.bar.com.au")]
[KnownType(typeof(Point))]
[KnownType(typeof(Site))]
public sealed class Alarm : IExtensibleDataObject
{
    [DataMember]
    public Point SourcePoint { get; set; }
    [DataMember]
    public Site SourceSite { get; set; }
    [DataMember]
    public DateTime ActiveTime { get; set; }
    [DataMember]
    public int Priority { get; set; }
    [DataMember]
    public bool IsAcknowledged { get; set; }
    [DataMember]
    public string Response { get; set; }

    private ExtensionDataObject _ExtensionData;
    public ExtensionDataObject ExtensionData
    {
        get { return _ExtensionData; }
        set { _ExtensionData = value; }
    }
}

This is being sent via a WCF service being hosted in an .NET 4.0 IIS site.

My issue is that for some reason, the SourcePoint and SourceSite properties are not being serialised. They are just returning null. Oddly, the ExtensionData contains all the fields of those two classes.

The other strange thing, is that when I run the IIS host locally on the dev web server, they are correctly serialised. The only change between the two tests is that the endpoint in the test client is pointing to the different IIS hosts.

Anyone have any idea's what's happening here?

EDIT: Added Site & Point snippets

[DataContract(Namespace = "http://foo.bar.com.au")]
public sealed class Site : BaseObject
{
    //~Site Details
    [DataMember]
    public string GisAssetId { get; set; }
    [DataMember]
    public string Catchment { get; set; }
    [DataMember]
    public string Description { get; set; }
    [DataMember]
    public string Location { get; set; }
    [DataMember]
    public string MelwaysReference { get; set; }
    [DataMember]
    public double Latitude { get; set; }
    [DataMember]
    public double Longitude { get; set; }
    ...
}

And the Point class.

[DataContract(Namespace = "http://foo.bar.com.au")]
public class Point : BaseObject
{
    [DataMember]
    public string Tag { get; set; }
    [DataMember]
    public string Description { get; set; }
    [DataMember]
    public object CurrentValue { get; set; }
    [DataMember]
    public string CurrentValueFormatted { get; set; }
    [DataMember]
    public bool IsDigital { get; set; }
    [DataMember]
    public DateTime LastUpdated { get; set; }
    [DataMember]
    public string Source { get; set; }
    [DataMember]
    public bool InService { get; set; }
    [DataMember]
    public bool IsAlarmEnabled { get; set; }
    [DataMember]
    public double TrendMinimum { get; set; }
    [DataMember]
    public double TrendMaximum { get; set; }
}

It should be noted that BaseObject is a base class that has the same DataContract signature as the rest.

回答1:

The issue was that the Visual Studio Web Setup project, that was being used to deploy to the server, wasn't updating the dependencies of the IIS host properly.

This means that any changes to the data contracts were not being copied across, causing the issues as the server didn't know about the properties to serialise them.

I had to remove the project output from the setup project and re-add it before it would pick up the dependencies properly.

Now everything works again!