C#WCF传递字典<string,object =“”>参数

时间:2017-03-06 08:39:54

标签: c# wcf dictionary

我尝试将Dictionary发送到WCF服务。但是,如果objcte类型是Array或List,它将显示错误&#34;尝试序列化参数时发生错误.......&#34;

  

尝试序列化参数时出错   http://tempuri.org/:str。 InnerException消息是&#39;类型   &#39; System.String []&#39;与数据合同名称   &#39; ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays&#39;   不是预期的。将任何静态未知的类型添加到列表中   已知类型 - 例如,通过使用KnownTypeAttribute属性   或者将它们添加到传递给的已知类型列表中   DataContractSerializer的。&#39 ;.有关详细信息,请参阅InnerException。

这是我的WCF服务:

[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");

还尝试添加一些ServiceKnowType属性,但仍无法正常工作

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

请帮帮我。提前谢谢。

2 个答案:

答案 0 :(得分:1)

你在那本词典中作为一个对象传递了什么?

WCF需要知道您传递的是什么类型,以便它可以反序列化该对象,换言之,WCF是强类型的。

如果您尝试这种方法

[OperationContract]
 int Method(object o);

并从客户端传递DataContract类型:

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

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

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

WCF运行时仍将抛出CommunicationException,因为Method(object o)已捕获定义为WCF 无法反序列化的所有类型。

如果要将对象o替换为MyDataClass,那么

  [OperationContract]
     int Method(MyDataClass myClassObject);

并传入MyDataClass对象,它应该按预期工作。

现在同样的规则适用于Dictionary<string, Object>。 Tye定义一个像MyDataClass这样的DataContract类型,如上所示而不是像对象一样  Dictionary<string, MyDataClass>以便WCF可以对其进行反序列化,通过网络发送到服务方法。

如果你想保持通用,那么使用手动序列化方法Stream,XML或byte []。

希望这有帮助!

答案 1 :(得分:0)

不幸的是,WCF不支持泛型。但是有一种方法可以创建Dictionary作为输入。我不确定你想要什么,但我有同样的问题,我可以这样解决。

[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);
        }
    }
}

它是一个输入类。你可以创建一个像这样的方法:

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