在VS 2010中将对象类型传递给WCF服务应用程序

时间:2015-02-27 18:49:01

标签: c# wcf

我需要将几种不同类型的用户定义类型作为参数传递给WCF服务应用程序中的同一方法,即CompositeType,CompositeType2,CompositeType3等。

以下是重现的步骤:

步骤1.启动Visual Studio 2010。

步骤2.创建一个新的" WCF服务应用程序"项目

步骤3.构建并运行项目(Debug->从主菜单启动调试或在Solution Explorer中右键单击项目,然后单击Debug-> Start New Instance)。

    Results: A Web Browser will display the contents of the web folder.

步骤4.将以下内容添加到IService1.cs接口:

[OperationContract]
string GetDataAsObject(object value);
[OperationContract]
CompositeType GetDataUsingDataContractAsObject(object composite);

步骤5.将以下内容添加到Service1.svc.cs服务:

public string GetDataAsObject(object value)
{
    int tmpInt = -1;
    tmpInt = (int)value;
    return string.Format("GetDataAsObject Responded You entered: {0}", tmpInt);
}

public CompositeType GetDataUsingDataContractAsObject(object composite)
{
    CompositeType tmpCompositeType;
    tmpCompositeType = (CompositeType)composite;
    if (tmpCompositeType == null)
    {
        throw new ArgumentNullException("composite");
    }
    if (tmpCompositeType.BoolValue)
    {
        tmpCompositeType.StringValue += "Suffix";
    }
    return tmpCompositeType;
}

步骤3.添加新的" Windows窗体应用程序"项目解决方案。

步骤4.在解决方案资源管理器中右键单击引用,然后选择"添加服务引用"然后单击“发现”按钮,然后单击“确定”。

    Results: A Service Reference named ServiceReference1 is added to the project.

步骤5.在表单中添加一个按钮,然后在单击事件中添加:

string tmpStr = string.Empty;
ServiceReference1.Service1Client tstServiceClient;
tstServiceClient = new ServiceReference1.Service1Client();
tmpStr = tstServiceClient.GetData(1);
tmpStr = tstServiceClient.GetDataAsObject(1);
tmpCompositeType = new ServiceReference1.CompositeType();
tmpCompositeType.BoolValue = true;
tmpCompositeType.StringValue = "Hello";
tmpStr = tstServiceClient.GetDataUsingDataContract(tmpCompositeType);
tmpStr = tstServiceClient.GetDataUsingDataContractAsObject(tmpCompositeType);

步骤6.在tmpStr = tstServiceClient.GetData(1)处放置一个断点;然后运行表单应用程序并单击按钮,然后单步执行代码。

Results: An exception occurs at
tstServiceClient.GetDataUsingDataContractAsObject(tmpCompositeType)

The exception while trying to deserialize the message: 

There was an error while trying to deserialize parameter composite.
The InnerException message was 'Error in line 1 position 302.
Element 'http://tempuri.org/:composite' contains data from a type that maps to the name 'CompositeType'.
The deserializer has no knowledge of any type that maps to this name.
Consider using a DataContractResolver or add the type corresponding
to 'CompositeType' 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.'.
Please see InnerException for more details.

添加KnownTypeAttribute并不起作用。 我想要使​​其工作所需的最低复杂性,即我不想替换正在使用的解串器......我只想修复此错误,     "反序列化器不知道任何映射到此名称的类型" 这样它就知道CompositeType是什么。有什么东西需要添加到CompositeType类吗?无论如何让反序列化器知道CompositeType类型吗?

1 个答案:

答案 0 :(得分:3)

Shawn Zhao在Social.MSDN.Microsoft.com论坛上提供了解决方案。将ServiceKnownTypeAttribute添加到OperationContract可以解决此问题:

[OperationContract]
[ServiceKnownType(typeof(CompositeType))]
CompositeType GetDataUsingDataContractAsObject(object composite);

异常消息建议将KnownTypeAttribute添加到DataContract,但这不起作用。感谢您的评论。