简体   繁体   English

使用HttpWebRequest使用multipart / form-data POST数据/上传图像

[英]Using HttpWebRequest to POST data/upload image using multipart/form-data

I am trying to use the ImageShack API to upload images. 我正在尝试使用ImageShack API上传图像。 To use it, I am supposed to POST the image using multipart/form-data . 要使用它,我应该使用multipart/form-data POST图像。 I did it like ... 我这样做...

var postData = "";
var req = HttpWebRequest.Create("http://www.imageshack.us/upload_api.php");
req.Method = "POST";
req.ContentType = "multipart/form-data";
postData += "key=my_key_here&";
postData += "type=base64&";

// get base64 data from image
byte[] bytes = File.ReadAllBytes(@"D:\tmp\WpfApplication1\WpfApplication1\Images\Icon128.gif");
string encoded = Convert.ToBase64String(bytes);
postData += "fileupload=" + encoded;

byte[] reqData = Encoding.UTF8.GetBytes(postData);
using (Stream dataStream = req.GetRequestStream())
{
    dataStream.Write(reqData, 0, reqData.Length);
}

var res = (HttpWebResponse)req.GetResponse();
var resStream = res.GetResponseStream();
var reader = new StreamReader(resStream);
string resString = reader.ReadToEnd();
txt1.Text = resString;

but ImageShack is complaining that 但ImageShack抱怨说

<links>
    <error id="parameter_missing">Sorry, but we've detected that unexpected data is received. Required parameter 'fileupload' is missing or your post is not multipart/form-data</error>
</links>

FileUpload is present and I am using multipart/form-data whats wrong? FileUpload存在,我使用multipart/form-data什么错了?

UPDATE: 更新:

New Code http://pastebin.com/TN6e0CD8 新代码http://pastebin.com/TN6e0CD8

Post data http://pastebin.com/fYE9fsxs 发布数据http://pastebin.com/fYE9fsxs

UPDATE 2 更新2

i looked at the other question Multipart forms from C# client . 从C#客户端查看了另一个Multipart表单问题。 modified my code with boundary, removed the expect 100 header still i cant get it working ... 用边界修改我的代码,删除了期望的100标题仍然无法让它工作...

ServicePointManager.Expect100Continue = false;
var boundary = "-----------------------------28520690214962";
var newLine = Environment.NewLine;
var propFormat = boundary + newLine +
                    "Content-Disposition: form-data; name=\"{0}\"" + newLine + newLine + 
                    "{1}" + newLine + newLine;
var fileHeaderFormat = boundary + newLine +
                        "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + newLine;

var req = (HttpWebRequest)HttpWebRequest.Create("http://jm/php/upload.php");
req.Method = WebRequestMethods.Http.Post;
req.ContentType = "multipart/form-data; boundary=" + boundary;

using (var reqStream = req.GetRequestStream()) {
    var reqWriter = new StreamWriter(reqStream);
    var tmp = string.Format(propFormat, "str1", "hello world");
    reqWriter.Write(tmp);
    tmp = string.Format(propFormat, "str2", "hello world 2");
    reqWriter.Write(tmp);
    reqWriter.Write(boundary + "--");
    reqWriter.Flush();
}
var res = req.GetResponse();
using (var resStream = res.GetResponseStream()) {
    var reader = new StreamReader(resStream);
    txt1.Text = reader.ReadToEnd();
}

I believe that you are not building the request body correctly. 我相信您没有正确构建请求正文。 First, you need to include part boundary (random text) in content type header. 首先,您需要在内容类型标题中包含部分边界(随机文本)。 For example, 例如,

Content-Type: multipart/form-data; 内容类型:multipart / form-data; boundary=----WebKitFormBoundarySkAQdHysJKel8YBM 边界= ---- WebKitFormBoundarySkAQdHysJKel8YBM

Now format of request body will be something like 现在请求体的格式就像

------WebKitFormBoundarySkAQdHysJKel8YBM 
Content-Disposition: form-data;name="key"

KeyValueGoesHere
------WebKitFormBoundarySkAQdHysJKel8YBM 
Content-Disposition: form-data;name="param2"

