jbeldock
jbeldock

Reputation: 2925

JSON.Net not serializing when JsonProperty set?

I'm using the latest (4.5) version of Newtonsoft Json.Net to serialize a complex type returned by my WCF web service. For some reason, if I apply the [JsonProperty] attribute, the fields simply don't serialize:

    [DataContract]
[JsonObject(MemberSerialization = Newtonsoft.Json.MemberSerialization.OptIn)]
public class ScalarResult
{
    [JsonProperty(Order = 0)]
    public string QueryId { get; set; }

    [JsonProperty(Order = 1)]
    public float CurrentPeriodValue { get; set; }

    [JsonProperty(Order = 2)]
    public bool HasPriorValue { get; set; }

    [JsonProperty(Order = 3)]
    public float PriorPeriodValue { get; set; }

    [JsonProperty(Order = 4)]
    public float ChangeOverPrior { get; set; }

    [JsonProperty(Order = 5)]
    public float ChangeOverPriorPercent { get; set; }

This results in a skimpy return object:

{
"SomethingElse": "why am I the only thing visible?"
}

If I add [DataMember] to each field (which I'm not supposed to have to do, according to the the Json.NET docs), then the fields show up, but the (Order = x) attribute is ignored, leading me to believe Json.NET might not actually be doing the serialization:

[DataContract]
[JsonObject(MemberSerialization = Newtonsoft.Json.MemberSerialization.OptIn)]
public class ScalarResult
{
    [DataMember]
    [JsonProperty(Order = 0)]
    public string QueryId { get; set; }

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

    [DataMember]
    [JsonProperty(Order = 1)]
    public float CurrentPeriodValue { get; set; }

    [DataMember]
    [JsonProperty(Order = 2)]
    public bool HasPriorValue { get; set; }

    [DataMember]
    [JsonProperty(Order = 3)]
    public float PriorPeriodValue { get; set; }

    [DataMember]
    [JsonProperty(Order = 4)]
    public float ChangeOverPrior { get; set; }

    [DataMember]
    [JsonProperty(Order = 5)]
    public float ChangeOverPriorPercent { get; set; }

Which results in (the wrong order):

{
"ChangeOverPrior": 8,
"ChangeOverPriorPercent": 0.25,
"CurrentPeriodValue": 40,
"HasPriorValue": true,
"PriorPeriodValue": 32,
"QueryId": "CitiesMonitored_count",
"SomethingElse": "why am I the only thing visible?"
}

Any ideas on how I can verify that Json.Net is doing the serialization and, if so, why the (Order =) property is being ignored?

Upvotes: 1

Views: 3494

Answers (1)

jbeldock
jbeldock

Reputation: 2925

As @Jonathan Holland pointed out, I was not actually using Json.Net to serialize, despite my attribute markup. I would have to implement a custom message formatter to do that. Fortunately, what I want to do can be done with the regular DataContractSerializer, as this blog post explains.

So this will do the trick:

    [DataContract]
public class ScalarResult
{
    [DataMember(Order = 0)]
    public string QueryId { get; set; }

    [DataMember(Order = 1)]
    public float CurrentPeriodValue { get; set; }

    [DataMember(Order = 2)]
    public bool HasPriorValue { get; set; }

    [DataMember(Order = 3)]
    public float PriorPeriodValue { get; set; }

    [DataMember(Order = 4)]
    public float ChangeOverPrior { get; set; }

    [DataMember(Order = 5)]
    public float ChangeOverPriorPercent { get; set; }

    // rest of code here
    }

The result is now as expected:

{
    "QueryId": "SystemsMonitored_count",
    "CurrentPeriodValue": 60,
    "HasPriorValue": true,
    "PriorPeriodValue": 47,
    "ChangeOverPrior": 13,
    "ChangeOverPriorPercent": 0.276595742
}

Upvotes: 1

Related Questions