2010-08-31 127 views
3

我需要確定是否DataContractJsonSerializer可以將JSON反序列化爲字典,如果該字典不是被反序列化的包裝對象。我知道還有其他的開源代碼項目可以做到這一點(json.net,json-framework),但我想知道,如果.NET可以在採取這種方法之前本身處理這個。所有MSDN documentation表明它可以但我不確定是否正確處理轉換。反序列化JSON與嵌入字典<字符串,字符串>

所以開始我是從這樣的JSON Web服務接收視頻對象:

{"videos": 
[{ 
    "id":000000000000, 
    "name":"Video Title", 
    "adKeys":null, 
    "shortDescription":"short description", 
    "longDescription":"long description", 
    "creationDate":"1282819270274", 
    "publishedDate":"1282819270274", 
    "lastModifiedDate":"1282857505013", 
    "linkURL":null, 
    "linkText":null, 
    "tags":["tag1","tag2","tag3","tag4","tag5","tag5"], 
    "videoStillURL":"", 
    "thumbnailURL":"", 
    "referenceId":"0000", 
    "length":177679, 
    "economics":"AD_SUPPORTED", 
    "playsTotal":178, 
    "playsTrailingWeek":178, 
    "customFields":{"custom title":"custom value", "custom title 2":"custom value2"}, 
    "FLVURL":"", 
    "renditions":[] 
}], 
"page_number":0, 
"page_size":0, 
"total_count":1} 

我這個反序列化對象作爲BCQueryResult。 BCQueryResult有一個名爲Videos的屬性,它是一個擴展List並應用CollectionDataContract的BCCollection。該視頻對象又具有名爲customFields的屬性,該屬性是CustomFields對象,它擴展了Dictionary並應用了CollectionDataContract。列表類型(視頻,標籤,提示點等)的所有集合類型都是反序列化的,沒有問題。 Dictionary類型是唯一具有反序列化問題的類型。沒有錯誤,但即使存在值,結果也是空的。如果我刪除所有日期類型並使用JavaScriptSerializer反序列化,它會給我適當的值,但由於所需字段類型的問題,我不能使用JavaScriptSerializer,而是使用DataContractJsonSerializer。我附上了下面的課程。

BCQueryResult:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.Serialization; 
using BrightcoveSDK.Media; 

namespace BrightcoveSDK 
{ 
[DataContract] 
public class BCQueryResult 
{ 
    [DataMember(Name = "videos")] 
    public BCCollection<BCVideo> Videos; 
    [DataMember(Name = "playlists")] 
    public BCCollection<BCPlaylist> Playlists; 
    [DataMember(Name = "page_number")] 
    public int PageNumber { get; set; } 
    [DataMember(Name = "page_size")] 
    public int PageSize { get; set; } 
    [DataMember(Name = "total_count")] 
    public int TotalCount { get; set; } 

    public int MaxToGet = 0; 
    public List<QueryResultPair> QueryResults = new List<QueryResultPair>(); 

    public BCQueryResult() { 
    Playlists = new BCCollection<BCPlaylist>(); 
    Videos = new BCCollection<BCVideo>(); 
    PageNumber = 0; 
    PageSize = 0; 
    TotalCount = 0; 
    } 

    public void Merge(BCQueryResult qr) { 

    //if (qr.QueryResults != null && qr.QueryResults.Count > 0) 
    //  QueryResults.Add(qr.QueryResults[qr.QueryResults.Count -1]); 
    if (qr.Videos != null) Videos.AddRange(qr.Videos); 
    if(qr.Playlists != null) Playlists.AddRange(qr.Playlists); 
    PageNumber = qr.PageNumber; 
    TotalCount = qr.TotalCount; 
    PageSize = qr.PageSize; 
    } 
} 
} 

BCCollection:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.Serialization; 

namespace BrightcoveSDK 
{ 
[CollectionDataContract] 
public class BCCollection<T> : List<T> 
{} 

public static class BCCollectionExtensions { 

    public static string ToDelimitedString(this BCCollection<string> list, string Delimiter) { 

    string r = ""; 
    foreach (string s in list) { 
    if (r.Length > 0) { 
    r += Delimiter; 
    } 
    r += s; 
    } 
    return r; 
    } 
} 
} 

BCVideo:

using System; 
using System.Collections.Generic; 
using System.Net; 
using System.Text; 
using System.Web; 
using System.Runtime.Serialization; 

namespace BrightcoveSDK.Media 
{ 
/// <summary> 
/// The Video object is an aggregation of metadata and asset information associated with a video 
/// </summary> 
[DataContract] 
public class BCVideo : BCObject, IComparable<BCVideo> 
{ 
    /// <summary> 
    /// A number that uniquely identifies this Video, assigned by Brightcove when the Video is created. 
    /// </summary> 
    [DataMember] 
    public long id { get; set; } 

