2009-12-09 10 views
12

मैं एक फ़ाइल अपलोड करने की कोशिश कर रहा हूं और .NET/C# का उपयोग करके मेरी साइट पर कुछ पैरामीटर के साथ भेज रहा हूं। कुछ ट्यूटोरियल पढ़ने के बाद जो कुछ पैरामीटर या फ़ाइल करते हैं, मैंने कोशिश की है, असफल, उन्हें गठबंधन करने के लिए। यहाँ कैसे मैं इसे करने का प्रयास है:फ़ाइल और पैरामीटर दोनों के साथ WebRequest POST

WebRequest req = WebRequest.Create(baseURL + "upload"); 
req.Credentials = new NetworkCredential(username, password); 
String boundary = "B0unD-Ary"; 
req.ContentType = "multipart/form-data; boundary=" + boundary; 
req.Method = "POST"; 
((HttpWebRequest)req).UserAgent = "UploadTester v0.1"; 

string postData = "--" + boundary + "\nContent-Disposition: form-data\n"; 
postData += "myId=123&someFk=456"; 
postData += "\n--" + boundary + "\nContent-Disposition: form-data; name=\"file\" filename=\"upload.pdf\" Content-Type: application/pdf\n\n"; 
byte[] byteArray = Encoding.UTF8.GetBytes(postData); 

byte[] filedata = null; 
using (BinaryReader reader = new BinaryReader(File.OpenRead("myfile.pdf"))) 
    filedata = reader.ReadBytes((int)reader.BaseStream.Length); 

req.ContentLength = byteArray.Length + filedata.Length; 
req.GetRequestStream().Write(byteArray, 0, byteArray.Length); 
req.GetRequestStream().Write(filedata, 0, filedata.Length); 

WebResponse response = req.GetResponse(); 
Stream data = response.GetResponseStream(); 
StreamReader sReader = new StreamReader(data); 
String sResponse = sReader.ReadToEnd(); 
response.Close(); 

जब मैंने इसे निष्पादित, मैं एक 500 अपवाद कहा, "हेडर अनुभाग से अधिक 10240 bnytes (शायद यह ठीक से समाप्त नहीं किया जाता है) है" और Wireshark मुझे उस को सूचित भेजा गया अनुरोध एक विकृत पैकेज था, जहां एमआईएमई मल्टीपार्ट विकृत था।

संभवतः कई मुद्दों यहाँ हैं, इसलिए मुझे सभी समस्याओं को आप पहचान सकते हैं हमें बताएं

अद्यतन:। सी #/नेट से माइम अलग करने के लिए, मैं पैदा किया है यहाँ एक धागा: https://stackoverflow.com/questions/1880002/error-in-mime-packet-for-http-post

अपडेट 2: तो बैकएंड में वास्तव में सामग्री-लंबाई के साथ समस्याएं हैं, यह कहकर कि पढ़ने के लिए उपलब्ध बाइट्स की मात्रा निर्दिष्ट सामग्री-लंबाई से छोटी है। परंतु! यदि मैं req.ContentLength में सामग्री-लंबाई को कम करता हूं, तो मेरे पास डेटा भेजने के लिए पर्याप्त बफर आकार नहीं है। कोई सुझाव?

अद्यतन 3: वास्तव में, यह कितना डेटा शामिल

+0

यदि आप .NET> = 4.0 का उपयोग कर रहे हैं तो ऐसा करने के लिए एक आसान तरीका के लिए मेरे उत्तर पर छोड़ दें। – Joshcodes

उत्तर

11

समस्या यह है कि आप एक '\ n' भूल रहे है साथ पोस्ट की जांच की हैं होने के लिए। निम्न पंक्ति:

string postData = "--" + boundary + "\nContent-Disposition: form-data\n"; 

होना चाहिए:

string postData = "--" + boundary + "\nContent-Disposition: form-data\n\n"; 

और इस लाइन:

postData += "\n--" + boundary + "\nContent-Disposition: form-data; name=\"file\" filename=\"upload.pdf\" Content-Type: application/pdf\n\n" 

से पहले 'सामग्री-प्रकार' एक '\ n' याद आ रही है। यह होना चाहिए:

string postData = "--" + boundary + "\nContent-Disposition: form-data\n"; 

बदलने के लिए

postData += "\n--" + boundary + "\nContent-Disposition: form-data; name=\"file\" filename=\"upload.pdf\"\nContent-Type: application/pdf\n\n" 
+3

कहां समाप्त होता है। डिबगिंग के 15 घंटों के बाद, मुझे मुख्य समस्या मिली: .NET इंजन मेरी सभी न्यूलाइनों को सीआर + न्यूलाइन में अनुवाद करता है, इस प्रकार सामग्री-लंबाई में निर्दिष्ट किए गए बाइट्स को लिखता है। इसलिए, भविष्य में किसी भी समस्या के लिए: सीआर + न्यूलाइन (\ n से \ r \ n) – niklassaers

