我正在序列化我创建的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
}
}
谢谢!
答案 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"]}
因此看起来这几乎肯定是你的问题。
要解决此问题,您可以
在asp.net中全局设置IgnoreSerializableAttribute = true
。要执行此操作,请参阅ASP.NET Web API and [Serializable] class或Setting IgnoreSerializableAttribute Globally in Json.net。
使用[JsonObject(MemberSerialization = MemberSerialization.OptOut)]
标记您的课程:
[Serializable]
[JsonObject(MemberSerialization = MemberSerialization.OptOut)]
public class MediaInfo : AbstractInfo<MediaInfo>
{
}