【发布时间】:2011-11-01 14:16:57
【问题描述】:
将表单的 enctype 设置为“multipart/form-data”会导致 web 服务抛出异常。
System.InvalidOperationException:请求格式无效:multipart/form-data;边界=---......
我需要将 HTML 表单直接发布到 web 服务,它不能由 .NET 服务器托管。
任何想法...
提前致谢。
【问题讨论】:
将表单的 enctype 设置为“multipart/form-data”会导致 web 服务抛出异常。
System.InvalidOperationException:请求格式无效:multipart/form-data;边界=---......
我需要将 HTML 表单直接发布到 web 服务,它不能由 .NET 服务器托管。
任何想法...
提前致谢。
【问题讨论】:
请参阅RFC 1867 以了解多部分协议的含义。 您需要手动制作多部分“装饰”,此代码可能会有所帮助:
-(NSData *)makeMultipartDataWithBoundary:(NSString *) boundary
parameters:(NSDictionary *)parameters
formName:(NSString *)formName
fileName:(NSString *)fileName
fileType:(NSString *)fileType
fileData:(NSData*)fileData
{
NSMutableString * res = [NSMutableString stringWithFormat:@"--%@\r\n", boundary];
for(NSString * key in [parameters allKeys]){
NSString * value = [parameters objectForKey:key];
if(![value isMemberOfClass:[NSString class]]) continue;
[res appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", key];
[res appendFormat:@"\r\n%@\r\n", value];
[res appendFormat:@"--%@\r\n", boundary];
}
[res appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", formName, fileName];
[res appendFormat:@"Content-Type: %@\r\n\r\n", fileType];
NSMutableData * data= [NSMutableData data];
NSLog(@"%@", res);
[data appendData:[res dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:fileData];
[data appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
return data;
}
地点:
boundary 是一个 NSString(字节序列),它不会出现在 fileData 部分中。例如'D33pN16h7abcd'
parameters 是一个字典,包含要传递给多部分协议的所有标头参数。
formName 是一个标识符。
fileType 是 mime 文件类型,例如'图像/png'
最后fileData是文件内容的字节数。
下一行显示了调用此方法的示例:
- (void) sendAllData {
NSData *data;
data = [self makeMultipartDataWithBoundary:kBoundary
parameters:nil
formName:@"imageField" fileName:@"imageExample.png"
fileType:@"image/png"
fileData:self.imageData];
// Make a post NSURLConnection request with the data
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.org/file.php"]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:data];
[request addValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kBoundary] forHTTPHeaderField:@"Content-Type"]
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
receivedData = [[NSMutableData data] retain];
}
}
希望这会有所帮助! :)
【讨论】:
通过使用 SOAP 服务解决。最终工作代码如下:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *imageDataToSend = [[NSData alloc] initWithData:UIImageJPEGRepresentation(previewImageView_.image, 90)];
NSString *imgegeDataStr = [imageDataToSend base64EncodedString];
NSString *soapMsg = [[NSString alloc] initWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><SaveCampaignImage xmlns=\"http://tempuri.org/\"><CampaignImage>%@</CampaignImage><ImageName>image1</ImageName><CampaignID>4</CampaignID></SaveCampaignImage></soap:Body></soap:Envelope>",imgegeDataStr];
NSLog(@"soapMsg");
NSURL *url = [NSURL URLWithString:@"http://10.4.3.224/VerizonDealsWebService/Service1.asmx"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMsg length]];
[req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req addValue:@"http://tempuri.org/SaveCampaignImage" forHTTPHeaderField:@"SOAPAction"];
[req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
[req setHTTPMethod:@"POST"];
[req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection_ = [[NSURLConnection alloc] initWithRequest:req delegate:self];
[connection_ start];
[connection_ release];
[pool release];
【讨论】: