I have a service that implements the following DataMember:
[DataMember]
public Dictionary<string, List<IOptionQueryResult>> QueryResultItems { get; set; }
I have the class "OptionQuerySingleResult" which inherits from IOptionQueryResult. Now, I understand that I need to make the OptionQueryResult type "known" to the Service and thus tried to add the KnownType in various ways:
[KnownType(typeof(Dictionary<string, OptionQuerySingleResult[]开发者_开发百科>))]
[KnownType(typeof(Dictionary<string, List<OptionQuerySingleResult>>))]
[KnownType(typeof(OptionQuerySingleResult)]
However, none of those approaches worked and on the client side I'm either getting that deserialization failed or the server simply aborted the request, causing a connection aborted error.
Does anyone have an idea on what's the proper way to get this to work? I'd like to add that if I change the QueryResultItems definition to use the concrete type, instead of the interface, everything works just fine.
Thanks,
Tom
Edit: The exception that I am getting is:
Error in line 1 position 524. Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType' contains data from a type that maps to the name ':OptionQuerySingleResult'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'OptionQuerySingleResult' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.
However, when I look at the client proxy that svcutil generates, "OptionQuerySingleResult" is definitely defined in it:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="OptionQuerySingleResult", Namespace="")]
[System.SerializableAttribute()]
public partial class OptionQuerySingleResult : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
I think you would use:
[KnownType(typeof(OptionQuerySingleResult)]
But you also need a [DataContract(Name = "OptionQuerySingleResult")]
on your OptionQuerySingleResult class.
I think this also relies on your client proxy classes being generated by the SVCUTIL.EXE util.
You simply need to add the following property to your datacontract class.
[DataMember]
public object UsedForKnownTypeSerializationObject;
So now the generated proxy contains the Knowtypes you set on the datacontract. I had the same problem and this is the only solution I came up with. If you don't at the a property of type Object to you DataContract class, the generated proxy doesn't contain the declared knowtypes
For example:
[DataContract]
[KnownType(typeof(List<String>))]
public class Foo
{
[DataMember]
public String FooName { get; set; }
[DataMember]
public IDictionary<String, Object> Inputs { get; set; }
[DataMember]
private Object UsedForKnownTypeSerializationObject{ get; set; }
}
It's not as pretty because you end up with a dummy property which doesn't have any functional implementation. But then again I don't have another solution.
精彩评论