1

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?

7
  • Why does order matter? That is a pretty bad API smell. Commented Nov 29, 2013 at 23:18
  • Can you paste the code configurating WCF to use JSON.NET as the serializer? Commented Nov 29, 2013 at 23:21
  • 1
    @JonathanHolland: of course, order doesn't really matter. But the JSON representation is much more human-readable if it is ordered a particular way. As to pasting the code configuring WCF to use JSON, it's already above: you apply [JsonObject(MemberSerialization = Newtonsoft.Json.MemberSerialization.OptIn)], unless I'm missing a step. Commented Nov 30, 2013 at 3:18
  • I'm not sure what particular WCF framework you are using, but that attribute is not going to be enough to tell it to use JSON.NET. You are still using the DataContractSerializer. Commented Nov 30, 2013 at 3:23
  • 1
    You need to implement a custom message formatter to make it use JSON.NET. blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/… Commented Nov 30, 2013 at 3:26

1 Answer 1

1

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
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.