0

在为 Web 服务提供 wsdl 之前,我已经使用 SQL 和 FOR XML PATH 生成了 xml。

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

4

2 回答 2

1

如果它有效,它就有效。

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

于 2015-09-17T09:48:44.647 回答
0

据我所知,如果您将复杂的 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

结束类

于 2015-09-18T17:05:48.683 回答