2015-09-14 95 views
1

我正在序列化我創建的MediaInfo類的對象列表。當這出來,我結束了:JsonConvert SerializeObject不包含[Serializable]類的類屬性名稱

Object: 
    ClassName: "WVO.Media", 
    Data: Array(): 
     0:9 
     1: null 
     ... 
     5: "A3000" 
     ... 
     8: "Oakland 
     ... etc... 

總之,我得到的類屬性整數鍵控數組而不是屬性名稱。序列化代碼非常簡單。首先,我加載表(表mediaInfos),然後調用:

JsonConvert.SerializeObject(mediaInfos); 

我可以RESPONSE.WRITE之類的東西:

Response.Write(mediaInfos[0].MediaTown); 

...並得到正確的輸出,但我很困惑,爲什麼這些屬性名稱不包含在JSon輸出中。我錯過了什麼?

編輯:

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

using CMS; 
using CMS.DataEngine; 
using CMS.Helpers; 
using WVO; 

[assembly: RegisterObjectType(typeof(MediaInfo), MediaInfo.OBJECT_TYPE)] 

namespace WVO 
{ 
    [Serializable] 
    public class MediaInfo : AbstractInfo<MediaInfo> 
    { 
     #region "Type information" 
     public const string OBJECT_TYPE = "wvo.media"; 

     public static ObjectTypeInfo TYPEINFO = new ObjectTypeInfo(typeof(MediaInfoProvider), OBJECT_TYPE, "WVO.Media", "MediaID", null, null, null, null, null, null, null, null) 
     { 
      ModuleName = "wvo", 
      TouchCacheDependencies = true, 
      DependsOn = new List<ObjectDependency>() 
      { 
       new ObjectDependency("MediaMarketID", "wvo.mediamarket", ObjectDependencyEnum.NotRequired), 
       new ObjectDependency("MediaStateID", "cms.state", ObjectDependencyEnum.NotRequired), 
       new ObjectDependency("MediaTypeID", "wvo.mediatype", ObjectDependencyEnum.NotRequired), 
       new ObjectDependency("MediaSizeID", "wvo.mediasize", ObjectDependencyEnum.NotRequired), 
      }, 
     }; 

     #endregion 

     #region "Properties" 
     [DatabaseField] 
     public virtual int MediaID 
     { 
      get 
      { 
       return ValidationHelper.GetInteger(GetValue("MediaID"), 0); 
      } 
      set 
      { 
       SetValue("MediaID", value); 
      } 
     } 

     [DatabaseField] 
     public virtual string MediaPanel 
     { 
      get 
      { 
       return ValidationHelper.GetString(GetValue("MediaPanel"), String.Empty); 
      } 
      set 
      { 
       SetValue("MediaPanel", value, String.Empty); 
      } 
     } 

     [DatabaseField] 
     public virtual string MediaTown 
     { 
      get 
      { 
       return ValidationHelper.GetString(GetValue("MediaTown"), String.Empty); 
      } 
      set 
      { 
       SetValue("MediaTown", value, String.Empty); 
      } 
     } 

     ... [several other properties similarly formatted] ... 

     #endregion 

     #region "Type based properties and methods" 
     protected override void DeleteObject() 
     { 
      MediaInfoProvider.DeleteMediaInfo(this); 
     } 
     protected override void SetObject() 
     { 
      MediaInfoProvider.SetMediaInfo(this); 
     } 
     #endregion 

     #region "Constructors" 
     public MediaInfo(SerializationInfo info, StreamingContext context) 
      : base(info, context, TYPEINFO) 
     { 
     } 

     public MediaInfo() 
      : base(TYPEINFO) 
     { 
     } 

     public MediaInfo(DataRow dr) 
      : base(TYPEINFO, dr) 
     { 
     } 
     #endregion 
    } 
} 

謝謝!

+0

你能告訴我們什麼是'ObjectTypeInfo'樣子? – vendettamit

回答

1

您沒有顯示基類AbstractInfo<MediaInfo>,但我注意到您已將您的班級標記爲[Serializable]。這使我可以猜測你的問題是什麼。

Serializable屬性的含義是,「以下.Net類型可以通過序列化其公有和專用字段 - 而不是其屬性。」。默認情況下,Json.NET忽略這個屬性,但是可以通過將IgnoreSerializableAttribute設置爲DefaultContractResolverfalse來強制它以這種方式序列化具有此屬性的類型。事實上,asp.net正是這樣做的,全球啓用了這種行爲。因此,如果您的基類實際上將其數據存儲在某個專用索引數組中,那麼Json.NET將輸出該專用數組而不是公共屬性。

現在讓我們試着用最小的例子重現問題。考慮下面的類:

[Serializable] 
public abstract class AbstractInfo<T> 
{ 
    object[] Data; 

    protected AbstractInfo(int tableSize) 
    { 
     Data = new object[tableSize]; 
    } 

    protected object GetValue(int index) 
    { 
     return Data[index]; 
    } 

    protected void SetValue(int index, object value) 
    { 
     Data[index] = value; 
    } 
} 

[Serializable] 
public class MediaInfo : AbstractInfo<MediaInfo> 
{ 
    public MediaInfo() : base(1) { } 

    public virtual string MediaPanel 
    { 
     get 
     { 
      return (string)GetValue(0) ?? string.Empty; 
     } 
     set 
     { 
      SetValue(0, value == "" ? null : value); 
     } 
    } 
} 

如果我這個序列到JSON的Data陣列出現而不是屬性:

 var test = new MediaInfo { MediaPanel = "panel" }; 
     var settings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver { IgnoreSerializableAttribute = false } }; 
     var json = JsonConvert.SerializeObject(test, settings); 
     Console.WriteLine(json); 
     // Prints {"Data":["panel"]} 

如此看來,這是幾乎可以肯定你的問題。

要解決這個問題,你可以

  1. IgnoreSerializableAttribute = true全球在asp.net。要執行此操作,請參見ASP.NET Web API and [Serializable] classSetting IgnoreSerializableAttribute Globally in Json.net

  2. 標記您的類[JsonObject(MemberSerialization = MemberSerialization.OptOut)]

    [Serializable] 
    [JsonObject(MemberSerialization = MemberSerialization.OptOut)] 
    public class MediaInfo : AbstractInfo<MediaInfo> 
    { 
    }