.net - 使用嵌入式字典反序​​列化 JSON<string, string>

标签 .net json serialization

如果 Dictionary 不是被反序列化的包装对象,我需要确定 DataContractJsonSerializer 是否可以将 JSON 反序列化为 Dictionary。我知道还有其他开源代码项目可能能够做到这一点(json.net、json-framework),但我想在采用这种方法之前明确地知道 .NET 是否可以在 native 处理这个问题。所有MSDN documentation建议可以,但我不确定我是否正确处理了转换。

首先,我从 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 的属性,它是一个 BCCollection,它扩展了 List 并应用了 CollectionDataContract。视频对象又具有一个名为 customFields 的属性,它是一个扩展 Dictionary 并应用 CollectionDataContract 的 CustomFields 对象。所有列表类型的集合类型(视频、标签、提示点等)都可以毫无问题地反序列化。 Dictionary 类型是唯一存在反序列化问题的类型。没有错误,但即使存在值,结果也为空。如果我去掉所有日期类型并使用 JavaScriptSerializer 反序列化,它会给我正确的值,但由于必填字段类型的问题,我无法使用 JavaScriptSerializer,而是使用 DataContractJsonSerializer。我附上了下面的类(class)。

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

BC视频:

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

自定义字段:

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

最佳答案

JSON 字典不会反序列化为字典,而是作为 KeyValuePair<T,U> 的数组

将您的数据成员类型更改为 KeyValuePair<string, string>[]

关于.net - 使用嵌入式字典反序​​列化 JSON<string, string>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3610785/

相关文章:

c# - 如何在不重置堆栈跟踪的情况下抛出异常?

php - 通过相关实体正确递归

c# - 具有继承类型的列表的序列化

java - 数据传输中反序列化后不是同一个对象

python - IronPython.dll - 使用哪一个?

java - .Net 4 垃圾收集

c# - Visual Studio 2010 不断改变我的 winforms 控件

json - 为两个几乎相同的实例定义一个 JSON 模式

json - SWIFT 2 : Loop through JSON array

serialization - boost::serialization 序列化过程中内存消耗高