开发者

WCF issues with KnownType for Dictionary

开发者 https://www.devze.com 2023-01-03 10:05 出处:网络
I have a service that implements the following DataMember: [DataMember] public Dictionary<string, List<IOptionQueryResult>> QueryResultItems { get; set; }

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消