Posso desserializar para um object imutável usando o JavascriptSerializer?

using System.Web.Script.Serialization.JavaScriptSerializer

posso desserializar em um object imutável de alguma forma?

  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; } } 

Restrições: Eu não quero um construtor vazio público, eu não quero mudar tudo para mutável, e eu não quero usar xml ao invés de Json.

Eu tive que encontrar uma resposta para isso, e desde que este é o primeiro resultado no google, mas não deu um exemplo, decidi compartilhar o que eu criei (com base no link fornecido por James Ellis-Jones).

Minha situação era que eu precisava de um object “Money” para ser imutável. Meu object Money precisava de uma quantia e uma moeda. Precisa ser imutável porque eu estou usando como se fosse o valor decimal que eu estou substituindo (operações matemáticas suportadas em valores de moeda corrente) e eu precisei passá-lo sem me preocupar se estou passando por referência ou uma cópia da coisa.

Então, eu implementei o JavaScriptConverter aqui:

 public class MoneyJsonConverter : JavaScriptConverter { public override object Deserialize(IDictionary 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 Serialize(object obj, JavaScriptSerializer serializer) { var moneyAmount = obj as Money; if (moneyAmount == null) return new Dictionary(); var result = new Dictionary { { "Amount", moneyAmount.Amount }, { "Currency", moneyAmount.Currency }, }; return result; } public override IEnumerable SupportedTypes { get { return new ReadOnlyCollection(new List(new[] { typeof(Money) })); } } } 

Então eu registrei o conversor com o JavaScriptSerializer através do arquivo web.config:

            

É isso aí! Eu também decorei minha class com alguns atributos, embora:

 [Serializable] [Immutable] public class Money 

JavaScriptSerializer fornece uma API de personalização, você pode criar uma class que herda de JavaScriptConverter para especificar como construir sua class Item de um dictionary de então usar o método RegisterConverters em uma instância JavaScriptSerializer para registrar seu conversor personalizado.

definição de javascriptserializer.registerconverters