使用 DataContractSerializer 序列化接口列表

2024-01-29

我有一个类,其中有一些嵌套类。我将其序列化并使用没有问题的方法将其发送到 wcf 服务。这是课程;

public class ComputerDTO
{
    [DataMember]
    public ComputerTypeDTO Type { get; set; }

    [DataMember]
    public string ComputerName { get; set; }

    [DataMember]
    public MonitorDTO Monitor { get; set; }
}

这是方法;

public void Check()
{
    Computer c = new Computer();

    ISystemInfoOperations cli = GetServiceClient();

    Mapper.CreateMap<Monitor, MonitorDTO>();
    Mapper.CreateMap<IHardwarePart, IHardwarePartDTO>();

    Mapper.CreateMap<Computer, ComputerDTO>()
            .ForMember(s => s.Hardware, m => m.MapFrom(q => Mapper.Map<List<IHardwarePart>, List<IHardwarePartDTO>>(q.Hardware)));


    Mapper.AssertConfigurationIsValid();

    ComputerDTO dto = Mapper.Map<Computer, ComputerDTO>(c);

    string sendComputerInfo = cli.SendComputerInfo(dto);
}

但我还有一个要发送的接口列表。所以我像下面这样更改代码并收到错误。

public class ComputerDTO
{
    [DataMember]
    public ComputerTypeDTO Type { get; set; }

    [DataMember]
    public string ComputerName { get; set; }

    [DataMember]
    public MonitorDTO Monitor { get; set; }

    [DataMember]
    public List<IHardwarePartDTO> Hardware { get; set; }
}

public interface IHardwarePartDTO
{
    [DataMember]
    string Name { get; set; }

    [DataMember]
    HardwarePartTypeDTO PartType { get; set;  }
}

硬件内部正在填充该项目。但如果我尝试发送它,我会收到这个著名的错误:

类型 '代理人' 带有数据合约名称 '_x0030__Culture_x003D_neutral_PublicKeyToken_x003D_null_x003E_:http://schemas.datacontract.org/2004/07/Proxy%3CSystemInfo.DTO.IHardwarePartDTO_SystemInfo.DTO_Version=1.0.0 http://schemas.datacontract.org/2004/07/Proxy%3CSystemInfo.DTO.IHardwarePartDTO_SystemInfo.DTO_Version=1.0.0' 预计不会。考虑使用 DataContractResolver 或添加任何 已知类型列表中静态未知的类型 - 例如, 通过使用 KnownTypeAttribute 属性或将它们添加到 传递给 DataContractSerializer 的已知类型列表。


DataContractSerializer 需要了解可能返回的具体类型。接口无法序列化,因为它无法反序列化(如何在没有具体实现的情况下创建接口的实例)。

简单的解决方案是添加 KnownTypes 属性,如下所示:

[KnownType(typeof(your hardware dto concrete type here))]
public class ComputerDTO
{
    [DataMember]
    public ComputerTypeDTO Type { get; set; }

    [DataMember]
    public string ComputerName { get; set; }

    [DataMember]
    public MonitorDTO Monitor { get; set; }

    [DataMember]
    public List<IHardwarePartDTO> Hardware { get; set; }
}

您可以根据需要添加任意数量的已知类型属性。

ServiceKnownTypes 属性稍微复杂一些。这非常相似,但您可以将其添加到您的服务类别中。

除此之外,您可以使用数据契约解析器 - 但这非常复杂,需要一段时间来解释。

编辑: 18/02/2013 15:11

您可能还需要查看 Automapper,因为它当前将在您的硬件列表中创建代理 - 并且代理无法序列化。您需要告诉自动映射器将它们序列化为什么 - 例如:

Mapper.CreateMap<Monitor, MonitorDTO>();
Mapper.CreateMap<Monitor, IHardwarePartDTO>().As<MonitorDTO>();

Mapper.CreateMap<Audio, AudioDTO>();
Mapper.CreateMap<Audio, IHardwarePartDTO>().As<AudioDTO>();

Mapper.CreateMap<CDROMDrive, CDROMDriveDTO>();
Mapper.CreateMap<CDROMDrive, IHardwarePartDTO>().As<CDROMDriveDTO>();
//you need entries like these for everythin that implements IHardwarePartDTO

这样自动映射器就知道它需要创建什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 DataContractSerializer 序列化接口列表 的相关文章

