2010-10-08 11 views
14

का उपयोग कर पोस्ट डेटा/अपलोड छवि के लिए HttpWebRequest का उपयोग करके मैं छवियों को अपलोड करने के लिए ImageShack API का उपयोग करने का प्रयास कर रहा हूं। इसका उपयोग करने के लिए, मुझे multipart/form-data का उपयोग कर छवि POST माना जाता है। मुझे यह पसंद था ...मल्टीपार्ट/फॉर्म-डेटा

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; 

लेकिन 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 मौजूद है और मैं multipart/form-data क्या गलत उपयोग कर रहा हूँ?

अद्यतन:

नए कोड http://pastebin.com/TN6e0CD8

डेटा पोस्ट http://pastebin.com/fYE9fsxs

अद्यतन 2

मैं अन्य प्रश्न Multipart forms from C# client को देखा। सीमा के साथ मेरे कोड को संशोधित किया, उम्मीद है कि 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(); 
} 
+1

के संभावित डुप्लिकेट काम करता है://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data) –

उत्तर

11

मुझे विश्वास है कि आप अनुरोध निकाय को सही तरीके से नहीं बना रहे हैं। सबसे पहले, आपको सामग्री प्रकार शीर्षलेख में भाग सीमा (यादृच्छिक पाठ) शामिल करने की आवश्यकता है। उदाहरण के लिए,

सामग्री-प्रकार: मल्टीपार्ट/फॉर्म-डेटा; सीमा = ---- WebKitFormBoundarySkAQdHysJKel8YBM तरह

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

कुछ

अब अनुरोध शरीर के प्रारूप हो जाएगा मैं तुम्हें समझने के लिए इन अनुरोधों निर्माण कर रहे हैं इस तरह के फ़िडलर के रूप में उपकरण का उपयोग करने का सुझाव देगा।

+0

मुझे यकीन नहीं है कि क्या मुझे अभी भी कुछ भी याद आया है, लेकिन मेरे अनुरोध डेटा के साथ [@pastebin] (http: // pastebin.com/vyqyG39A) पूर्ण कोड [पेस्टबिन] पर भी (http://pastebin.com/g1FDQnhH)। मुझे अभी भी एक ही त्रुटि मिलती है –

0

यह बहुखण्डीय/फार्म-डेटा

  1. की तरह कुछ भी नहीं है वहाँ क्षेत्रों के बीच कोई सीमा नहीं (एक क्षेत्र के साथ भी आवश्यक) है।
  2. आप बेस -64 एन्कोडिंग क्यों कर रहे हैं?
  3. छवि के सामग्री-प्रकार का कोई संकेत नहीं है।

वास्तविक प्रारूप spec के लिए आरएफसी 2388 पर एक नज़र डालें। वेब पेज से फ़ाइल अपलोड के फिडलर को पकड़ने के लिए यह उपयोगी भी हो सकता है।

+1

हां, विनयसी ने मुझे उस पर प्रकाश डाला। मैंने कोड संपादित किया और यह अब [@pastebin] (http://pastebin.com/TN6e0CD8) जैसा दिखता है। और जेनरेट किया गया पोस्ट डेटा इस तरह दिखता है ... [@pastebin] (http://pastebin.com/fYE9fsxs) –

+0

मूल्यों के बाद आने वाली न्यूलाइन की कोई आवश्यकता नहीं है। एपीआई के लिए विशिष्ट आवश्यकता बेस -64 है? यह असामान्य है, लेकिन मैं देख सकता था कि एपीआई इसके लिए कैसे पूछ सकता है। चूंकि बेस -64िंग मल्टीफार्म प्रारूप का हिस्सा नहीं है, जो आप भेज रहे हैं वह छवि/gif नहीं बल्कि टेक्स्ट/सादा है। इसके अलावा, जब तक न्यूलाइन सीआरएलएफ हैं, यह सही दिखता है। मैं सीमा के नामों को समाप्त करने की अनुशंसा करता हूं ----- क्योंकि यह जांचना कठिन होता है कि अंतिम एक समान है लेकिन अतिरिक्त के साथ - –

+0

मैं छवि को कैसे भेजूं? मैंने बेस 64 का इस्तेमाल किया जब मैंने देखा कि यह कहीं भी इस्तेमाल किया गया था। तो हो सकता है कि मैं इसे गलत कर रहा हूं –

11

मैं अंत में निम्न कोड के साथ मिल गया ...

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

सूचना सीमाओं -- {सीमा ContentType में घोषित} और न खत्म होने वाली सीमा के साथ शुरू -- साथ & अंत शुरू होगा की है।मेरे मामले में, मैं मूल रूप से इस्तेमाल किया

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

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

से बदलने और सब कुछ [साथ HttpWebRequest (बहुखण्डीय/फार्म-डेटा) फ़ाइलें अपलोड करें] (http

+0

यह वास्तव में सहायक था .. विशेष रूप से मैं फ़ाइल का नाम नहीं दे रहा था ... – Barun

+2

मैं नहीं करता देखें कि आप 'fileHeaderFormat' कहां उपयोग करते हैं या जहां आप फ़ाइल सामग्री जोड़ते हैं। क्या आप इसे भी जोड़ सकते हैं? –

+0

requestWriter.Write (string.Format (fileHeaderFormat, "image", myImage.FileName, myImage.ContentType)); requestWriter.Flush(); requestStream.Write (myImageAsByteArray, 0, (myImageAsByteArray.Length); तो आप requestWriter के अनुरोध पर तार लिखते हैं लेकिन फिर सीधे अपने बाइट [] लिखें। –