直接生成 XML 以发送到 WCF Web 服务是不好的做法吗?

Is it bad practice to directly generate XML for sending to a WCF web service?

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

现在我有了 wsdl,我应该返回并从 SQL 中单独填充每个对象,我应该将我的 XML 反序列化到请求对象中(如果可能的话)还是有另一个选择?有什么陷阱可以提前提醒我吗?

如果有效,那就有效。

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

据我所知,如果您要将复杂的 xml 结构从 SQL 数据库发布到 WCF Web 服务,那么创建整个 xml 并没有什么坏处document using FOR XML PATH - 事实上我会说它更好更简单。然后,您可以针对 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

结束Class