Как отправить запрос на загрузку файла изображения на сервер LINE с multipart / form-data для публикации изображения в LINE Notify? - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь опубликовать изображение с локального компьютера с помощью LINE Notify, но получаю неверный запрос, как отправить правильный запрос с помощью HttpWebRequest с типом содержимого multipart / form-data в vb.net?

Я пробовал cURL, и он просыпается:

curl -i -X POST https://notify-api.line.me/api/notify -H "Authorization: Bearer <TOKEN>" -F "message=test" -F "imageFile=@C:\PATH\to\file.jpg"

Вот что я сделал в vb.net:

Imports System.IO
Imports System.Net
Imports System.Security.Cryptography
Imports System.Text

Public Class Form1
    Private Sub btnPic_Click(sender As Object, e As EventArgs) Handles btnPic.Click
        OpenFileDialog1.Filter = "Image File (*.jpg)|*.jpg;*.JPG |Image File (*.png)|*.png;*.PNG"
        OpenFileDialog1.FileName = ""

        If OpenFileDialog1.ShowDialog() <> DialogResult.Cancel Then
            txtPic.Text = OpenFileDialog1.FileName
        End If
    End Sub

    Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
        ' [references]
        'https://notify-bot.line.me/doc/en/
        'http://white5168.blogspot.com/2017/01/line-notify-6-line-notify.html
        'https://aprico-media.com/posts/1824
        '/3914547/ispolzovanie-httpwebrequest-dlya-post-dannyh-zagruzki-izobrazhenii-s-ispolzovaniem-multipart-form-data

        Dim md5Hash As MD5 = MD5.Create()
        'Boundary string
        Dim strBound As String = "---------------------" & GetMd5Hash(md5Hash, CInt(Int((654321 * Rnd()) + 1))).Substring(0, 10)

        Try
            Dim request = DirectCast(WebRequest.Create("https://notify-api.line.me/api/notify"), HttpWebRequest)
            Dim postData As String = "--" & strBound & vbCrLf
            postData += "Content-Disposition: form-data; name=""message""" & vbCrLf & vbCrLf
            postData += txtText.Text & vbCrLf
            ' [Not working] sticker part
            'postData += "--" & strBound & vbCrLf
            'postData += "Content-Disposition: form-data; name=""stickerPackageId""" & vbCrLf & vbCrLf
            'postData += 1 & vbCrLf
            'postData += "--" & strBound & vbCrLf
            'postData += "Content-Disposition: form-data; name=""stickerId""" & vbCrLf & vbCrLf
            'postData += 2 & vbCrLf

            If txtPic.Text <> "" Then
                Dim ext As String = Path.GetExtension(txtPic.Text)
                If ext = ".jpg" Then
                    ext = "jpeg"
                ElseIf ext = ".png" Then
                    ext = "png"
                Else
                    MessageBox.Show("Sorry! LINE Notify supports only jpeg/png image file.")
                    btnPic.PerformClick()
                    Return
                End If
                ' [Not working] image part
                postData += "--" & strBound & vbCrLf
                postData += "Content-Disposition: form-data; name=""imageFile""; filename=""" & Path.GetFileName(txtPic.Text) & """" & vbCrLf
                postData += "Content-Type: image/" & ext & vbCrLf & vbCrLf
                postData += Convert.ToBase64String(File.ReadAllBytes(txtPic.Text)) & vbCrLf
            End If
            postData += vbCrLf & "--" & strBound & "--"
            Dim data = Encoding.UTF8.GetBytes(postData)

            request.Method = "POST"
            request.ContentType = "multipart/form-data; boundary=" & strBound
            request.ContentLength = data.Length
            request.Headers.Add("Authorization", "Bearer <TOKEN>")

            Using stream = request.GetRequestStream()
                stream.Write(data, 0, data.Length)
            End Using

            Dim response = DirectCast(request.GetResponse(), HttpWebResponse)
            Dim responseString = New StreamReader(response.GetResponseStream()).ReadToEnd()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
        End Try
    End Sub

    Shared Function GetMd5Hash(ByVal md5Hash As MD5, ByVal Input As String) As String

        ' Convert the input string to a byte array and compute the hash.
        Dim data As Byte() = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(Input))

        ' Create a new Stringbuilder to collect the bytes
        ' and create a string.
        Dim sBuilder As New StringBuilder()

        ' Loop through each byte of the hashed data 
        ' and format each one as a hexadecimal string.
        Dim i As Integer
        For i = 0 To data.Length - 1
            sBuilder.Append(data(i).ToString("x2"))
        Next i

        ' Return the hexadecimal string.
        Return sBuilder.ToString()

    End Function 'GetMd5Hash

End Class

Нет проблем с отправкой только «сообщения», когда другие части, т. Е. «ImageFile», «stickerPackageId», «stickerId», ..., объединяются с, в результате получается ошибка (400). Однако, если имя поля изменяется на маленькую букву, например «stickerpackageid», «stickerid» vb не будет перехватывать какие-либо исключения, а просто отправит «сообщение» для уведомления. Итак, я думаю, что неправильная часть должна быть в строке HTTP-запроса, или это нужно для преобразования каждого поля в двоичный массив? Если это так, как получить правильный результат?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...