2012-06-05 65 views
2

使用Newtonsoft.Json庫,想象我有適當的Json.net System.Object往返?

public class Test 
{ 
    public Object Obj { get; set; } 
} 

現在,試圖序列這種像這樣

var json = JsonConvert.SerializeObject(new Test(){ Obj = new Uri(@"http://www.google.com") }); 

...會給我下面的JSON

{ 
    "Obj": "http://www.google.com" 
} 

這顯然沒有足夠的信息反序列化成Uri對象,事實上,嘗試反序列化它會給我一個String對象。

是否有任何現有的方法來正確序列化和反序列化這裏的類型信息,以便該對象將作爲Uri而不是字符串讀回?在這種特殊情況下,我只是試圖與.NET應用程序進行交互,並且確切類型被反序列化是非常重要的。

在此先感謝。

回答

2

如果你想將字符串轉換回開放的,你可以使用自定義轉換器屬性

轉換器

public class UriConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.String) 
     { 
      //try to create uri out of the string 
      Uri uri; 
      if(Uri.TryCreate(reader.Value.ToString(), UriKind.Absolute, out uri)) 
      { 
       return uri; 
      } 
      //just a string -> return string value 
      return reader.Value; 
     } 

     if (reader.TokenType == JsonToken.Null) 
     { 
      return null; 
     } 

     throw new InvalidOperationException("Unable to process JSON"); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (null == value) 
     { 
      writer.WriteNull(); 
      return; 
     } 

     if (value is Uri) 
     { 
      writer.WriteValue(((Uri)value).OriginalString); 
      return; 
     } 

     throw new InvalidOperationException("Unable to process JSON"); 
    } 
} 

而且使用屬性

[JsonConverter(typeof(UriConverter))] 
public object Obj {get;set;} 

您應該然後是能夠確定底層對象是否是Uri類似

var data = JsonConvert.DeserializeObject<YourObject>(yourJSONString); 
    if (data.Obj is Uri) 
    { 
     ... add logic here 
    } 
    else 
    { 
     ... not Uri different logic 
    } 

您還可以看看本文的詳細信息Json.NET Uri (de)serialization errors

+0

謝謝。如果System.Object始終是Uri,這確實可以解決問題,但不幸的是它不是(否則我只需更改類聲明中的類型)。 – Devknoll

+0

+1真棒,我已經使用了JSON.NET多年,並不知道它是這樣複雜的東西! – Andomar

+0

您應該能夠重寫轉換器以處理您的方案,確定該字符串是否是Uri並將其作爲Uri返回。我將爲你的場景重寫轉換器 – workoholic

1

JSON只知道JavaScript數據類型:字符串,數字和布爾值。一個URL不在列表中。

事實上,JSON的整個POINT是允許鬆散類型的傳輸。如果你想強類型傳輸,請檢查一個更強的傳輸協議,如WCF二進制序列化。

+0

雖然我一般你同意關於JSON的意圖,讓鬆散類型轉移,Json.net有關於.NET類型(靈活性通過特殊的$ type屬性和TypeNameHandling設置)。它只是發生在特殊情況下一個Uri到一個字符串... 無論如何,謝謝你,我會考慮WCF二進制序列化。 – Devknoll