我有一個需要格式化輸出json的十進制貨幣,與文化指定我的對象我序列化,對象可以嵌套,所以我不能預設序列化器中的選項。目前我這樣做的方式是使用格式化輸出的額外字符串屬性。NewtonSoft JsonConverter - 訪問其他屬性
[JsonIgnore]
public decimal Cost {get;set;}
[JsonIgnore]
public CultureInfo Culture {get;set;}
public string AsCurrency(decimal value) {
return string.Format(this.Culture, "{0:c}", value);
}
[JsonProperty("FormattedCost")]
public string FormatedCost {
get { return this.AsCurrency(this.Cost); }
}
我有很多的屬性來處理,我不打擾關於反序列化時,把JSONObject是使用不同的語言來填充的PDF,所以我希望字符串值。
理想情況下,我想一個JsonConverter
這樣我就可以做
[JsonProperty("FormattedCost")]
[JsonConverter(typeof(MyCurrencyConverter))]
public decimal Cost {get;set;}
我的問題是如何訪問轉換器包含對象的文化財產。
public class MyCurrencyConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var culture = // How do I get the Culture from the parent object?
writer.WriteValue(string.format(culture, "{0:c}", (decimal)value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return typeof(decimal) == objectType;
}
}
As請求示例JSON。
對於一個Contract
類別的數組,每個類都有一個Cost和一個Culture。
[{ FormattedCost : "£5000.00"}, { FormattedCost : "$8000.00"}, { FormattedCost : "€599.00"}]
實際的對象要複雜得多,嵌套Assets的多個字段會有自己的數字。另外並非所有小數都是貨幣。
我真的不想爲合約本身編寫自定義序列化程序,因爲每次屬性更改時都必須對其進行修改。
理想的解決方案是能夠使用轉換器屬性標記某些小數屬性,以便它可以處理它。
我想去的另一種方式是用十進制隱式轉換爲小數屬性創建一個自定義類,但是由於某些屬性是基於以前的結果計算的屬性,因此會變得更加複雜。
替代方法
我有一個變通爲我的使用情況,但它使用反射來獲得串行私有變量。
var binding = BindingFlags.NonPublic | BindingFlags.Instance;
var writer = serializer.GetType()
.GetMethod("GetInternalSerializer", binding)
?.Invoke(serializer, null);
var parent = writer?.GetType()
.GetField("_serializeStack", binding)
?.GetValue(writer) is List<object> stack
&& stack.Count > 1 ? stack[stack.Count - 2] as MyType: null;
在我測試的用例中,這給了我父對象,但它沒有使用公共API。
您是否試過編寫'MyCurrencyConverter'? (PS你的第一個代碼塊不編譯) – DavidG
@DavidG是的,但問題是在writeJson裏面我無法弄清楚如何訪問父對象和它的屬性。 –
給我們你迄今爲止的,然後我們可以提供幫助。 – DavidG