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; }
}

Allowedとが空の場合Disallowed、WCF サービス全体で問題なくシリアル化されます。これらのリストのいずれかに値が含まれるとすぐに、CommunicationException でこれを取得します。

ソケット接続が中止されました。これは、メッセージの処理中にエラーが発生したか、リモート ホストが受信タイムアウトを超過したか、基になるネットワーク リソースの問題が原因である可能性があります。ローカル ソケットのタイムアウトは「00:00:29.9899990」でした。

これら 2 つのプロパティをシリアル化するのが難しいのはなぜですか? 前もって感謝します。

4

1 に答える 1

3

Regexクラスはインターフェイスを実装します。ISerializableつまり、プロパティ バッグ (文字列/オブジェクトの辞書) としてシリアル化されます。ISerializable.GetObjectDataReflectorのクラスの の実装を見るとRegex、パターン (文字列) とオプション (型RegexOptions) の両方がシリアル化されていることがわかります。型がであるため、WCF は を認識ISerializableないため、この型のシリアル化に失敗します。RegexOptions

簡単な解決策の 1 つは、これが既知の型であることを 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 に答える