• 解决一个通过 WebReference 调用 WCF 时自定义 DataContract 类参数提交的问题


    先看一下VS2013自动创建默认的IService1.vb,注意自定义的数据契约 CompositeType

    ' 注意: 使用上下文菜单上的“重命名”命令可以同时更改代码和配置文件中的接口名“IService1”。
    <ServiceContract()>
    Public Interface IService1
    
        <OperationContract()>
        Function GetData(ByVal value As Integer) As String
    
        <OperationContract()>
        Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType
    
        ' TODO: 在此添加您的服务操作
    
    End Interface
    
    ' 使用下面示例中说明的数据约定将复合类型添加到服务操作。
    
    <DataContract()>
    Public Class CompositeType
    
        <DataMember()>
        Public Property BoolValue() As Boolean
    
        <DataMember()>
        Public Property StringValue() As String
    
    End Class

    通过添加 WebReference 引用后的客户端代码

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim wrClient As New localhost.Service1
        Dim data As New localhost.CompositeType
        data.BoolValue = True
        'data.BoolValueSpecified = True
        data.StringValue = "Hello world"
    
        Dim result As localhost.CompositeType = wrClient.GetDataUsingDataContract(data)
        MessageBox.Show(result.StringValue)
    End Sub

    注意被注释掉的那一行,在没有显式地指定 data.BoolValueSpecified = True 的情况下,BoolValue 的值不会被客户端提交到服务端,服务端接收到的 data 参数中BoolValue 将赋值为其默认值(false)。

    类似的还有服务契约中的参数如果不是String类型,则必须指定 [参数名]Specified = True,该参数才会被执行提交,如

      <OperationContract()>
       Function GetDataUsingBoolValue(ByVal boolValue As Boolean, ByVal StringValue As String) As String

    对应的客户端调用代码

    MessageBox.Show(wrClient.GetDataUsingBoolean(True, True, "Hello World"))

    如果你打算客户端省点功夫,不想总是显式地设置 Specified = True, 那么在声明服务契约和数据契约时,就要多做一点工作

    <ServiceContract()>
    Public Interface IService1
    
        <OperationContract()>
        Function GetData(ByVal value As Integer) As String
    
        <OperationContract()>
        Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType
    
        ' TODO: 在此添加您的服务操作
    
        ''' <summary>
        ''' 存在非String类参数的方法
        ''' </summary>
        ''' <param name="boolValue"></param>
        ''' <param name="StringValue"></param>
        ''' <returns></returns>
        ''' <remarks>
        ''' 注意:DataContractFormat(Style:=OperationFormatStyle.Rpc)
        ''' 如果没有设置此属性,非String类的参数默认不会被提交,是否被提交将由 [非String类参数名]Specified 的取值决定
        ''' </remarks>
        <OperationContract(), DataContractFormat(Style:=OperationFormatStyle.Rpc)>
        Function GetDataUsingBoolValue(ByVal boolValue As Boolean, ByVal StringValue As String) As String
    End Interface
    
    ' 使用下面示例中说明的数据约定将复合类型添加到服务操作。
    
    <DataContract()>
    Public Class CompositeType
    
        ''' <summary>
        ''' 非String类的参数
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>
        ''' 注意:IsRequired:=True
        ''' 如果没有设置此属性,该参数默认不会被提交,是否被提交将由 BoolValueSpecified 的取值决定
        ''' </remarks>
        <DataMember(IsRequired:=True)>
        Public Property BoolValue() As Boolean
    
        <DataMember()>
        Public Property StringValue() As String
    
    End Class

    具体的解释,可以参见这里

    今天为这个问题折腾了老半天,尤其是 DataContract 里面的 DataMember(IsRequired:=True) 藏得比较深,特别是在客户端通过 ServiceReference 引用的时候没有这个问题,到了用 WebReference 引用的时候,发现非String类型(如 Integer, Double, Single, DateTime等,不过 Byte数组除外)的参数死活提交不上去了。

    立此存照,希望能帮到不小心掉进这个坑里的同行,:)

  • 相关阅读:
    【高软作业4】:Tomcat 观察者模式解析 之 Lifecycle
    Eclipse 导入 Tomcat 源码
    【高软作业3】:原型化系统 DevTools
    Java Obejct
    Java PriorityQueue
    【高软作业2】:Java IDE调研分析
    GitHub fork 合作开发 快速实现版
    用C#实现天气预报(调用WebService)
    hover和点击事件之间的冲突
    BurpSuite2021系列(三)新建扫描
  • 原文地址:https://www.cnblogs.com/towerbit/p/6436357.html
Copyright © 2020-2023  润新知