10

I've started using json.net to produce better DateTimes, but I've noticed that one of my properties isn't being serialized. It has no setter, and its getter is reliant upon another member of the object, e.g.

public int AmountInPence { get; set;}
public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }

I've made a class that inherits from JsonResult and the main line is:

string serializedObject = JsonConvert.SerializeObject(Data, new IsoDateTimeConverter());

Can anyone tell me how to force it to serialize that property?

Edit: Just to clarify - that was a simplified example. I've updated it to reflect that I am casting the int to decimal first. I'd forgotten to check previously, but the property is part of a partial class, because it's being returned from a WCF service. I'm declaring that property in my assembly, so could this be a clue?

2 Answers 2

18

There is nothing wrong with the Json.net. It can serialize read only properties just fine. The problem is in your AmountInPounds

public decimal AmountInPounds { get { return AmountInPence / 100;  } }

Because your are doing integer division with / 100 it means you will get 0 if AmountInPence is less than 100.

What you need is to use the m suffix to mark 100 as decimal:

public decimal AmountInPounds { get { return AmountInPence / 100m;  } }

to get the right result in AmountInPounds.

EDIT after comments:

The calculated property AmountInPounds was in a partial class of a WCF service's generated DataContract.

And in DataContract if a property is not marked with DataMemberAttribute it seems it won't be serialized.

So beside the OP's answer:

[JsonPropertyAttribute(DefaultValueHandling = DefaultValueHandling.Include)]
public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }

This is also works:

[System.Runtime.Serialization.DataMemberAttribute()]
public decimal AmountInPounds { get { return (decimal)AmountInPence / 100; } }
9
  • Thanks for the reply. I don't think it's because of that though (I've edited my question)
    – NickL
    Commented Mar 15, 2012 at 21:05
  • Ok, then you should provide more context. What is Data what your are trying to serialize? What is the output? Because as @StriplingWarrior also pointed out: JsonConvert serializes AmountInPounds...
    – nemesv
    Commented Mar 15, 2012 at 21:07
  • Data is an object - a property of JsonResult. Would it have to be cast first?
    – NickL
    Commented Mar 15, 2012 at 21:10
  • No you don't need to cast. I think the problem is with the partial class... could you post a simplified but reproduce able code? With partials correct namespaces etc. Because it should also work with partials...
    – nemesv
    Commented Mar 15, 2012 at 21:19
  • 1
    Just realised I can't use that attribute on a readonly property like that: it needs to be [System.Runtime.Serialization.DataMemberAttribute()] public decimal AmountInPounds { get { return (decimal)AmountInPence / 100; } internal set { } } which is a bit of a hack. Can you update your answer please?
    – NickL
    Commented Mar 16, 2012 at 16:07
3

OK looks like I've found the answer, sorry for not providing more details in the post, but I don't think it mattered in the end.

I needed to add an attribute on the AmountInPounds property:

[JsonPropertyAttribute(DefaultValueHandling = DefaultValueHandling.Include)]
public decimal AmountInPounds { get { return (decimal)AmountInPence / 100;  } }
4
  • I'm glad that you've found a solution, but it's still very strange. Because I was not able to reproduce your issue not with partial classes or inheritance or with nullable properties. Newtonsoft.Json version 4.0.8 always included the readonly properties...
    – nemesv
    Commented Mar 16, 2012 at 12:15
  • Yes, I created a seperate solution replicating everything apart from the class being created by WCF service and it worked as expected. Perhaps there's an attribute on that class that prevents Json.Net from automatically serializing those readonly properties. Thanks for your time!
    – NickL
    Commented Mar 16, 2012 at 13:24
  • It seems the DataMemberAttribute also solves your problem, I don't know why maybe this is a bug in Json.net. However I've also updated my answer with this info.
    – nemesv
    Commented Mar 16, 2012 at 13:59
  • Perhaps because there were attributes on the class that the standard JavaScriptSerializer used, it wasn't needed on the property, but if Json.Net doesn't use them then that's the reason it stopped working. Anyhoo I've marked your answer as accepted
    – NickL
    Commented Mar 16, 2012 at 15:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.