我有以下代码:
[DataContract]
class TestContract {
private String _Name;
private Int32 _Age;
[DataMember( Name = "Name" )]
public String Name {
get { return _Name; }
set { _Name = value; }
}
[DataMember( Name = "Age" )]
public Int32 Age {
get { return _Age; }
set { _Age = value; }
}
}
[Serializable]
public class DNCJsonDictionary<K, V> : ISerializable {
Dictionary<K, V> dict = new Dictionary<K, V>();
public DNCJsonDictionary() { }
protected DNCJsonDictionary( SerializationInfo info, StreamingContext context ) {
}
public void GetObjectData( SerializationInfo info, StreamingContext context ) {
foreach( K key in dict.Keys ) {
info.AddValue( key.ToString(), dict[ key ] );
}
}
public void Add( K key, V value ) {
dict.Add( key, value );
}
public V this[ K index ] {
set { dict[ index ] = value; }
get { return dict[ index ]; }
}
}
public class MainClass {
public static String Serialize( Object data ) {
var serializer = new DataContractJsonSerializer( data.GetType() );
var ms = new MemoryStream();
serializer.WriteObject( ms, data );
return Encoding.UTF8.GetString( ms.ToArray() );
}
public static void Main() {
DNCJsonDictionary<String, Object> address = new DNCJsonDictionary<String, Object>();
address[ "Street" ] = "30 Rockefeller Plaza";
address[ "City" ] = "New York City";
address[ "State" ] = "NY";
TestContract test = new TestContract();
test.Name = "CsDJ";
test.Age = 28;
DNCJsonDictionary<String, Object> result = new DNCJsonDictionary<String, Object>();
result[ "foo" ] = "bar";
result[ "Name" ] = "John Doe";
result[ "Age" ] = 32;
result[ "Address" ] = address;
// ** --- THIS THROWS AN EXCEPTION!!! --- **
result[ "test" ] = test;
Console.WriteLine( Serialize( result ) );
Console.ReadLine();
}
}
当我运行时,我得到这个异常:
Type 'Json_Dictionary_Test.TestContract' with data contract name 'TestContract:http://schemas.datacontract.org/2004/07/Json_Dictionary_Test' 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.
但是我不明白!据我所知,KnownTypeAttribute只是在反序列化中使用,如果有继承,不是吗?但这里只是连载。没有数据契约(Contract)成员也能正常工作。
有什么想法吗?
我发现了一些有用的东西!有一个带有 KnownTypes 列表的父类,我用所有子类填充它,并将用于序列化:
[DataContract]
[KnownType( "GetKnownTypes" )] // for serialization
class ResultContract {
private static List<Type> KnownTypes { get; set; }
public static List<Type> GetKnownTypes() {
return KnownTypes;
}
static ResultContract() {
KnownTypes = new List<Type>();
try {
foreach( Type type in Assembly.GetExecutingAssembly().GetTypes() ) {
if( !type.IsAbstract && type.IsSubclassOf( typeof( ResultContract ) ) ) {
KnownTypes.Add( type );
}
}
} catch( Exception ex ) {
Console.WriteLine( "Fatal error!" );
}
}
}
[DataContract]
class TestContract : *ResultContract* {
...
}
...
最佳答案
添加这一行:
[KnownType(typeof(TestContract))]
这样
[Serializable]
[KnownType(typeof(TestContract))]
public class DNCJsonDictionary<K, V> : ...
这是一个已知问题。这就是泛型不适用于 WCF 的原因。
但原因很简单,WCF 应该创建 WSDL 并能够发布您的契约(Contract)。使用泛型来定义您的契约(Contract)很好,但 WSDL 需要指向某个具体类,因此您需要 KnownType
。
关于c# - DataContract 序列化异常(数据契约名称不是预期的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4875187/