WCF入门开发的常见问题。

648 阅读1分钟

最近10天一直再开发基于wcf的cs架构软件,遇到很多问题记录一下。

  1. wcf的客户端添加服务引用时,自动在新命名空间下生成代码。如果想使用原来的数据结构,需要的数据结构独立定义,在添加服务引用前就添加项目依赖。参考链接

  2. 找不到引用协定“××”的默认终结点元素 。 这是客户端配置问题,需要把client中自动生成的app.config中的servicemodel中的内容拷贝到主程序的app.config中。参考链接

  3. wcf加载过程中提示wcf IMetadataExchange xmlserializers file not found的异常问题。可以直接忽略,wcf的内部错误。或者勾选vs中的仅我的代码即可。

  4. 含有回调的wcf在wcf测试工具添加服务后显示所有服务均无法测试问题:正常现象,因为回调接口需要在客户端实现,显然客户端测试工具没有回调的实现所以无法测试。参考链接

  5. 添加wcf服务引用时报错的问题。解决方法:使用wcf测试工具添加终端点(需要公布mex),在html视图有详细失败原因:如:需要的数据未添加DataContract特性。

  6. 服务元数据的发布:1.mex 需要添加契约为IMetadataExchange的服务终端点。2.Http-Get。最好在基地址中把需要的方式的基地址都定义了,wcf会自行适配。公布了服务元数据才能添加服务引用和wcfTestClient工具。

  7. 启动服务时:XmlException: 名称不能以“<”字符(十六进制值 0x3C)开头。可能的原因:重写app.config,配置文件错误。参考链接

  8. 错误如下: 好像是协议配置错误的问题,重配后好了。

EndpointNotFoundException: '没有通道可以接受带有操作“http://schemas.xmlsoap.org/ws/2004/09/transfer/Get'
There was no channel that could accept the message with action 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get'

  1. wcf不能从特殊类“System.MulticastDelegate”派生,wcf中定义的接口不允许使用该类型参数。

  2. 在含有回调的接口服务实现中OperationContext为null的问题

  • 可能因为回调接口没有定义操作[OperationContract] 也就是回调没有正确的定义。
  • 请注意这句话!!!! OperationContext is populated by information about the client when an operation call is made. 必须在客户端的对服务端的调用的函数中才能获取到OperationContext 。 参考链接
  • 获取OperationContext 的对象必须是wcf通过serviceHost创建的参考链接
  1. 回调调用时出现异常:
$exception {"无法将通信对象 System.ServiceModel.Channels.ServiceChannel 用于通信,因为它已经被中止。"} System.ServiceModel.CommunicationObjectAbortedException
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

重新生成项目,更新服务引用后解决。

  1. 异常如下。原因:如果参数是object的话,必须使用真正的类型声明ServiceKnowType否则就会报如上错误。(最好不要使用object)。
- $exception {"尝试对参数 Wayeal.Smartlab.qPCR 进行序列化时出错: sender。InnerException 消息是“数据协定名称为“qPCR:http://schemas.datacontract.org/2004/07Lab.Plugin.CComponent.WayealDevice.qPCR”的类型“SmartLab.Plugin.CComponent.WayealDevice.qPCR.qPCR”不是所需的类型。请考虑使用 DataContractResolver(如果你正在使用 DataContractSerializer),或将任何未知类型以静态方式添加到已知类型的列表。例如,可以使用 KnownTypeAttribute 属性,或者将未知类型添加到传递给序列化程序的已知类型列表。”。有关详细信息,请参见 InnerException。"} System.ServiceModel.CommunicationException
  1. 调用接口时出现以下异常:
System.Xml.XmlException
HResult=0x80131940
Message=名称不能以“<”字符(十六进制值 0x3C)开头。
Source=System.Xml
StackTrace:
at System.Xml.XmlConvert.VerifyNCName(String name, ExceptionType exceptionType)

This exception was originally thrown at this call stack:
System.Xml.XmlConvert.VerifyNCName(string, System.Xml.ExceptionType)

WCF内部异常,不影响服务调用。勾选仅我的代码可以忽略

  1. 使用int而不是枚举。枚举ServiceKnowType声明后会生成客户端字符串形式。

  2. (别人分享的)如果调用wcf的服务客户端发送是正常的,服务端收到的也正常,但客户端的返回是Null时,可能时服务的契约更新了,客户端与服务端不对应导致的。

16.最小的wcf回调的例子: adamprescott.net/2012/08/15/…

  1. 进行序列化时出错,内部异常为
数据协定名称为“ArrayOfKeyValueOfanyTypeanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays”的类型“System.Collections.Hashtable”不是所需的类型

原因:由于Hashtable并不是强类型的,它内部实际使用object来存储,所以当数据传输到另一端时,并不能正确判断其元素类型并反序列化。 参考: social.msdn.microsoft.com/Forums/sqls… 解决方案有3种:

  • 需要给包含Hashtable类型属性的类加上KnownType attribute来指定实际的类型。如:
[DataContract]
public class Book { }

[DataContract]
public class Magazine { }

[DataContract]
[KnownType(typeof(Book))]
[KnownType(typeof(Magazine))]
public class LibraryCatalog
{
[DataMember]
System.Collections.Hashtable theCatalog;
}

详见msdn.microsoft.com/en-us/libra…

  • 实现序列化方法,参考<<全面解析wcf>>上。
  • 转换成 Dictionary<TKey,TValue>.
  • 直接转成string传