UWP项目序列化RealmObject时如何忽略ObjectSchema与Realm属性
解决UWP中RealmObject序列化时忽略ObjectSchema和Realm属性的问题
我之前也碰到过这个棘手的问题!RealmObject自带的ObjectSchema和Realm属性确实会在序列化时凭空冒出来添乱,而且直接用构造函数跳过根本不好使——毕竟Realm的对象是动态生成的代理类,你写的构造逻辑很容易被覆盖掉。给你几个亲测有效的解决方案:
方案1:自定义Json.NET契约解析器(推荐用Newtonsoft.Json时)
如果你的项目用的是Newtonsoft.Json(Json.NET),可以通过自定义ContractResolver来强制忽略这两个基类属性:
public class RealmContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 检查属性名,匹配就标记为忽略 if (member.Name is "Realm" or "ObjectSchema") { property.Ignored = true; } return property; } }
使用的时候,把这个解析器传入序列化设置即可:
var serializerSettings = new JsonSerializerSettings { ContractResolver = new RealmContractResolver() }; var serializedJson = JsonConvert.SerializeObject(yourRealmObjectInstance, serializerSettings);
方案2:映射到DTO(最干净的架构方案)
直接序列化Realm实体其实不太符合分层架构的最佳实践,更稳妥的方式是创建一个和Realm对象结构一致的数据传输对象(DTO),把实体属性复制到DTO后再序列化:
// 你的Realm实体类 public class User : RealmObject { public string Username { get; set; } public DateTimeOffset CreatedAt { get; set; } } // 对应的DTO类(普通POCO) public class UserDto { public string Username { get; set; } public DateTimeOffset CreatedAt { get; set; } }
然后手动或通过工具完成映射:
// 从Realm获取实体 var user = realm.Find<User>("user-id-123"); // 映射到DTO var userDto = new UserDto { Username = user.Username, CreatedAt = user.CreatedAt }; // 序列化DTO var json = JsonConvert.SerializeObject(userDto);
如果属性很多,可以用AutoMapper这类工具自动完成映射,省掉手动复制的麻烦。
方案3:用System.Text.Json自定义转换器
如果你的项目用的是.NET自带的System.Text.Json,就需要写一个自定义转换器来过滤掉不需要的属性:
public class RealmObjectJsonConverter<T> : JsonConverter<T> where T : RealmObject { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 如果不需要反序列化Realm对象,可以直接抛出异常或返回null throw new NotImplementedException("反序列化Realm对象请直接使用Realm的API"); } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { // 先序列化所有属性,再过滤掉目标属性 var document = JsonSerializer.SerializeToDocument(value, options); using (writer.WriteObjectValue()) { foreach (var property in document.RootElement.EnumerateObject()) { if (property.Name != "Realm" && property.Name != "ObjectSchema") { property.WriteTo(writer); } } } } }
使用时把转换器添加到序列化选项中:
var options = new JsonSerializerOptions(); options.Converters.Add(new RealmObjectJsonConverter<User>()); var json = JsonSerializer.Serialize(user, options);
为什么构造函数方法没用?
Realm在创建对象实例时,会动态生成一个继承自你的RealmObject子类的代理类,这个代理类会接管很多属性的处理逻辑。你写的构造函数逻辑会被代理类覆盖,而且Realm和ObjectSchema是基类的只读属性,构造函数根本无法控制它们是否被序列化框架识别到。
内容的提问来源于stack exchange,提问作者Hamza Bouzidi
相关产品推荐
相关产品推荐