    /// <summary> 
    /// The title of this Video. 
    /// </summary> 
    [DataMember] 
    public string name { get; set; } 

    /// <summary> 
    /// A short description describing this Video, limited to 256 characters. 
    /// </summary> 
    [DataMember] 
    public string shortDescription { get; set; } 

    /// <summary> 
    /// A longer description of this Video, bounded by a 1024 character limit. 
    /// </summary> 
    [DataMember] 
    public string longDescription { get; set; } 

    [DataMember(Name = "creationDate")] 
    private string createDate { get; set; } 

    /// <summary> 
    /// The date this Video was created, represented as the number of milliseconds since the Unix epoch. 
    /// </summary> 
    public DateTime creationDate { 
    get { 
    return DateFromUnix(createDate); 
    } 
    set { 
    createDate = DateToUnix(value); 
    } 
    } 

    [DataMember(Name = "publishedDate")] 
    private string publishDate { get; set; } 

    /// <summary> 
    /// The date this Video was last made active, represented as the number of milliseconds since the Unix epoch. 
    /// </summary> 
    public DateTime publishedDate { 
    get { 
    return DateFromUnix(publishDate); 
    } 
    set { 
    publishDate = DateToUnix(value); 
    } 
    } 

    [DataMember(Name = "lastModifiedDate")] 
    private string modifyDate { get; set; } 

    /// <summary> 
    /// The date this Video was last modified, represented as the number of milliseconds since the Unix epoch. 
    /// </summary> 
    public DateTime lastModifiedDate { 
    get { 
    return DateFromUnix(modifyDate); 
    } 
    set { 
    modifyDate = DateToUnix(value); 
    } 
    } 

    /// <summary> 
    /// An optional URL to a related item. 
    /// </summary> 
    [DataMember] 
    public string linkURL { get; set; } 

    /// <summary> 
    /// The text displayed for the linkURL. 
    /// </summary> 
    [DataMember] 
    public string linkText { get; set; } 

    [DataMember(Name = "FLVURL")] 
    public string flvURL { get; set; } 

     private BCCollection<string> _tags; 

    /// <summary> 
    /// A list of Strings representing the tags assigned to this Video. 
    /// </summary> 
     [DataMember] 
     public BCCollection<string> tags { 
      get { 
       if (_tags == null) { 
        _tags = new BCCollection<string>(); 
       } 
       return _tags; 
      } 
      set { 
       _tags = value; 
      } 
     } 

     private BCCollection<BCCuePoint> _cuePoints; 

     /// <summary> 
     /// A list of cuePoints representing the cue points assigned to this Video. 
     /// </summary> 
     [DataMember] 
     public BCCollection<BCCuePoint> cuePoints { 
      get { 
       if(_cuePoints == null){ 
        _cuePoints = new BCCollection<BCCuePoint>(); 
       } 
       return _cuePoints; 
      } 
      set { 
       _cuePoints = value; 
      } 
     } 

    /// <summary> 
    /// The URL to the video still image associated with this Video. Video stills are 480x360 pixels. 
    /// </summary> 
    [DataMember] 
    public string videoStillURL { get; set; } 

    /// <summary> 
    /// The URL to the thumbnail image associated with this Video. Thumbnails are 120x90 pixels. 
    /// </summary> 
    [DataMember] 
    public string thumbnailURL { get; set; } 

    /// <summary> 
    /// A user-specified id that uniquely identifies this Video. ReferenceID can be used as a foreign-key to identify this video in another system. 
    /// </summary> 
    [DataMember] 
    public string referenceId { get; set; } 

    /// <summary> 
    /// The length of this video in milliseconds. 
    /// </summary> 
    [DataMember] 
    public string length { get; set; } 

    [DataMember(Name = "economics")] 
    private string ecs { get; set; } 

    /// <summary> 
    /// Either FREE or AD_SUPPORTED. AD_SUPPORTED means that ad requests are enabled for this Video. 
    /// </summary> 
    public BCVideoEconomics economics { 
    get { 
    if (ecs == null) { 
    return BCVideoEconomics.AD_SUPPORTED; 
    } 
    else if (ecs.Equals(BCVideoEconomics.AD_SUPPORTED.ToString())) { 
    return BCVideoEconomics.AD_SUPPORTED; 
    } 
    else if (ecs.Equals(BCVideoEconomics.FREE.ToString())) { 
    return BCVideoEconomics.FREE; 
    } 
    else { 
    return BCVideoEconomics.AD_SUPPORTED; 
    } 
    } 
    set { 
    ecs = value.ToString(); 
    } 
    } 

    [DataMember(Name = "playsTotal")] 
    private string plays { get; set; } 

