use*_*326 32 nhibernate json.net
是否有人使用JSON.NET和nHibernate?我注意到当我尝试加载具有子集合的类时,我遇到了错误.
Ali*_*uri 42
我遇到了同样的问题,所以我尝试使用@Liedman的代码,但是GetSerializableMembers()从来没有调用代理引用.我发现了另一种覆盖方法:
public class NHibernateContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
return base.CreateContract(objectType.BaseType);
else
return base.CreateContract(objectType);
}
}
Run Code Online (Sandbox Code Playgroud)
Lie*_*man 25
我们有这个确切的问题,这是在Handcraftsman的回应中得到的解决.
问题源于JSON.NET对如何序列化NHibernate的代理类感到困惑.解决方案:将代理实例序列化为基类.
Handcraftsman代码的简化版本如下:
public class NHibernateContractResolver : DefaultContractResolver {
protected override List<MemberInfo> GetSerializableMembers(Type objectType) {
if (typeof(INHibernateProxy).IsAssignableFrom(objectType)) {
return base.GetSerializableMembers(objectType.BaseType);
} else {
return base.GetSerializableMembers(objectType);
}
}
}
Run Code Online (Sandbox Code Playgroud)
恕我直言,这段代码的优势仍然是依赖于JSON.NET关于自定义属性等的默认行为(并且代码更短!).
它像这样使用
var serializer = new JsonSerializer{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver()
};
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);
serializer.Serialize(jsonWriter, objectToSerialize);
string serializedObject = stringWriter.ToString();
Run Code Online (Sandbox Code Playgroud)
注意:此代码是为NHibernate 2.1编写并使用的.正如一些评论者指出的那样,它不能与更新版本的NHibernate一起开箱即用,你将不得不做一些调整.如果我必须使用更新版本的NHibernate,我会尝试更新代码.
Han*_*man 18
我使用NHibernate和Json.NET,并注意到我在序列化对象中得到了莫名其妙的"__interceptors"属性.谷歌搜索出现了Lee Henson的这个出色的解决方案,我适应了Json.NET 3.5 Release 5,如下所示.
public class NHibernateContractResolver : DefaultContractResolver
{
private static readonly MemberInfo[] NHibernateProxyInterfaceMembers = typeof(INHibernateProxy).GetMembers();
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var members = base.GetSerializableMembers(objectType);
members.RemoveAll(memberInfo =>
(IsMemberPartOfNHibernateProxyInterface(memberInfo)) ||
(IsMemberDynamicProxyMixin(memberInfo)) ||
(IsMemberMarkedWithIgnoreAttribute(memberInfo, objectType)) ||
(IsMemberInheritedFromProxySuperclass(memberInfo, objectType)));
var actualMemberInfos = new List<MemberInfo>();
foreach (var memberInfo in members)
{
var infos = memberInfo.DeclaringType.BaseType.GetMember(memberInfo.Name);
actualMemberInfos.Add(infos.Length == 0 ? memberInfo : infos[0]);
}
return actualMemberInfos;
}
private static bool IsMemberDynamicProxyMixin(MemberInfo memberInfo)
{
return memberInfo.Name == "__interceptors";
}
private static bool IsMemberInheritedFromProxySuperclass(MemberInfo memberInfo, Type objectType)
{
return memberInfo.DeclaringType.Assembly == typeof(INHibernateProxy).Assembly;
}
private static bool IsMemberMarkedWithIgnoreAttribute(MemberInfo memberInfo, Type objectType)
{
var infos = typeof(INHibernateProxy).IsAssignableFrom(objectType)
? objectType.BaseType.GetMember(memberInfo.Name)
: objectType.GetMember(memberInfo.Name);
return infos[0].GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length > 0;
}
private static bool IsMemberPartOfNHibernateProxyInterface(MemberInfo memberInfo)
{
return Array.Exists(NHibernateProxyInterfaceMembers, mi => memberInfo.Name == mi.Name);
}
}
Run Code Online (Sandbox Code Playgroud)
要使用它,只需在JsonSerializer的ContractResolver属性中放置一个实例.可以通过将ReferenceLoopHandling属性设置为ReferenceLoopHandling.Ignore来解决jishi指出的循环依赖问题.这是一个扩展方法,可用于使用Json.Net序列化对象
public static void SerializeToJsonFile<T>(this T itemToSerialize, string filePath)
{
using (StreamWriter streamWriter = new StreamWriter(filePath))
{
using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
{
jsonWriter.Formatting = Formatting.Indented;
JsonSerializer serializer = new JsonSerializer
{
NullValueHandling = NullValueHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NHibernateContractResolver(),
};
serializer.Serialize(jsonWriter, itemToSerialize);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您是否遇到循环依赖错误?如何忽略序列化中的对象?
由于延迟加载会生成代理对象,因此类成员拥有的任何属性都将丢失。我在使用 Newtonsoft JSON 序列化器时遇到了同样的问题,因为代理对象不再具有 [JsonIgnore] 属性。
| 归档时间: |
|
| 查看次数: |
17017 次 |
| 最近记录: |