+0

के साथ सभी न्यूलाइनों को प्रतिस्थापित करें, जिसका उपयोग मैं मल्टीपार्ट प्राप्त कर रहा हूं: अंतिम सीमा अपेक्षित है? उस मुद्दे को हल करने के बारे में कोई विचार? –

1

मुझे लगता है कि तात्कालिक समस्या की घोषणा की और वास्तविक लंबाई के बीच एक बेमेल है की तुलना में लग रहा है हेडर की तरह एक बहुत बड़ा आकार है।

आपने गलत अनुमान लगाया था, मुझे यकीन नहीं है, लेकिन अगर मुझे सही याद है तो लंबाई में पहली पंक्ति को छोड़कर प्रतिक्रिया के प्रत्येक बाइट (हेडर समेत) शामिल होना चाहिए।

यकीन है कि मैं एक साधारण html पृष्ठ पोस्ट आप चाहते हैं उत्पन्न करने के लिए निर्माण और फ़िडलर (या फ़ायरबग)

+0

आह, धन्यवाद, यह एक अच्छा संकेत है। यह एक दयालुता है कि मुझे इसे हाथ से करना है। मुझे यकीन है कि हजारों लोगों ने इस तरह कोड लिखा है, एक मानक पुस्तकालय के साथ आसान होगा। – niklassaers

+0

हम्म, लेकिन मेरी सामग्री लंबाई ठीक से 12 9 5 9 7 बाइट्स पर सेट है, 10240 के पास कहीं भी नहीं।: -I – niklassaers

+0

अनुरोध स्ट्रीम को लिखने के बजाय, मैं इसे एक फाइलस्ट्रीम में लिखूंगा, और देख सकता हूं कि कितने बाइट हैं, और सुनिश्चित करें कि सामग्री लंबाई मिलान करता है। या वैकल्पिक रूप से, मेमोरीस्ट्रीम में लिखें, फिर आप मेमोरीस्ट्रीम.ToArra() कर सकते हैं और उस से सामग्री की लंबाई प्राप्त कर सकते हैं। – feroze

0

कोशिश

string postData = "\n\n--" + boundary + "\nContent-Disposition: form-data\n\n"; 

को और बेहतर भी की जगह सभी \ n \ करने के लिए r \ n। कम से कम पहले दो न्यूलाइन ने मुझे हल करने के लिए काम किया "हेडर सेक्शन में 10240 बाइट्स से अधिक है (शायद इसे ठीक से समाप्त नहीं किया गया है)" समस्या।

और यह कोड सही नहीं लगती है:

NSMutableData *reqData = [NSMutableData data]; 
NSURL *encUrl; 
encUrl = [NSURL URLWithString:[NSString url]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:encUrl]; 
request.HTTPMethod = @"POST"; 
request.timeoutInterval = kServerConnectionTimeout; 
    NSString *stringBoundary = [NSString stringWithString:@"Multipart-Boundary"]; // TODO - randomize this 
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=\"%@\"",stringBoundary]; 
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 

[reqData appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
for (id key in [self.parameters allKeys]) 
{ 
    if (![key isEqualToString:@"image"]) 
    { 
     NSString *val = [self.parameters objectForKey:key]; 
     if (val != nil) 
     { 
      [reqData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]]; 
      [reqData appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
      [reqData appendData:[[NSString stringWithFormat:@"Content-Transfer-Encoding: 8bit\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
      [reqData appendData:[[NSString stringWithFormat:@"%@",val] dataUsingEncoding:NSUTF8StringEncoding]]; 
      [reqData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
     } 
    } 
} 

// send binary part last 
if ([self.parameters objectForKey:@"image"]) 
{ 
    NSString *key = @"image"; 
    NSData *imageData = [self.parameters objectForKey:key]; 
    if (imageData != nil) 
    { 
     [reqData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\";filename=\"avatar.png\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
     [reqData appendData:[[NSString stringWithFormat:@"Content-Type: image/png\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 

     [reqData appendData:[[NSString stringWithFormat:@"Content-Transfer-Encoding: binary\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
     [reqData appendData:imageData]; 
     [reqData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    } 
} 
NSString * dataLength = [NSString stringWithFormat:@"%d", [reqData length]]; 
[request addValue:dataLength forHTTPHeaderField:@"Content-Length"]; 

request.HTTPBody = reqData; 
NSLog(@"postBody=%@", [[NSString alloc] initWithData:reqData encoding:NSASCIIStringEncoding]); 

आशा इस मदद करता है:

postData += "myId=123&someFk=456"; 

जो मैं उपयोग कर रहा हूँ और जो iPhone एप्लिकेशन के लिए मेरा उद्देश्य सी कोड अब काम करता है इस तरह दिखता है कोई।

संबंधित मुद्दे