【发布时间】:2019-06-19 04:27:42
【问题描述】:
我正在尝试使用 LINE Notify 从本地发布图像,但收到错误请求,如何在 vb.net 中使用带有 multipart/form-data 内容类型的 HttpWebRequest 发送正确的请求?
我已经尝试过 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
'https://stackoverflow.com/questions/3890754/using-httpwebrequest-to-post-data-upload-image-using-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 将不会捕获任何异常,而只是将“消息”发送给 Notify。所以,我认为http请求字符串中应该有错误的部分,还是需要将每个字段转换为二进制数组?如果是这样,如何获得正确的结果?
【问题讨论】:
标签: vb.net multipartform-data line-api