Trying to create a service to return an object that has many shared properties, but one property should be highly limited in some situations. This is resulting in odd and undesired behaviour, where a property name is reused in the serialized output, resulting in incorrect behaviour in the browser. Here is an example that can be pasted into LINQPad (if you add a reference to System.Web.Extensions
) to see the problem:
void Main()
{
System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
json.Serialize(new Full(true)).Dump();
json.Serialize(new Limited()).Dump();
}
public class Full
{
public String Stuff { get { return "Common things"; } }
public FullStatus Status { get; set; }
public Full(bool includestatus)
{
if(includestatus)
Status = new FullStatus();
}
}
public class Limited : Full
{
public new LimitedStatus Status { get; set; }
public Limited() : base(false)
{
Status = new LimitedStatus();
}
}
public class FullStatus
{
public String Text { get { return "Loads and loads and loads of things"; } }
}
public class LimitedStatus
{
public String Text { get { return "A few things"; } }
}
This prints:
{"Stuff":"Common things","Status":{"Text":"Loads and loads and loads of things"}}
{"Status":{"Text":"A few things"},"Stuff":"Common things","Status":null}
When JSON.parse is called in the browser, the second Status overrides the first, meaning Status is always null.
The only way I can see of fixing this is to refactor so that FullStatus and LimitedStatus both inherit from a common parent and use override
rather that new
- bit more complicated in the real world code, but possible. Is my assumption correct? And also, I'd be interested to know if this is expected behaviour or a bug.