WebRequest POST同时包含文件和参数

我正在尝试使用.NET / C#上传文件并将一些参数发送到我的网站。 阅读了一些做了一些参数或文件的教程后,我尝试过,但没有成功地将它们组合起来。 以下是我尝试这样做的方法:

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

当我执行它时,我得到500exception,说“标题部分有超过10240个bnytes(可能没有正确终止)”,Wireshark通知我发送的请求是格式错误的包,其中MIME多部分格式错误。

这里可能有几个问题,所以请告诉我你能发现的所有问题

更新 :要将MIME与C#/ .NET分开,我在这里产生了一个post: https : //stackoverflow.com/questions/1880002/error-in-mime-packet-for-http-post

更新2 :因此后端确实存在内容长度问题,表示可用于读取的字节数小于指定的内容长度。 但! 如果我相应地减少req.ContentLength中的内容长度,我没有足够大的缓冲区大小来发送数据。 有什么建议?

更新3 :实际上,与包含的数据量相比,标题的大小看起来太大了

问题是你错过了’\ 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" 

在’Content-Type’之前缺少’\ n’。 它应该是:

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

我想直接问题是声明长度和实际长度之间的不匹配。

你在哪里算错了我不确定,但如果我没记错,长度应该包括响应的每个字节(包括标题),第一行除外。

为了确保我会构建一个简单的html页面来生成你想要的post并用fiddler(或firebug)检查post

试着改变

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

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

最好还将\ n全部替换为\ r \ n。 至少前两个新行为我解决了“Header部分超过10240字节(可能没有正确终止)”的问题。

这段代码看起来不正确:

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

我正在使用的iPhone应用程序的目标-c代码现在可以使用:

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

希望这有助于某人。