You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨应用序列化异常:控制台无法反序列化PerfisDeAcesso数组属性

解决跨应用反序列化数组属性的报错问题

这个问题我之前在做跨应用数据同步的时候也碰到过!核心原因要么是领域类的程序集标识不一致,要么是序列化/反序列化的配置不统一,给你几个针对性的解决思路:

一、最推荐:把领域模型抽成共享类库

你现在网站和控制台里的Comunicado、PerfilDeAcesso是各自实现的,哪怕代码完全一样,它们在CLR里也是两个不同的类型(因为属于不同的程序集)。序列化的时候会把类型的程序集信息写入到数据里,控制台反序列化时找不到对应程序集的类型,就会报这个错。

解决办法很简单:

  • 新建一个类库项目(比如叫YourProject.Domain),把所有领域类(包括Comunicado、PerfilDeAcesso)移到这个类库里
  • 网站和控制台项目都引用这个类库

这样两个应用里使用的是同一个程序集的同一种类型,序列化和反序列化时类型标识完全匹配,从根源上解决问题,还能避免重复代码。

二、临时方案:调整序列化配置忽略程序集信息

如果暂时没法重构到共享类库,可以修改序列化器的配置,让它不写入程序集信息,或者反序列化时忽略程序集差异。

如果你用的是Newtonsoft.Json:

网站端(序列化时):

var jsonSettings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None, // 不写入类型的程序集信息
    Formatting = Formatting.Indented
};
string serializedData = JsonConvert.SerializeObject(yourComunicadoInstance, jsonSettings);

控制台端(反序列化时):

var jsonSettings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None,
    // 如果还是有问题,用自定义Binder映射类型
    SerializationBinder = new CrossAppSerializationBinder()
};
var comunicado = JsonConvert.DeserializeObject<Comunicado>(serializedData, jsonSettings);

自定义Binder的实现:

public class CrossAppSerializationBinder : ISerializationBinder
{
    public Type BindToType(string assemblyName, string typeName)
    {
        // 忽略原数据里的程序集名,用当前控制台应用的程序集类型
        return Type.GetType($"{typeName}, {Assembly.GetExecutingAssembly().FullName}");
    }

    public void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null; // 序列化时不输出程序集信息
        typeName = serializedType.FullName;
    }
}

如果你用的是System.Text.Json:

网站端(序列化时):

var jsonOptions = new JsonSerializerOptions
{
    WriteIndented = true,
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { typeInfo => typeInfo.PolymorphismOptions = null } // 关闭多态类型信息写入
    }
};
string serializedData = JsonSerializer.Serialize(yourComunicadoInstance, jsonOptions);

控制台端(反序列化时):

var jsonOptions = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { typeInfo => typeInfo.PolymorphismOptions = null }
    }
};
var comunicado = JsonSerializer.Deserialize<Comunicado>(serializedData, jsonOptions);

三、检查属性定义的一致性

最后再确认一下两个应用里的PerfilDeAcesso[]属性定义完全一致:

  • 两边都要有virtual关键字(你代码里用了virtual,别一边有一边没有)
  • 不要有不一致的序列化特性(比如一边加了[JsonIgnore],另一边没有)
  • 属性的getter/setter访问修饰符也要完全一样

比如两边的属性定义必须是:

public virtual PerfilDeAcesso[] PerfisDeAcesso { get; set; }

内容的提问来源于stack exchange,提问作者Cassio Henrique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:52:55