【问题标题】:XML Request Attachment Missing缺少 XML 请求附件
【发布时间】:2014-05-08 19:23:00
【问题描述】:

我正在尝试使用 API 调用 UploadSiteHostedPictures 将图像上传到 eBay 的服务器。

该调用允许发送 URL 或二进制数据。对于我的应用程序,我选择使用后者来规避因 eBay 无法通过 HTTPS 读取数据而导致的问题。


我的请求

标题

  • 内容类型:multipart/form-data;边界=abcdefghijklmnopqrstuv0987654321
  • X-EBAY-API-DEV-NAME:DEV_NAME
  • X-EBAY-API-APP-NAME:APP_NAME
  • X-EBAY-API-CERT-NAME:CERT_NAME
  • X-EBAY-API-SITEID:SITEID
  • X-EBAY-API-COMPATIBILITY-LEVEL:863

身体

--abcdefghijklmnopqrstuv0987654321
Content-Disposition: form-data; name="XML Payload"
Content-Type: text/xml;charset=utf-8"

<?xml version="1.0" encoding="utf-8"?>
<UploadSiteHostedPicturesRequest xmlns="urn:ebay:apis:eBLBaseComponents">
  <RequesterCredentials>
    <eBayAuthToken>token</eBayAuthToken>
  </RequesterCredentials>
</UploadSiteHostedPicturesRequest>
--abcdefghijklmnopqrstuv0987654321
Content-Disposition: form-data; name="imgname"; filename="imgname"
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream

photo base64binary data
--abcdefghijklmnopqrstuv0987654321--

Ebay 的回应

<?xml version="1.0" encoding="UTF-8"?>
<UploadSiteHostedPicturesResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2014-05-08T18:31:03.633Z</Timestamp>
  <Ack>Failure</Ack>
  <Errors>
    <ShortMessage>Attachment request file is missing.</ShortMessage>
    <LongMessage>Attachment request file is missing.</LongMessage>
    <ErrorCode>2191116</ErrorCode>
    <SeverityCode>Error</SeverityCode>
    <ErrorClassification>RequestError</ErrorClassification>
  </Errors>
  <Version>871</Version>
  <Build>E871_CORE_MSA_16805861_R1</Build>
</UploadSiteHostedPicturesResponse>

【问题讨论】:

  • 你有没有得到这个工作?我正在尝试使用相同的调用来发布图像文件数据或仅提供远程图像 url。我实际上需要让两者都工作,但我有相同的错误消息。如果你确实得到了这个工作,你能发布你的.net代码吗?非常感谢
  • 我从来没有在这个问题上取得任何进展,但这是我在此过程中发现的一个 PHP 示例:ebaydts.com/eBayKBDetails?KBid=1092

标签: xml base64 attachment multipartform-data ebay-api


【解决方案1】:

