15

私はこれらのクラスを持っています:

[DataContract]
public class ErrorBase {}

[DataContract]
public class FileMissingError: ErrorBase {}

[DataContract]
public class ResponseFileInquiry
{
  [DataMember]
  public List<ErrorBase> errors {get;set;};
}

クラスResponseFileInquiryのインスタンスは、私のサービスメソッドがクライアントに返すものです。ここで、ResponseFileInquiry.errorsにErrorBaseのインスタンスを入力すると、すべて正常に機能しますが、継承されたタイプFileMissingErrorのインスタンスを追加すると、シリアル化中にサービス側の例外が発生します。

Type 'MyNamespace.FileMissingError' with data contract name 'FileMissingError' 
is not expected. Add any types not known statically to the list of known types - 
for example, by using the KnownTypeAttribute attribute or by adding them to the 
list of known types passed to DataContractSerializer.'

そのため、シリアライザーは、リストに宣言された型オブジェクト(ErrorBase)が含まれていることを期待しているが、継承された型(FileMissingError)オブジェクトを取得しているために混乱しています。

たくさんのエラータイプがあり、リストにはそれらの組み合わせが含まれているので、それを機能させるために何ができますか?

4

3 に答える 3

17

基本クラスにKnownType属性を追加する必要があります

[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}

このブログでKnownType属性の詳細を読む

于 2010-02-24T21:01:21.753 に答える
7

これを試して:

[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}

エラーメッセージに示されているように、静的に知ることができない情報(ここで表現したポリモーフィックな関係など)は、属性を介して提供する必要があります。この場合、FileMissingErrorデータコントラクトがその基本クラスの既知のタイプであることを指定する必要がありますErrorBase

于 2010-02-24T21:00:29.107 に答える
2

少し遅れますが、将来の世代のためかもしれません。=)

すべての子クラスの属性を親クラスに追加したくない場合は、次を使用して、親クラスの静的コンストラクターで既知の型のリストを作成できます。

 IEnumerable<Assembly> assemblies = AppDomain.CurrentDomain
                                             .GetAssemblies()
                                             .Where(a => !a.GlobalAssemblyCache);

 IEnumerable<Type> serializableTypes = assemblies.SelectMany(a => a.GetTypes())
                                                 .Where(t => IsSerializable(t));

// ...

private static bool IsSerializable(Type type)
{
    return type.GetCustomAttributes(true).Any(a => a is DataContractAttribute);
}

このリストをde/serializersコンストラクターに渡します。このソリューションがどれほど堅牢かはわかりませんが、それが私が行っていることであり、これまでのところ機能しています。少し遅いので、必ず結果をキャッシュしてください。

于 2012-10-23T14:19:02.533 に答える