【问题标题】:WCF DataContract With List of RegExs Won't Serialize Properly带有 RegEx 列表的 WCF DataContract 无法正确序列化
【发布时间】:2011-10-26 21:39:15
【问题描述】:

我有一个看起来像这样的类:

[DataContract]
public class InboundMailbox
{
    public const char EmailSeparator = ';';

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

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

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

    [DataMember]
    public List<Regex> Allowed { get; set; }

    [DataMember]
    public List<Regex> Disallowed { get; set; }
}

如果 AllowedDisallowed 为空,那么它可以在我的 WCF 服务中很好地序列化。只要其中一个列表包含一个值,我就会在 CommunicationException 中得到它:

套接字连接被中止。这可能是由错误引起的 处理您的消息或接收超时被超过 远程主机或底层网络资源问题。本地插座 超时为“00:00:29.9899990”。

为什么我很难序列化这两个属性?提前致谢。

【问题讨论】:

  • 您通过网络发送的正则表达式列表有多大?
  • 如果我将单个正则表达式放在其中一个列表中,我会得到异常。并且正则表达式本身并不长,可能

标签: regex wcf serialization datacontract datamember


【解决方案1】:

Regex 类实现了ISerializable 接口,这意味着它被序列化为一个属性包(字符串/对象的字典)。查看 Reflector 中 Regex 类的 ISerializable.GetObjectData 实现,它表明它序列化了模式(字符串)和选项(类型为 RegexOptions)。由于类型是ISerializable,WCF 不知道 RegexOptions,所以它无法序列化这个类型。

一个简单的解决方案是简单地“告诉”WCF 这是一个已知类型,因此序列化将起作用(一个简单的声明它的地方是使用@987654329 中的[KnownType] 属性@ 类(见下文)。另一种选择是将数据成员作为正则表达式模式,而不是 Regex 本身(也可能是选项)。

public class StackOverflow_7909261
{
    [DataContract]
    [KnownType(typeof(RegexOptions))]
    public class InboundMailbox
    {
        public const char EmailSeparator = ';';

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

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

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

        [DataMember]
        public List<Regex> Allowed { get; set; }

        [DataMember]
        public List<Regex> Disallowed { get; set; }
    }

    public static void Test()
    {
        MemoryStream ms = new MemoryStream();
        InboundMailbox obj = new InboundMailbox
        {
            POP3Host = "popHost",
            EmailId = "email",
            WebServiceURL = "http://web.service",
            Allowed = new List<Regex>
            {
                new Regex("abcdef", RegexOptions.IgnoreCase),
            },
            Disallowed = null,
        };
        DataContractSerializer dcs = new DataContractSerializer(typeof(InboundMailbox));
        try
        {
            dcs.WriteObject(ms, obj);
            Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
}

顺便说一句,如果您在服务器端启用了跟踪,您会发现错误;它会有一个例外,说类型 RegexOptions 不是预期的。

【讨论】:

  • 你知道你是我的英雄,我想成为的一切吗?我可以飞得比鹰更高,因为你是我翅膀下的风。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 2010-09-08
  • 1970-01-01
  • 2011-06-28
  • 2012-06-23
相关资源
最近更新 更多