这是我的 .net 版本。抱歉,它是 vb。Telerik 提供的一款很棒的免费在线工具。 (http://converter.telerik.com/)

回应

Public Class UploadSiteHostedPicture_APIResponse

Private _APICallLength As Integer
''' <summary>
''' This is the time in milliseconds that it took for the API call to respond.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property APICallLength() As Integer
    Get
        Return _APICallLength
    End Get
    Set(ByVal value As Integer)
        _APICallLength = value
    End Set
End Property

Public Property APIStatus() As String
Public Property Success As Boolean = False

Public Property APICallStartTime As DateTime
Public Property APICallEndTime As DateTime

Public Property FullResponse As String

Public Property SiteHostedPictureDetail As New SiteHostedPictureDetails

Public Property ExternalPictureURL As String
Public Property UseByDate As DateTime

Public Property Errors As Boolean = False
Public Property ErrorMsgShort As String
Public Property ErrorMsgLong As String

Public Class SiteHostedPictureDetails
    Public Property PictureSet As String
    Public Property PictureFormat As String
    Public Property FullURL As String
    Public Property BaseURL As String
    Public Property ExternalPictureURL As String

    Public Property PictureSetMembers As New List(Of PictureSetMember)

    Public Class PictureSetMember
        Public Property MemberURL As String
        Public Property PictureHeight As Integer
        Public Property PictureWidth As Integer
    End Class

End Class

请求

Imports System.Xml.XPath
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Configuration

Public Class UploadSiteHostedPicture_APIRequest

'http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/UploadSiteHostedPictures.html
'http://iweb.corp.ebay.com/prod/help/API/doc_internal/xml/Reference/ebay/DeleteSiteHostedPictures.html

#Region "Private Init Items"

Private _DevID As String = ""
Private _AppID As String = ""
Private _CertID As String = ""
Private _ServiceEndpoint As String = ""
Private _AuthToken As String = ""

Private SERVER_NAME As String = ConfigurationManager.AppSettings("Host_Name")
Private SCRIPT_NAME As String = SERVER_NAME & "/UploadSiteHostedPicture_APIRequest.vb"

Private _ExtensionDays As Integer = -1 'Need to set this to a value >=0 for it to be added into the request.
Private _BoundaryText As String = "file_boundary_tag"
Private _APICallStartTime As DateTime
Private _APICallEndTime As DateTime

#End Region

#Region "Public Items"

Public Property RawResponse As String

Public Sub New(DevID As String, AppID As String, CertID As String, ServiceEndpoint As String, AuthToken As String)
    _DevID = DevID
    _AppID = AppID
    _CertID = CertID
    _ServiceEndpoint = ServiceEndpoint
    _AuthToken = AuthToken
End Sub

''' <summary>
''' Allows you to pass in the remote url of the image for the eBay service to download and process.
''' </summary>
''' <param name="RemoteImageUrl">Remote URL of the image that the image service needs to download</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetAPIValue(RemoteImageUrl As String) As UploadSiteHostedPicture_APIResponse
    Dim retVal As New UploadSiteHostedPicture_APIResponse()
    _APICallStartTime = Now()
    Dim respString As String = getAPIResponse(RemoteImageUrl)
    _APICallEndTime = Now()

    If (respString = "") Then
    Else
        retVal = ProcessResponse(respString)
    End If
    Return retVal
End Function

''' <summary>
''' Allows you to pass in a byte array with the image data.
''' </summary>
''' <param name="RawImageData">A byte array of the image to post to the eBay image service</param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetAPIValue(RawImageData As Byte()) As UploadSiteHostedPicture_APIResponse
    Dim retVal As New UploadSiteHostedPicture_APIResponse()
    _APICallStartTime = Now()
    Dim respString As String = getAPIResponse(RawImageData)
    _APICallEndTime = Now()

    If (respString = "") Then
    Else
        retVal = ProcessResponse(respString)
    End If

    Return retVal
End Function

#End Region

#Region "Private Processing Methods"

''' <summary>
''' Private function to add the necessary headers to the WebRequest
''' </summary>
''' <param name="RemoteURLInUse">Setting this to FALSE means that you are posting binary image data and the method will add the necessary ContentType values to the WebRequest</param>
''' <returns>A new HttpWebRequest object</returns>
''' <remarks></remarks>
Private Function getWebRequest(RemoteURLInUse As Boolean) As HttpWebRequest
    Dim req As HttpWebRequest = DirectCast(WebRequest.Create(_ServiceEndpoint), HttpWebRequest)

    'Add the request headers
    req.Headers.Add("X-EBAY-API-COMPATIBILITY-LEVEL", "803")
    'req.Headers.Add("X-EBAY-API-SITEID", "0")  'US SiteID
    req.Headers.Add("X-EBAY-API-SITEID", "15") 'AU SiteID
    req.Headers.Add("X-EBAY-API-CALL-NAME", "UploadSiteHostedPictures")
    req.Headers.Add("X-EBAY-API-DEV-NAME", _DevID)
    req.Headers.Add("X-EBAY-API-APP-NAME", _AppID)
    req.Headers.Add("X-EBAY-API-CERT-NAME", _CertID)

    req.Method = "POST"

    If (RemoteURLInUse = False) Then
        req.ContentType = "multipart/form-data; boundary=" & _BoundaryText
    End If

    Return req
End Function

''' <summary>
''' Gets the raw response from the API when a remote image url is passed in.
''' </summary>
''' <param name="RemoteImageUrl">The url of the image that the eBay image service will need to download</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function getAPIResponse(RemoteImageUrl As String) As String
    Dim retVal As HttpWebResponse = Nothing
    Dim req As HttpWebRequest = getWebRequest(True)
    Dim strRequest As New StringBuilder("")

    strRequest.Append("<?xml version=""1.0"" encoding=""utf-8""?>")
    strRequest.Append("<UploadSiteHostedPicturesRequest xmlns=""urn:ebay:apis:eBLBaseComponents"">")
    If _ExtensionDays >= 0 Then
        strRequest.Append(" <ExtensionInDays>" & _ExtensionDays & "</ExtensionInDays>")
    End If
    strRequest.Append(" <ExternalPictureURL>" & RemoteImageUrl & "</ExternalPictureURL>")
    strRequest.Append(" <RequesterCredentials>")
    strRequest.Append("  <eBayAuthToken>" & _AuthToken & "</eBayAuthToken>")
    strRequest.Append(" </RequesterCredentials>")
    strRequest.Append("</UploadSiteHostedPicturesRequest>")

    Dim postDataBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(strRequest.ToString())
    Dim len As Integer = postDataBytes.Length
    req.ContentLength = len

    Dim requestStream As System.IO.Stream = req.GetRequestStream()
    requestStream.Write(postDataBytes, 0, len)
    requestStream.Close()

    Try
        ' get response and write to console
        retVal = DirectCast(req.GetResponse(), HttpWebResponse)
    Catch ex As Exception

    End Try

    Return getWebResponseString(retVal)
End Function

''' <summary>
''' Gets the raw response from the API when the raw image data is passed in.
''' </summary>
''' <param name="ImageData">A byte array containing the image file data</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function getAPIResponse(ImageData As Byte()) As String
    Dim retVal As HttpWebResponse = Nothing

    Dim req As HttpWebRequest = getWebRequest(False)

    Dim uploadFileRequest As String

    Dim sb As New StringBuilder()
    sb.AppendLine("--" & _BoundaryText)
    sb.AppendLine("Content-Disposition: form-data; name=""XML Payload""")
    sb.AppendLine("Content-Type: text/plain; charset=US-ASCII")
    sb.AppendLine("Content-Transfer-Encoding: 8bit")
    sb.AppendLine("")
    sb.AppendLine("<?xml version=""1.0"" encoding=""utf-8""?>")
    sb.AppendLine("<UploadSiteHostedPicturesRequest xmlns=""urn:ebay:apis:eBLBaseComponents"">")
    If _ExtensionDays >= 0 Then
        sb.AppendLine(" <ExtensionInDays>" & _ExtensionDays & "</ExtensionInDays>")
    End If
    sb.AppendLine(" <RequesterCredentials>")
    sb.AppendLine("  <ebl:eBayAuthToken xmlns:ebl=""urn:ebay:apis:eBLBaseComponents"">" & _AuthToken & "</ebl:eBayAuthToken>")
    sb.AppendLine(" </RequesterCredentials>")
    sb.AppendLine(" <PictureSet>Supersize</PictureSet>")
    sb.AppendLine("</UploadSiteHostedPicturesRequest>")
    sb.AppendLine("")
    sb.AppendLine("--" & _BoundaryText)
    sb.AppendLine("Content-Type: application/octet-stream; charset=ISO-8859-1")
    sb.AppendLine("Content-Transfer-Encoding: binary")
    sb.AppendLine("")
    uploadFileRequest = sb.ToString()
    Dim postDataBytes1 As Byte() = System.Text.Encoding.UTF8.GetBytes(uploadFileRequest)

    Dim postDataBytes2 As Byte() = System.Text.Encoding.UTF8.GetBytes(vbCrLf & "--" & _BoundaryText & "--" & vbCrLf)

    Dim len As Integer = postDataBytes1.Length + ImageData.Length + postDataBytes2.Length
    req.ContentLength = len

    Dim requestStream As System.IO.Stream = req.GetRequestStream()
    requestStream.Write(postDataBytes1, 0, postDataBytes1.Length)
    requestStream.Write(ImageData, 0, ImageData.Length)
    requestStream.Write(postDataBytes2, 0, postDataBytes2.Length)
    requestStream.Close()
    retVal = DirectCast(req.GetResponse(), HttpWebResponse)

    Return getWebResponseString(retVal)
End Function

''' <summary>
''' Returns the WebResponse as a string
''' </summary>
''' <param name="resp"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function getWebResponseString(resp As HttpWebResponse) As String
    Dim retVal As String
    Dim responseReader As New StreamReader(resp.GetResponseStream(), Encoding.UTF8)
    retVal = responseReader.ReadToEnd()
    resp.Close()
    Return retVal
End Function

''' <summary>
''' Processess the response from the API and returns a typed object of UploadSiteHostedPicture_APIResponse
''' </summary>
''' <param name="strResponse">The response string from the API</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function ProcessResponse(strResponse As String) As UploadSiteHostedPicture_APIResponse
    Dim retVal As New UploadSiteHostedPicture_APIResponse

    strResponse = strResponse.Replace("<?xml version='1.0' encoding='UTF-8'?>", "").Replace("<?xml version=""1.0"" encoding=""UTF-8""?>", "").Replace(" xmlns=""urn:ebay:apis:eBLBaseComponents""", "")
    retVal.FullResponse = strResponse

    Using stream = New StringReader(strResponse)
        Dim doc As XPathDocument = New XPathDocument(stream)
        Dim nav As XPathNavigator = doc.CreateNavigator()
        Dim strException As String = SCRIPT_NAME & " | ProcessResponse() | "
        'Check for successfull call
        nav = nav.SelectSingleNode("/UploadSiteHostedPicturesResponse")

        If (Not IsNothing(nav)) Then

            With retVal
                .APIStatus = getXPathValue(nav.SelectSingleNode("//Ack"))

                .ErrorMsgShort = getXPathValue(nav.SelectSingleNode("//ShortMessage")).ToString.Trim
                .ErrorMsgLong = getXPathValue(nav.SelectSingleNode("//LongMessage")).ToString.Trim
                If .APIStatus = "Failure" Then
                    .Success = False
                    .Errors = True
                    'Logging.Log(Logging.LogLevel.Warn, SCRIPT_NAME & " | ProcessResponse | API ERROR", New Exception("API Call Error - " & .ErrorMsgShort))
                Else
                    .Success = True
                    nav = nav.SelectSingleNode("//SiteHostedPictureDetails")
                    With .SiteHostedPictureDetail
                        .PictureSet = getXPathValue(nav.SelectSingleNode("PictureSet"))
                        .PictureFormat = getXPathValue(nav.SelectSingleNode("PictureFormat"))
                        .FullURL = getXPathValue(nav.SelectSingleNode("FullURL"))
                        .BaseURL = getXPathValue(nav.SelectSingleNode("BaseURL"))
                        .ExternalPictureURL = getXPathValue(nav.SelectSingleNode("ExternalPictureURL"))

                        Dim psm As XPathNodeIterator = nav.Select("PictureSetMember")
                        For Each node As XPathNavigator In psm
                            Dim NewPSM As New UploadSiteHostedPicture_APIResponse.SiteHostedPictureDetails.PictureSetMember()
                            With NewPSM
                                .MemberURL = getXPathValue(node.SelectSingleNode("MemberURL"))
                                .PictureHeight = cInt(getXPathValue(node.SelectSingleNode("PictureHeight")))
                                .PictureWidth = cInt(getXPathValue(node.SelectSingleNode("PictureWidth")))
                            End With
                            .PictureSetMembers.Add(NewPSM)
                        Next
                    End With
                End If
                .APICallStartTime = _APICallStartTime
                .APICallEndTime = _APICallEndTime
            End With

        End If

    End Using

    Return retVal
End Function

#End Region

#Region "Private Helper Functions"

''' <summary>
''' Gets the XPathValue
''' </summary>
''' <param name="strValue"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function getXPathValue(strValue As XPathNavigator) As String
    If (Not strValue Is Nothing) Then
        Return strValue.Value
    End If
    Return Nothing
End Function

#End Region

End Class

【讨论】:

  • 如果您有任何关于代码或优化的 cmets,请随时添加。如果您对代码有任何疑问,请告诉我。这是我们用于另一个包的类库。我不认为我们的其他图书馆有任何调用。我想我把它们都拿出来了。 “cint”是一个,如果代码不正确,请见谅。
猜你喜欢
  • 1970-01-01
  • 2013-03-24
  • 2021-09-14
  • 1970-01-01
  • 2019-07-06
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
相关资源
最近更新 更多