随机推荐

  • 从数据库创建 Grails 域类

    我想从现有数据库创建 grails 域类 通常我是从域类创建数据库 现在我需要从现有数据库模式创建它 如果有可用的命令 请帮助我 我遇到了同样的问题 我发现这个 Grails 插件 https web archive org web 201
  • PHP 解析 XML 时出错(RSS 提要)

    我正在使用基于的 PHP 类在这个答案中找到的 https stackoverflow com questions 250679 best way to parse rss atom feeds with php解析五个 RSS 提要 五人
  • 关闭模态视图

    如果我没记错的话 模态视图必须从父视图中消除 而不是从模态视图本身中消除 在我当前的项目中 我有两个模式视图 在第一个中 我将数据传递给父视图 当数据传递到父视图时 执行dismiss 现在 我有另一个模态视图 它不将数据传递给父视图 所以
  • 处理 WebBrowser 控件上的按键事件?

    目前我正在使用一个可以播放的应用程序ppt并在 WebBrowser 控件中闪烁 在 WebBrowser 中 我可以使用隐藏上下文菜单 this IsWebBrowserContextMenuEnabled false 并使用捕获关键事件
  • 如何捕获 Sequelize 连接错误

    如果存在续集连接错误 如何捕获续集连接错误 我尝试做 var connection new Sequelize db uri connection on error function perhaps reconnect here 但显然这不
  • Akka Stream 和 Kamon-Prometheus 不返回任何指标,但加载空页面

    我尝试将 kamon prometheus 与 akka Stream 项目集成 但在http 本地主机 9095 http localhost 9095 它加载一个空页面 在控制台中 我可以看到一条消息 表明指标信息可在http 本地主机
  • 在 Windows 上使用 HDF5 库和 CMake(错误:“无法找到 HDF5”)

    我想在我的 C 程序中使用 HDF5 库 我在Windows 7上使用VS 2010 x64编译器和CMake 3 8 0rc2 我安装的HDF5版本是1 8 10 通过运行官方 安装程序 安装 在我的 CMakeLists 文件中 我添加
  • 如何在 Laravel 中执行 MYSQL 查询?

    我有一个 MYSQL 查询 我想在 laravel 中执行这个查询 select d1 update id from select update id count update id as ct from updates tags wher
  • 为什么 GCC 说“不再支持命名返回值”?

    我不小心将函数定义的左大括号放在 return 语句之后 int id int k return k 但 GCC 回答了一个奇怪的错误消息 错误 不再支持命名返回值 谁能解释一下这个奇怪的功能可能是什么 我从来没有听说过 See here
  • 编程中的“阻塞”是什么意思?

    有人可以提供外行定义和用例吗 阻塞 意味着调用者等待 直到被调用者完成其处理 例如 来自套接字的 阻塞读取 会等待 直到有数据返回 非阻塞 读取不会 它只是返回是否有读取的指示 通常是计数 您听到这个术语主要是围绕 API 来访问不一定需要
  • Common lisp:有没有一种不那么痛苦的方法来输入数学表达式?

    我喜欢 Common lisp 但有时输入简单的数学表达式真的很痛苦 a 8b 2 1 4bc 4b 2 1 当然我可以转换它 但是有点慢 我先写 然后在每个括号中写 我想知道这里是否有人知道更好的输入方法 我正在考虑编写一个数学宏 其中
  • Azure 逻辑应用响应 HTTP 操作在 60 秒后超时

    我有一个非常简单的 Azure 逻辑应用程序 它对 SAP Web 服务器进行 REST 调用 并在将响应发送回逻辑应用程序的调用者之前转换响应 JSON 令我困惑的是 当 SAP 调用仅花费 1 分钟多一点时 响应操作就会抛出此错误 操作
  • Python C 程序子进程挂在“for line in iter”处

    好的 我正在尝试从 python 脚本运行 C 程序 目前我正在使用一个测试 C 程序 include
  • 为什么即使参数没有经过 URL 编码,某些查询字符串仍然可以工作?

    这是一个例子 The url范围 http journals plos org plosone s file id wjVg PLOSOne formatting sample main body pdf 未编码 它包含保留字符 例如冒号
  • 如何在android中上传PDF文件到服务器?

    我提到了一些以前提出的问题 但没有得到正确的解决方案 我正在创建一个应用程序 并希望通过从文件管理器中选择它来发送 PDF 文件 感谢任何类型的帮助 只有当您必须从图库中选择 PDF 文件时 您才需要更改这行代码 intent setTyp
  • 池化还是不池化 java 加密服务提供商

    Solution MessageDigest gt 根据需要经常创建新实例 KeyFactory gt 使用单个共享实例 SecureRandom gt 使用堆栈对象池 http commons apache org proper comm
  • 敏感列表中的哪个信号触发该过程

    在VHDL中 当模拟测试平台时 我有一个过程和一个敏感度列表 是否可以查看敏感列表中的哪个信号触发了该过程 我知道这可能取决于工具 我正在使用 Xilinx ISE 模拟器是否提供此信息 您可以使用 transaction属性结合 even
  • 为什么 System.Web.HttpUtility.UrlEncode 给出的命名空间名称在 Visual C# 2008 中不存在?

    我正在尝试使用以下方法对 URL 进行编码HttpUtility UrlEncode 方法 为什么我得到 命名空间 System Web 中不存在类型或命名空间名称 HttpUtility 是否缺少程序集引用 错误 我正在使用 Visual
  • Python:从 multiprocessing.Process 获取回溯

    我试图从 multiprocessing Process 获取回溯对象 不幸的是 通过管道传递异常信息不起作用 因为回溯对象无法被腌制 def foo pipe to parent try raise Exception xxx excep
  • 使用 DataContractSerializer 序列化接口列表

    我有一个类 其中有一些嵌套类 我将其序列化并使用没有问题的方法将其发送到 wcf 服务 这是课程 public class ComputerDTO DataMember public ComputerTypeDTO Type get set