    /// <summary> 
    /// How many times this Video has been played since its creation. 
    /// </summary> 
    public long playsTotal { 
    get { 
    if (!String.IsNullOrEmpty(plays)) { 
    return long.Parse(plays); 
    } else { 
    return 0; 
    } 
    } 
    set { 
    plays = value.ToString(); 
    } 
    } 

    [DataMember(Name = "playsTrailingWeek")] 
    private string playsWeek { get; set; } 

     public static List<string> VideoFields { 
      get { 
       List<string> fields = new List<string>(); 
       foreach (string s in Enum.GetNames(typeof(BrightcoveSDK.VideoFields))) { 
        fields.Add(s); 
       } 
       return fields; 
      } 
     } 

    /// <summary> 
    /// How many times this Video has been played within the past seven days, exclusive of today. 
    /// </summary> 
    public long playsTrailingWeek { 
    get { 
    if(!String.IsNullOrEmpty(playsWeek)) { 
    return long.Parse(playsWeek); 
    } else { 
    return 0; 
    } 
    } 
    set { 
    playsWeek = value.ToString(); 
    } 
    } 

     [DataMember(Name = "itemState")] 
     private string _itemState {get; set;} 

     public ItemStateEnum itemState { 
      get { 
    if (_itemState == null) { 
    return ItemStateEnum.ACTIVE; 
    } 
    else if (_itemState.Equals(ItemStateEnum.ACTIVE.ToString())) { 
    return ItemStateEnum.ACTIVE; 
    } 
    else if (_itemState.Equals(ItemStateEnum.DELETED.ToString())) { 
    return ItemStateEnum.DELETED; 
    } 
       else if (_itemState.Equals(ItemStateEnum.INACTIVE.ToString())) { 
    return ItemStateEnum.INACTIVE; 
    } 
    else { 
    return ItemStateEnum.ACTIVE; 
    } 
    } 
    set { 
    ecs = value.ToString(); 
    } 
     } 

     [DataMember(Name = "version")] 
     private string _version {get; set;} 

     public long version { 
     get { 
    if (!String.IsNullOrEmpty(_version)) { 
    return long.Parse(_version); 
    } else { 
    return 0; 
    } 
    } 
    set { 
    _version = value.ToString(); 
    } 
     } 

     [DataMember] 
     public string submissionInfo {get; set;} 

     public CustomFields _customFields; 

     [DataMember] 
     public CustomFields customFields { 
      get { 
       if (_customFields == null) { 
        _customFields = new CustomFields(); 
       } 
       return _customFields; 
      } 
      set { 
       _customFields = value; 
      } 
     } 

     [DataMember] 
     public string releaseDate {get; set;} 

     [DataMember] 
     public string geoFiltered {get; set;} 

     [DataMember] 
     public string geoRestricted {get; set;} 

     [DataMember] 
     public string geoFilterExclude {get; set;} 

     [DataMember] 
     public string excludeListedCountries {get; set;} 

     private BCCollection<string> _geoFilteredCountries; 

     [DataMember] 
     public BCCollection<string> geoFilteredCountries { 
      get { 
       if (_geoFilteredCountries == null) { 
        _geoFilteredCountries = new BCCollection<string>(); 
       } 
       return _geoFilteredCountries; 
      } 
      set { 
       _geoFilteredCountries = value; 
      } 
     } 

     private BCCollection<string> _allowedCountries; 

     [DataMember] 
     public BCCollection<string> allowedCountries { 
      get { 
       if (_allowedCountries == null) { 
        _allowedCountries = new BCCollection<string>(); 
       } 
       return _allowedCountries; 
      } 
      set { 
       _allowedCountries = value; 
      } 
     } 

     [DataMember(Name = "accountId")] 
     private string _accountId {get; set;} 

     public long accountId { 
     get { 
    if (!String.IsNullOrEmpty(_accountId)) { 
    return long.Parse(_accountId); 
    } else { 
    return 0; 
    } 
    } 
    set { 
    _accountId = value.ToString(); 
    } 
     } 

    public BCVideo() { 
    } 

    #region IComparable Comparators 

    public int CompareTo(BCVideo other) { 
    return name.CompareTo(other.name); 
    } 

    //CREATION_DATE 
    public static Comparison<BCVideo> CreationDateComparison = 
    delegate(BCVideo v1, BCVideo v2) 
    { 
    return v1.creationDate.CompareTo(v2.creationDate); 
    }; 

    //PLAYS_TOTAL 
    public static Comparison<BCVideo> TotalPlaysComparison = 
    delegate(BCVideo v1, BCVideo v2) 
    { 
    return v1.playsTotal.CompareTo(v2.playsTotal); 
    }; 

    //PUBLISH_DATE 
    public static Comparison<BCVideo> PublishDateComparison = 
    delegate(BCVideo v1, BCVideo v2) 
    { 
    return v1.publishedDate.CompareTo(v2.publishedDate); 
    }; 

