using System.Web.Script.Serialization.JavaScriptSerializer
can I deserialize into an immutable object somehow?
public class Item
{
public Uri ImageUri { get;private set; }
public string Name { get; private set; }
public Uri ItemPage { get;private set; }
public decimal Retail { get;private set; }
public int? Stock { get; private set; }
public decimal Price { get; private set; }
public Item(Uri imageUri, string name, Uri itemPage, decimal retail, int? stock, decimal price)
{
ImageUri = imageUri;
Name = name;
ItemPage = itemPage;
Retail = retail;
Stock = stock;
Price = price;
}
}
Constraints: I don't want a public empty constructor, I don't want to change everything to mutable, and I don't want to use xml instead of Json.
I had to find an answer for this, and since this is the first result on google, but it didn't give an example, I decided to share what I came up with (based upon the link provided by James Ellis-Jones.)
My situation was I needed a "Money" object to be immutable. My Money object needed an amount and a currency. Needs to be immutable because I'm using it as if it were the decimal value I'm replacing it with (math operations supported on like-currency values) and I needed to pass it around without worrying about whether I'm passing by reference or a copy of the thing.
So, I implemented the JavaScriptConverter here:
public class MoneyJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (type != typeof(Money))
return null;
var amount = Convert.ToDecimal(dictionary.TryGet("Amount"));
var currency = (string)dictionary.TryGet("Currency");
return new Money(currency, amount);
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var moneyAmount = obj as Money;
if (moneyAmount == null)
return new Dictionary<string, object>();
var result = new Dictionary<string, object>
{
{ "Amount", moneyAmount.Amount },
{ "Currency", moneyAmount.Currency },
};
return result;
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(Money) })); }
}
}
Then I registered the converter with the JavaScriptSerializer via the web.config file:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="MoneyConverter" type="My.Namespace.MoneyJsonConverter, MyAssembly, Version=1.0.0.0, Culture=neutral"/>
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
That's it! I did also decorate my class with a couple attributes, though:
[Serializable]
[Immutable]
public class Money
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With