使用System.Web.Script.Serialization.JavaScriptSerializer
我可以以某种方式反序列化为不可变对象吗?
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;
}
}
约束:我不想要一个公共的空构造函数,我不想将所有内容都改为mutable,我不想使用xml代替Json。
答案 0 :(得分:7)
我必须找到答案,因为这是谷歌的第一个结果,但它没有给出一个例子,我决定分享我想出的东西(根据James Ellis提供的链接 - 琼斯。)
我的情况是我需要一个“Money”对象是不可变的。我的Money对象需要金额和货币。需要是不可变的,因为我正在使用它,好像它是十进制值我正在替换它(数字运算支持的数学运算)我需要传递它而不用担心我是否通过引用传递或该东西的副本。
所以,我在这里实现了JavaScriptConverter:
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) })); }
}
}
然后我通过web.config文件在JavaScriptSerializer中注册了转换器:
<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>
就是这样!不过,我也用几个属性来装饰我的班级:
[Serializable]
[Immutable]
public class Money
答案 1 :(得分:0)
JavaScriptSerializer提供了一个自定义API,您可以创建一个继承自JavaScriptConverter的类,以指定如何从字典构建Item类,然后使用JavaScriptSerializer实例上的RegisterConverters方法注册自定义转换器。