InnerException消息是'在传递给W服务时键入包含数据协定名称

时间:2013-02-04 16:15:26

标签: wcf

我有一个WCF服务,其操作合同为

void AddQuery(IQuery Query);

我的智商就像这样

public interface IQuery
{
    Guid                Id { get; set; }        
    string              QueryNo { get; set; }
    string              Status { get; set; }
    IData               data { get; set; }
}

并且IQuery的实现在

[Serializable]
public class Query : IQuery
{
    Guid                Id { get; set; }        
    string              QueryNo { get; set; }
    string              Status { get; set; }
    IData               data { get; set; }
}

当我尝试从客户端发送我的对象时

  public void AddQuery(IQuery query)
  {
      try
      {
          // I am sure that the query object is not null and it is implemented
          objServiceClient.AddEnquiry(query);
      }
      catch (Exception ex)
      {
      }
  }

但是我得到了一个例外

  

尝试序列化参数时出错。 InnerException消息是' Type' ViewModels.Query'数据合同名称'查询:http://schemas.datacontract.org/2004/07/ViewModels'不是预期的。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。'。有关详细信息,请参阅InnerException。

有人可以建议我这个错误的解决方案是什么?

1 个答案:

答案 0 :(得分:5)

考虑序列化具体类。您无法序列化接口。请参阅此答案:https://stackoverflow.com/a/4659289/860243

我从bing中找到了一些有用的链接:

http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/

上面的文章讨论了您的情况以及为派生类使用[KnownType]的示例

<强>更新

根据此link,请查看以下更新:

public interface IQuery 
{ 
    Guid Id { get; set; }
    string QueryNo{ get; set; } 
    string Status { get; set; } 
    IData data {get; set;}
}

使用数据合同序列化程序实现接口IQuery

的Query类
[DataContract]
public class Query : IQuery
{
    [DataMember]
    public Guid Id { get; set; };
    [DataMember]
    public string QueryNo { get; set; };
    [DataMember]
    public string Status { get; set; };
    [DataMember]
    public Data data { get; set; }; //Make sure you serialize Data class as well
}

对于您的服务合同:

[ServiceContract]
public interface IMyQueryService
{
      [OperationContract]
      [ServiceKnownType(typeof(Query))]
      void AddQuery(IQuery query);
}

[ServiceKnownType(typeof(Query))]将允许您的操作合同允许Query作为输入。另请注意,您需要将所有需要作为参数传递的IQuery实现指定为具有ServiceKnownType属性的操作合同。

此外,如果您希望多个(或所有)操作合同将其作为参数,请分别为ServiceKnownType而不是每个操作合同指定ServiceContract属性。

希望这有帮助!