【问题标题】:JsonConvert SerializeObject not including class property names for a [Serializable] classJsonConvert SerializeObject 不包括 [Serializable] 类的类属性名称
【发布时间】:2015-12-10 15:47:42
【问题描述】:

我正在序列化我创建的 MediaInfo 类的对象列表。当它出现时,我最终得到:

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

简而言之,我将类属性作为一个整数键控数组而不是属性名称。序列化代码非常简单。首先我加载列表(List 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
    }
}

谢谢!

【问题讨论】:

  • 你能告诉我们ObjectTypeInfo的样子吗?

标签: c# asp.net json.net


【解决方案1】:

您没有显示基类AbstractInfo&lt;MediaInfo&gt;,但我注意到您已将您的类标记为[Serializable]。这让我可以猜测你的问题是什么。

Serializable 属性的意思是,“以下 .Net 类型可以通过序列化它的公共和私有 字段 来序列化——而不是它的属性。”默认情况下,Json.NET 忽略此属性,但是可以通过将 DefaultContractResolver 上的 IgnoreSerializableAttribute 设置为 false 来强制它以这种方式序列化具有此属性的类型。事实上,asp.net 就是这样做的,全局启用了这种行为。因此,如果您的 AbstractInfo&lt;T&gt; 基类实际上将其数据存储在某个私有索引数组中,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. 在 asp.net 中全局设置 IgnoreSerializableAttribute = true。为此,请参阅 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>
    {
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多