Отсутствует вложение XML-запроса

Я пытаюсь загрузить изображение на сервер eBay с помощью вызова API UploadSiteHostedPictures.

Вызов позволяет отправлять либо URL-адрес, либо двоичные данные. Для моего приложения я решил использовать последний, чтобы обойти проблему, вызванную невозможностью чтения eBay данных через HTTPS.


Мой запрос

Заголовки

  • Content-Type: multipart/form-data; border=abcdefghijklmnopqrstuv0987654321
  • X-EBAY-API-DEV-NAME: DEV_NAME
  • X-EBAY-API-ИМЯ-ПРИЛОЖЕНИЯ: APP_NAME
  • X-EBAY-API-CERT-NAME: CERT_NAME
  • X-EBAY-API-SITEID: SITEID
  • УРОВЕНЬ СОВМЕСТИМОСТИ С X-EBAY-API: 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>

person user1371414    schedule 08.05.2014    source источник
comment
У вас когда-нибудь это работало?? Я пытаюсь использовать тот же вызов, чтобы опубликовать данные файла изображения или просто указать URL-адрес удаленного изображения. На самом деле мне нужно, чтобы оба работали, но у меня одно и то же сообщение об ошибке. Если у вас это получилось, не могли бы вы опубликовать свой код .net. Большое спасибо   -  person Ads    schedule 22.04.2015
comment
Я так и не продвинулся в решении этой проблемы, но вот пример PHP, который я нашел по пути: ebaydts.com /eBayKBDetails?KBid=1092   -  person user1371414    schedule 23.04.2015


Ответы (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
person Ads    schedule 22.04.2015
comment
Если у вас есть какие-либо комментарии по поводу кода или оптимизации, не стесняйтесь добавлять их. Если у вас есть какие-либо вопросы о коде, дайте мне знать. Это из библиотеки классов, которую мы используем для другого пакета. Я не думаю, что есть какие-либо звонки в другие наши библиотеки. Я думаю, что вытащил их всех. Цинт был один, так что извините, если этот код неверен. - person Ads; 24.04.2015