无法序列化 System.Collections.Generic.Dictionary`2 类型的成员 ...,因为它实现了 IDictionary

2024-04-30

我试图通过 WCF 传递一个带有 Dictionary 属性的类,对于一种方法失败,但对于另一种方法有效。当类在 a 内返回时List, 有用。但是当类在 a 中返回时DataTable,客户端只是说连接已断开并且没有显示错误。

这是引起问题的类:

[DataContract]
public class DetailLog
{
    [DataMember]
    public string Name
    {
        get;
        set;
    }

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

    [DataMember]
    public Dictionary<string, string> Fields
    {
        get;
        set;
    }

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

我开始创建一个没有问题的方法:

public List<DetailLog> GetDetailLog(List<int> IDs, List<int> actionTypeIds, List<int> userIds, DateTime beginDate, DateTime endDate)

然后我们需要创建一些非常动态的报告,因此我使用了我们之前用于其他动态报告的数据表。

但我需要传递 DetailLog 类,因此我创建了该类型的 DataTable 列:

public DataTable GetCustomDetailReport(int CustomReportID, List<CustomReportFilter> reportFilters)
{
DataTable data = new DataTable();
...
data.Columns.Add("DetailLog", typeof(DetailLog));
...
}

此方法在 WCF 主机端可以正常退出,但在客户端会出现连接丢失的错误。我尝试在界面中为OperationContract添加ServiceKnownType,但没有修复它:

[OperationContract]
[ServiceKnownType(typeof(DetailLog))]
DataTable GetCustomUserAuditReport(int CustomReportID, List<CustomReportFilter> reportFilters);

当该方法返回 DataTable 时,我无法真正调试序列化,因此我将此代码添加到 GetCustomDetailReport() 的末尾以捕获错误。

DataContractSerializer ser = new DataContractSerializer(typeof(DataTable), new List<Type> { typeof(DetailLog) });
ser.WriteObject(Stream.Null, data);

当我这样做时,我看到了一个异常

Cannot serialize member ... of type System.Collections.Generic.Dictionary`2 because it implements IDictionary.

您的问题如下:

  1. Dictionary<TKey, TValue>是由数据契约序列化器 https://msdn.microsoft.com/en-us/library/ms731072%28v=vs.110%29.aspx在 WCF 中使用,如docs https://msdn.microsoft.com/en-us/library/ms731923%28v=vs.110%29.aspx。这就是为什么你的DetailLog类可以由 WCF 作为根对象成功地通过线路发送。

  2. 该序列化器还支持IXmlSerializable https://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx允许类型手动将自身序列化为 XML。

  3. DataTable https://msdn.microsoft.com/en-us/library/system.data.datatable%28v=vs.110%29.aspx实施IXmlSerializable.

  4. 在内部,DataTable序列化非原始条目using XmlSerializer https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.110%29.aspx-- 一个完全不同的序列化器,使用完全不同的代码库。

  5. XmlSerializer不支持字典 https://msdn.microsoft.com/en-us/library/ms950721.aspx。因此你的DetailLog无法通过 WCF 有线发送当嵌套在DataTable.

  6. 作为一个无关的问题,你还需要设置数据表名,如果不设置,序列化会抛出异常:

        data.TableName = "CustomDetailReport"; // For instance
    

要解决字典问题,您需要使您的DetailLog两个序列化器都可以序列化类。问题如何序列化/反序列化Dictionary<int, string>来自不使用 XElement 的自定义 XML? https://stackoverflow.com/questions/12554186/how-to-serialize-deserialize-to-dictionaryint-string-from-custom-xml-not-us给出了多种方法来序列化其字典属性,包括使用代理数组属性:

[XmlType("KeyValue"), XmlRoot("KeyValue")]
public class SerializableKeyValuePair<TKey, TValue>
{
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}

public static class SerializableKeyValuePairExtensions
{
    public static SerializableKeyValuePair<TKey, TValue> ToSerializablePair<TKey, TValue>(this KeyValuePair<TKey, TValue> pair)
    {
        return new SerializableKeyValuePair<TKey, TValue> { Key = pair.Key, Value = pair.Value };
    }
}

[DataContract]
public class DetailLog
{
    [DataMember]
    public string Name { get; set; }

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

    [DataMember]
    [XmlIgnore]
    public Dictionary<string, string> Fields { get; set; }

    [IgnoreDataMember]
    [XmlArray("Fields")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public SerializableKeyValuePair<string, string>[] FieldsArray
    {
        get
        {
            return Fields == null ? null : Fields.Select(p => p.ToSerializablePair()).ToArray();
        }
        set
        {
            Fields = value == null ? null : value.ToDictionary(p => p.Key, p => p.Value);
        }
    }

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

WCF 现在应该能够发送您的DataTable成功通过电线。

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

无法序列化 System.Collections.Generic.Dictionary`2 类型的成员 ...,因为它实现了 IDictionary 的相关文章

  • 部署 MVC4 项目时出错:找不到文件或程序集

    过去 我只需使用 Visual Studio 2012 发布到 AWS 菜单项即可部署我的 MVC4 网站 到 AWS Elastic Beanstalk 现在 程序可以在本地编译并运行 但无法部署 从消息来看 它似乎正在寻找不在当前部署的
  • boost::multi_index_container 复合键中的 equal_range 与比较运算符

    我正在尝试从多索引容器查询结果 其中值类型是三个元素的结构 第一个值已给出 但第二个和第三个值必须大于或小于查询参数 经过搜索后 我发现必须实现自定义密钥提取器 并且这里的一些链接建议相同 但我无法实现它 boost multi index
  • 在 LINQ 查询中返回不带时间的日期

    我正在编写一个查询 我想计算按日期联系我们的呼叫中心的次数 看起来很简单 但由于联系日期字段是日期时间字段 我得到了时间 因此当我按联系日期 时间 分组时 每个联系日期实例的计数为 1 所以 我想只按日期分组 而不按时间分组 下面是我用来查
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud

随机推荐