我正在序列化我创建的MediaInfo类的对象列表。当输出时,我以:
结束Object:
ClassName: "WVO.Media",
Data: Array():
0:9
1: null
...
5: "A3000"
...
8: "Oakland
... etc...
简而言之,我得到类属性作为一个整数键数组,而不是与属性名称。序列化代码非常直接。首先加载列表(list mediaInfos),然后调用:
JsonConvert.SerializeObject(mediaInfos);
I can Response。这样写:
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
}
}
谢谢!
您没有显示基类AbstractInfo<MediaInfo>
,但我注意到您已将类标记为[Serializable]
。这使我可以猜测你的问题是什么。
Serializable
属性的意思是,"以下。net类型可以通过序列化其公共和私有字段而不是其属性来序列化。"默认为Json。NET忽略此属性,但是可以通过将DefaultContractResolver
上的IgnoreSerializableAttribute
设置为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和[Serializable]类或在Json.net中全局设置IgnoreSerializableAttribute用
标记你的类[JsonObject(MemberSerialization = MemberSerialization.OptOut)]
:[Serializable] [JsonObject(MemberSerialization = MemberSerialization.OptOut)] public class MediaInfo : AbstractInfo<MediaInfo> { }