我需要将几种不同类型的用户定义类型作为参数传递给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类型吗?
答案 0 :(得分:3)
Shawn Zhao在Social.MSDN.Microsoft.com论坛上提供了解决方案。将ServiceKnownTypeAttribute添加到OperationContract可以解决此问题:
[OperationContract]
[ServiceKnownType(typeof(CompositeType))]
CompositeType GetDataUsingDataContractAsObject(object composite);
异常消息建议将KnownTypeAttribute添加到DataContract,但这不起作用。感谢您的评论。