3

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

[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”。

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

4

1 回答 1

3

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

一个简单的解决方案是简单地“告诉” WCF 这是一个已知类型,因此序列化将起作用(声明它的一个简单地方是使用类[KnownType]中的属性InboundMailbox(见下文)。另一种选择是拥有数据成员作为正则表达式模式而不是其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不是预期的。

于 2011-10-26T22:39:45.270 回答