ValueHere
------WebKitFormBoundarySkAQdHysJKel8YBM 
Content-Disposition: form-data;name="fileUpload"; filename="y1.jpg"
Content-Type: image/jpeg 

[image data goes here]

I will suggest you to use tool such as Fiddler to understand how these requests are built. 我建议你使用Fiddler这样的工具来理解这些请求是如何构建的。

I finally got it with the following code ... 我终于得到了以下代码......

var boundary = "------------------------" + DateTime.Now.Ticks;
var newLine = Environment.NewLine;
var propFormat = "--" + boundary + newLine +
                    "Content-Disposition: form-data; name=\"{0}\"" + newLine + newLine + 
                    "{1}" + newLine;
var fileHeaderFormat = "--" + boundary + newLine +
                        "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + newLine;

var req = (HttpWebRequest)HttpWebRequest.Create("http://jm/php/upload.php");
req.Method = WebRequestMethods.Http.Post;
req.ContentType = "multipart/form-data; boundary=" + boundary;

using (var reqStream = req.GetRequestStream()) {
    var reqWriter = new StreamWriter(reqStream);
    var tmp = string.Format(propFormat, "str1", "hello world");
    reqWriter.Write(tmp);
    tmp = string.Format(propFormat, "str2", "hello world 2");
    reqWriter.Write(tmp);
    reqWriter.Write("--" + boundary + "--");
    reqWriter.Flush();
}
var res = req.GetResponse();
using (var resStream = res.GetResponseStream()) {
    var reader = new StreamReader(resStream);
    txt1.Text = reader.ReadToEnd();
}

Notice boundaries have to begin with -- {boundary declared in ContentType} and ending boundary must begin & end with -- . 注意边界必须以-- {在ContentType中声明的边界}开始,结束边界必须以--开头和结尾。 in my case, I originally used 在我的情况下,我最初使用

var propFormat = boundary + newLine +
                    "Content-Disposition: form-data; name=\"{0}\"" + newLine + newLine + 
                    "{1}" + newLine;

replace it with 用它替换它

var propFormat = "--" + boundary + newLine +
                    "Content-Disposition: form-data; name=\"{0}\"" + newLine + newLine + 
                    "{1}" + newLine;

and everything works 一切正常

This is nothing like multipart/form-data 这与multipart / form-data完全不同

  1. There's no boundaries between fields (needed even with one field). 字段之间没有边界(甚至需要一个字段)。
  2. Why are you base-64 encoding? 为什么你的base-64编码?
  3. There's no indication of the content-type of the image. 没有迹象表明图像的内容类型。

Take a look at RFC 2388 for the actual format spec. 看一下RFC 2388的实际格式规范。 It can also be useful to look at a Fiddler grab of a file upload from a web-page. 从网页上查看文件上传的Fiddler抓取也很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用HttpWebRequest上传文件(multipart / form-data) - using HttpWebRequest upload file (multipart/form-data) 使用 Python 通过 POST 多部分表单数据上传文件 - Upload file via POST multipart form-data using Python 使用多部分/表单数据上传文件 - File upload using multipart/form-data 通过 POST 方法上传图片 multipart/form-data - Upload image multipart/form-data via POST method 使用HTTPWebrequest(multipart / form-data)发布文件时出现错误(从客户端检测到潜在的Request.Form值) - Post a file using HTTPWebrequest (multipart/form-data) gives an error (A potentially dangerous Request.Form value was detected from the client) 如何在C#的multipart / form-data中使用HttpWebRequest多次发布相同的参数名称? - How can we post same parameter name multiple times using HttpWebRequest in multipart/form-data in C#? 如何在Restsharp中使用multipart / form-data上传XML文件? - How to upload an XML file using multipart/form-data with Restsharp? 在C#中使用RestClient作为多部分/表单数据上传文件 - Upload File using RestClient as multipart/form-data in c# 使用RestSharp在multipart / form-data POST中包含文件的问题 - Trouble including a file in multipart/form-data POST using RestSharp 使用RestSharp发送HTTP POST Multipart / form-data字段 - Sending HTTP POST Multipart/form-data field using RestSharp
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM