【问题标题】:Is it bad practice to directly generate XML for sending to a WCF web service?直接生成 XML 以发送到 WCF Web 服务是不好的做法吗?
【发布时间】:2015-09-17 09:46:47
【问题描述】:

在获得 Web 服务的 wsdl 之前,我已经使用 SQL 和 FOR XML PATH 生成了 xml。

现在我有了 wsdl,我应该返回并从 SQL 中单独填充每个对象,我应该将我的 XML 反序列化为请求对象(如果可能的话)还是有其他选择?有什么问题可以提前警告我吗?

【问题讨论】:

  • 感谢@CodeCaster 的回复。我可以稍微扩展一下最初的问题吗? wsdl 包含一个内联 xsd,但我可以看到 xsd 中的限制不在从它创建的对象模型中。是在运行时的任何时候使用内联 xsd 还是实际上没有使用这些验证?如果正在使用,它们是在创建对象时使用还是在对象被序列化为 xml 时使用?
  • `

标签: xml web-services wcf wsdl for-xml-path


【解决方案1】:

如果它有效,它就有效。

从 WSDL 生成客户端代码和类比手工制作 XML 有很多好处:它们很容易更新,并且不像后一种选项那样容易出现复制粘贴错误。

【讨论】:

    【解决方案2】:

    据我所知,如果您将复杂的 xml 结构从 SQL 数据库发布到 WCF Web 服务,那么使用 FOR XML PATH 创建整个 xml 文档并没有什么坏处 - 事实上我会说它更好更简单。然后,您可以针对 xsd 手动验证它(它将针对 xsd:restrictions、minOccurs、maxOcurs 等进行验证),然后将其反序列化为 WSDL 创建的复杂对象层次结构。请注意,WSDL 不进行任何验证(xsd:restrictions、minOccurs、maxOccurs 不在客户端验证)——它只是创建对象层次结构。

    这当然假设您对 SQL 和 XML PATH 很熟悉!否则,您可以在代码中构建对象层次结构,但在调用真正的 Web 服务之前不会进行任何验证。

    xsd 验证是一种带和大括号的备份,以避免将无效数据发送到 Web 服务。显然,在现实世界中,您发送的任何数据都应该使用用户友好的错误消息进行正确验证。

    这里有一些示例代码:

    Imports System.Xml
    Imports System.Xml.Schema
    Imports System.Data.SqlClient
    Imports System.Xml.Serialization
    Imports ClassLibrary1.ServiceReferences.ClientX
    Imports System.IO
    Imports System.Configuration
    
    Public Class ClientXWebServices
    
    Private _isValid As Boolean?
    Private _xmlErrorList As New List(Of String)
    Private _xmlWarningList As New List(Of String)
    
    Sub New()
    
    End Sub
    
    Function Send(id As Guid) As StoreData.storeDataResponse
        Dim xdoc As XmlDocument = New XmlDocument()
        Using cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString())
            cnn.Open()
            Dim cmd = New SqlCommand("employer.clientx_xml_setup_select", cnn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.AddWithValue("@id", id)
    
            Using reader = cmd.ExecuteXmlReader
                If (reader.Read()) Then
                    xdoc.Load(reader)
                End If
            End Using
        End Using
    
        'Validate (belt and braces)
        Dim myschema As XmlSchema
        Using reader As XmlTextReader = New XmlTextReader("storeData.xsd")
            myschema = XmlSchema.Read(reader, Nothing)
        End Using
        xdoc.Schemas.Add(myschema)
        xdoc.Validate(AddressOf DocumentValidationCallback)
        If Not _isValid.HasValue Then
            _isValid = True
        End If
        If _isValid = False Then
            MsgBox(String.Join(vbCrLf, _xmlErrorList.Union(_xmlWarningList).ToArray))
            Return Nothing
        End If
    
        Dim xmlSer As XmlSerializer = New XmlSerializer(GetType(StoreData.storeDataRequest))
        Dim ssdr As StoreData.storeDataRequest = xmlSer.Deserialize(New StringReader(xdoc.OuterXml))
        Dim client As New StoreData.StoreDataClient
        Dim response As StoreData.storeDataResponse
        Try
            response = client.ServiceReferences_CLIENTX_StoreData_StoreData_storeData(ssdr)
        Catch ex As Exception
            Throw New IOException("ClientX Web Service 'StoreData' could not be contacted.", ex)
        End Try
    
        Return response
    End Function
    
    Sub DocumentValidationCallback(ByVal sender As Object, ByVal args As ValidationEventArgs)
        If args.Severity = XmlSeverityType.Warning Then
            _xmlErrorList.Add(args.Message)
        ElseIf args.Severity = XmlSeverityType.Error Then
            _xmlWarningList.Add(args.Message)
        End If
        _isValid = False
    End Sub
    

    结束类

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多