    //MODIFIED_DATE 
    public static Comparison<BCVideo> ModifiedDateComparison = 
    delegate(BCVideo v1, BCVideo v2) 
    { 
    return v1.lastModifiedDate.CompareTo(v2.lastModifiedDate); 
    }; 

    //PLAYS_TRAILING_WEEK 
    public static Comparison<BCVideo> PlaysTrailingComparison = 
    delegate(BCVideo v1, BCVideo v2) 
    { 
    return v1.playsTrailingWeek.CompareTo(v2.playsTrailingWeek); 
    }; 

    #endregion 
} 

public static class BCVideoExtensions { 

    #region Extension Methods 

    public static string ToCreateJSON(this BCVideo video) { 
    return ToJSON(video, JSONType.Create); 
    } 

    public static string ToJSON(this BCVideo video) { 
    return ToJSON(video, JSONType.Update); 
    } 

     private static string ToJSON(this BCVideo video, JSONType type) { 

    //--Build Video in JSON -------------------------------------// 

      StringBuilder jsonVideo = new StringBuilder(); 
      jsonVideo.Append("{"); 

    if(type.Equals(JSONType.Update)){ 
    //id 
    jsonVideo.Append("\"id\": " + video.id.ToString() + ","); 
    } 

    //name 
    if (!string.IsNullOrEmpty(video.name)) { 
    jsonVideo.Append("\"name\": \"" + video.name + "\""); 
    } 

    //shortDescription 
    if (!string.IsNullOrEmpty(video.shortDescription)) { 
    jsonVideo.Append(",\"shortDescription\": \"" + video.shortDescription + "\""); 
    } 

    //Tags should be a list of strings 
    if (video.tags.Count > 0) { 
    jsonVideo.Append(",\"tags\": ["); 
    string append = ""; 
    foreach (string tag in video.tags) { 
    jsonVideo.Append(append + "\"" + tag + "\""); 
    append = ","; 
    } 
    jsonVideo.Append("]"); 
    } 

    //referenceId 
    if (!string.IsNullOrEmpty(video.referenceId)) { 
    jsonVideo.Append(",\"referenceId\": \"" + video.referenceId + "\""); 
    } 

    //longDescription 
    if (!string.IsNullOrEmpty(video.longDescription)) { 
    jsonVideo.Append(",\"longDescription\": \"" + video.longDescription + "\""); 
    } 

      if (video.cuePoints.Count > 0) { 
       jsonVideo.Append(",\"cuePoints\": " + video.cuePoints.ToJSON()); 
      } 

    //economics 
    jsonVideo.Append(",\"economics\": " + video.economics.ToString()); 

    jsonVideo.Append("}"); 

    return jsonVideo.ToString(); 
    } 

    #endregion 
} 
} 

CustomFields:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.Serialization; 

namespace BrightcoveSDK 
{ 
    [CollectionDataContract] 
    public class CustomFields : Dictionary<string, string> 
    { } 
} 

回答

1

JSON詞典都沒有反序列化字典,而是作爲KeyValuePair<T,U>

更改您的數據成員類型KeyValuePair<string, string>[]

+0

看起來問題是,返回的customFields對象不適合.NET的Dictionary或KeyValuePair的定義。它將其視爲具有稱爲「自定義標題」和「自定義標題2」的屬性的對象。要作爲KeyValuePair進行反序列化,結構需要如下所示:{「key」:「some key」,「value」:「some value」}。謝謝你的幫助。 – 2010-09-22 13:12:53

1

CollectionDataContract屬性的陣列可用於指定序列化到JSON「字典」合同,即鍵值對對象的數組。一個示例看起來像這樣:

using System; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 

namespace DictionarySample 
{ 
    [CollectionDataContract(Name = "dict", ItemName = "key", KeyName = "key", ValueName = "value")] 
    public class DictContract : Dictionary<string, string> 
    { 
     public DictContract() { } 
     public DictContract(SerializationInfo info, StreamingContext context : base(info, context) { } 
    } 
} 
+0

'ItemName','KeyName'和'ValueName'似乎不被尊重。我仍然得到默認的「關鍵」和「價值」。 – crush 2015-03-20 13:42:30

+0

讓我添加到我的最後一條評論,當我訪問服務生成的幫助頁面時,它顯示自定義設置KeyName和ValueName,但實際上從我的WCF服務接收的JSON使用的是「Key」和「Value」,它是不是我設定的。 – crush 2015-03-20 13:50:01

+0

哇,從過去的爆炸!我似乎記得這個工作,但五年後誰可以說。我從2011年起就沒有使用過WCF,所以很遺憾我沒有太大的幫助。 – Ben 2015-03-20 18:12:48

相關問題