webentwicklung-frage-antwort-db.com.de

Verwenden von HttpWebRequest to POST Daten-/Upload-Image mit Multipart-/Formulardaten

Ich versuche, die ImageShack-API zum Hochladen von Bildern zu verwenden. Um es zu benutzen, soll ich POST das Bild mit multipart/form-data verwenden. Ich habe es gerne gemacht ...

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;

aber ImageShack beschwert sich darüber 

<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 ist vorhanden und ich verwende multipart/form-data was ist falsch?

UPDATE:  

Neuer Code http://Pastebin.com/TN6e0CD8

Posten Sie Daten http://Pastebin.com/fYE9fsxs

UPDATE 2

ich schaute auf die andere Frage Multipart-Formulare von C # -Client . Code mit Begrenzung geändert, den Expect-100-Header entfernt. Ich kann ihn nicht zum Laufen bringen ... 

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();
}
14
Jiew Meng

Ich glaube, dass Sie den Anfragetext nicht korrekt erstellen. Zuerst müssen Sie Teilbegrenzungen (zufälligen Text) in den Inhaltstypheader aufnehmen. Zum Beispiel,

Inhaltstyp: Multipart/Formulardaten; Border = ---- WebKitFormBoundarySkAQdHysJKel8YBM

Jetzt wird das Format des Anfragetextes ungefähr so ​​aussehen 

------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]

Ich werde Ihnen vorschlagen, ein Tool wie Fiddler zu verwenden, um zu verstehen, wie diese Anforderungen erstellt werden.

11
VinayC

Ich habe es endlich mit folgendem Code bekommen ... 

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();
}

Hinweis-Begrenzungen müssen mit -- {in ContentType deklarierte Grenze} beginnen, und die Endbegrenzung muss mit -- beginnen und enden. In meinem Fall habe ich ursprünglich verwendet

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

ersetze es mit 

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

und alles funktioniert

11
Jiew Meng

Dies ist nicht vergleichbar mit Multipart/Form-Daten

  1. Es gibt keine Grenzen zwischen Feldern (auch bei einem Feld erforderlich).
  2. Warum sind Sie eine Base-64-Codierung?
  3. Es gibt keinen Hinweis auf den Inhaltstyp des Bildes.

Schauen Sie sich RFC 2388 für das tatsächliche Format an. Es kann auch nützlich sein, einen Fiddler-Zugriff auf einen Datei-Upload von einer Webseite aus zu betrachten.

0
Jon Hanna