Runhua Guan
Runhua Guan

Reputation: 13

C# WCF Passing Dictionary<string, object> parameter

I am try send Dictionary to WCF service. However if the objcte type is Array or List, it will show me the error " There was an error while trying to serialize parameter......."

There was an error while trying to serialize parameter http://tempuri.org/:str. The InnerException message was 'Type 'System.String[]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' 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.'. Please see InnerException for more details.

This is my WCF Service:

[OperationContract]
int PDFImport(string server, 
              string repo, 
              string username, 
              string password, 
              string templateName, 
              string entryName, 
              byte[] image, 
              Dictionary<string, Object> value, 
              string entryPath = @"\1. Incoming", 
              string volume = "DEFAULT");

Also try to adding some ServiceKnowType Attributes, but still not working

[ServiceContract]
[ServiceKnownType(typeof(Dictionary<string, string>))]
[ServiceKnownType(typeof(Dictionary<string, object>))]
[ServiceKnownType(typeof(Dictionary<string, List<string>>))]
[ServiceKnownType(typeof(List<Dictionary<string, List<string>>>))]

Please help me out. Thanks in advance.

Upvotes: 1

Views: 5401

Answers (2)

Mohammad
Mohammad

Reputation: 2764

Unfortunately WCF doesn't support generics. but there is a way you can create Dictionary as a input. I'm not sure that's what you want but i had a same problem and i could solve it this way.

[Serializable]
public class WebServiceInputGetDataParams : ISerializable
{
    public Dictionary<string, object> Entries
    {
        get { return entries; }
    }


    private Dictionary<string, object> entries;
    public WebServiceInputGetDataParams()
    {
        entries = new Dictionary<string, object>();
    }
    protected WebServiceInputGetDataParams(SerializationInfo info, StreamingContext context)
    {
        entries = new Dictionary<string, object>();
        foreach (var entry in info)
        {
            entries.Add(entry.Name, entry.Value);
        }
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        foreach (var entry in entries)
        {
            info.AddValue(entry.Key, entry.Value);
        }
    }
}

its a input class. you can create a method like this:

public void TestMethod(WebServiceInputGetDataParams input)
{
    //access the input through dictiobnary
    input.Entries
}

Upvotes: 0

Yawar Murtaza
Yawar Murtaza

Reputation: 3865

What are you passing as an object in that dictionary?

WCF needs to know what type are you passing so that it can deserialise that object in other words WCF is strongly typed.

If you would try this method

[OperationContract]
 int Method(object o);

and from client pass a DataContract type:

 [DataContract]
    public class MyDataClass
    {
        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public DateTime DateOfBirth { get; set; }   
    }

the WCF runtime will still throw CommunicationException because Method(object o) has catch all type defined that WCF can not deserialise.

If you would replace object o with MyDataClass like so

  [OperationContract]
     int Method(MyDataClass myClassObject);

and pass in MyDataClass object, it should work as expected.

Now same rule applies to the Dictionary<string, Object>. Tye to define a DataContract type like MyDataClass as shown above instead of object like Dictionary<string, MyDataClass> so that WCF can deserialise it, send across the wire to the service method.

If you want to keep it generic then use manual serialisation methods Stream, XML or byte[].

Hope this helps!

Upvotes: 1

Related Questions