JsonConvert SerializeObject不包括[Serializable]类的类属性名

时间:2015-09-14 15:12:32

标签: c# asp.net json.net

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:1)

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

什么Serializable属性意味着,&#34;以下.NET类型可以通过串行化其公共和私人的字段被序列 - 不它的属性&#34。默认情况下,Json.NET会忽略此属性,但可以通过将IgnoreSerializableAttribute上的DefaultContractResolver设置为false来强制它以这种方式序列化具有此属性的类型。实际上,asp.net就是这样做的,全球范围内都能实现这种行为。因此,如果您的AbstractInfo<T>基类实际上将其数据存储在某个私有索引数组中,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>
    {
    }