1

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.

4
  • 1
    Why do you need to send type object? Commented Mar 6, 2017 at 9:10
  • I think he is sending System.String[] as object. It says in the inner exception message. Commented Mar 6, 2017 at 10:32
  • This is my first time to write the WCF Service. It is used to communicate with one ECM software. So, with the Dictionary<string, object>, the string represent template name, and object is for the value( can be DateTime, int, double, list, array, ect..) , that is why i am passing the object type. Commented Mar 6, 2017 at 23:49
  • int, double, float and other premitive types should work fine. DateTime is a struct and that should be fine too. List<int> and ArrayList wont work. Commented Mar 7, 2017 at 8:16

2 Answers 2

1

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!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your reply. I will try it.
0

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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.