使用SOAP将使用WCF服务的图像从iPhone上传到服务器

hiii,我使用wcf SOAP服务为我的应用程序,我发送下面的请求。

postStr = [NSString stringWithFormat:@"<?xml version=\"1.0\"?>\n" "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" "<s:Body>\n" "<InsUpdDelActivityInfo xmlns=\"http://tempuri.org/\">\n" "<objEventsContent xmlns:d4p1=\"http://schemas.datacontract.org/2004/07/iCampuslite.Model.ActivityStream\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\n" "<d4p1:ActCommentId i:nil=\"true\" />\n" "<d4p1:ActSubTypeCd i:nil=\"true\" />\n" "<d4p1:ActType>Status</d4p1:ActType>\n" "<d4p1:ActTypeCd>1</d4p1:ActTypeCd>\n" "<d4p1:ActivityAnswersList />\n" "<d4p1:ActivityComments />\n" "<d4p1:ActivityId i:nil=\"true\" />\n" "<d4p1:ActivityLike />\n" "<d4p1:ActivityName>%@</d4p1:ActivityName>\n" "<d4p1:ActivityStreamImagesBytes>%@</d4p1:ActivityStreamImagesBytes>\n" "<d4p1:AnswerDesc i:nil=\"true\" />\n" "<d4p1:AnswerId>0</d4p1:AnswerId>\n" "<d4p1:CommentDesc i:nil=\"true\" />\n" "<d4p1:CommentId i:nil=\"true\" />\n" "<d4p1:CreatedUserId>%@</d4p1:CreatedUserId>\n" "<d4p1:CreatedUserName i:nil=\"true\" />\n" "<d4p1:FileOrLinkName i:nil=\"true\" />\n" "<d4p1:IsLiked>0</d4p1:IsLiked>\n" "<d4p1:IsTotalSchool i:nil=\"true\" />\n" "<d4p1:LikeCount>0</d4p1:LikeCount>\n" "<d4p1:LinkImage i:nil=\"true\" />\n" "<d4p1:ObjTypeCdId i:nil=\"true\" />\n" "<d4p1:ObjTypeId i:nil=\"true\" />\n" "<d4p1:OperationMode>I</d4p1:OperationMode>\n" "<d4p1:OperationType i:nil=\"true\" />\n" "<d4p1:OperationTypeId i:nil=\"true\" />\n" "<d4p1:OrganizationId>%@</d4p1:OrganizationId>\n" "<d4p1:OtherActivityId i:nil=\"true\" />\n" "%@\n" "</objEventsContent>\n" "<ismobile>true</ismobile>\n" "</InsUpdDelActivityInfo>\n" "</s:Body>\n" "</s:Envelope>", statusText, [appDelegateObj.loginUserInfoDict valueForKey:@"a:UserId"], [appDelegateObj.loginUserInfoDict valueForKey:@"a:OrgId"], workspaceStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@iCampusliteMobileService/ActivityStreamSl.svc", appDelegateObj.baseURL]]]; NSString *messageLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postStr length]]; [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request addValue:@"http://tempuri.org/IActivityStreamSl/InsUpdDelActivityInfo" forHTTPHeaderField:@"SOAPAction"]; [request addValue:messageLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; NSError *error = nil; NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; 

在上面的请求中有一个ActivityStreamImagesBytes元素,它是我必须传递图像的base64binary参数。

我试过使用很多不同的格式。

这里是wcf服务的截图 这里

这里是服务器端代码

 public string byteArrayToImage(byte[] byteArrayIn,string fileName) { if (byteArrayIn != null) { ActivityStreamSl.LogMsg("Byte Array Count : "+byteArrayIn.Length.ToString(), "D:\\log.txt"); var serverfile = "D:somepath\somepath\somefolder"; var getfile = HelperClass.Filesavehelper(Constants.UploadPaths.ActivityStream, "testfilename.png", serverfile); FileStream file = new FileStream(getfile, FileMode.Create); file.Write(byteArrayIn, 0, byteArrayIn.Length); file.Close(); file.Dispose(); return getfile; } else { ActivityStreamSl.LogMsg("Byte array is null","D:\\log.txt"); } return ""; } 

服务器期待一个字节数组,我不知道如何发送它? 而我不知道什么是base64binary数据types是? 我必须发送base64编码的string或字节数组或仅从NSData *data = UIImageJPEGRepresentation([UIImage imageNamed:@"popular.png"], 0.7);的图像NSData *data = UIImageJPEGRepresentation([UIImage imageNamed:@"popular.png"], 0.7);

任何帮助是可观的

WCF服务明确要求base64binary,所以你必须发送它在base64binary只。

base64binary不过是base64编码的二进制数据

1)使用下面的代码片段将图像转换为二进制

 NSData *binaryImageData = UIImageJPEGRepresentation([UIImage imageNamed:@"Photo.png"], 0.0); 

2)将二进制编码成base64格式

这里是我用来处理base64二进制和UIImage的类

  @interface base64BinaryandImagehandler:NSObject +(NSString *) base64BinaryStringFromBinaryData: (NSData *)data length: (int)length; +(UIImage*)Base64BinaryToImage:(NSString *)Base64; @end @implementation base64BinaryandImagehandler:NSObject static char base64EncodingTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; +(NSString *) base64BinaryStringFromBinaryData: (NSData *)data length: (int)length{ unsigned long ixtext, lentext; long ctremaining; unsigned char input[3], output[4]; short i, charsonline = 0, ctcopy; const unsigned char *raw; NSMutableString *result; lentext = [data length]; if (lentext < 1) return @""; result = [NSMutableString stringWithCapacity: lentext]; raw = [data bytes]; ixtext = 0; while (true) { ctremaining = lentext - ixtext; if (ctremaining <= 0) break; for (i = 0; i < 3; i++) { unsigned long ix = ixtext + i; if (ix < lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] & 0xFC) >> 2; output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4); output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6); output[3] = input[2] & 0x3F; ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i < ctcopy; i++) [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]]; for (i = ctcopy; i < 4; i++) [result appendString: @"="]; ixtext += 3; charsonline += 4; if ((length > 0) && (charsonline >= length)) charsonline = 0; } return result; } +(UIImage*)Base64BinaryToImage:(NSString *)Base64{ NSString* base64String=[[NSString alloc]initWithFormat:@"data:image/png;base64,%@",Base64]; NSURL *base64url = [NSURL URLWithString:base64String]; NSData *imageData = [NSData dataWithContentsOfURL:base64url]; UIImage *img=[UIImage imageWithData:imageData]; return img; } @end 

这里是将二进制转换为base64binary的方法

 NSString *Base64Binary=[base64BinaryandImagehandler base64BinaryStringFromBinaryData:binaryImageData length:binaryImageData.length]; 

你也可以在这里find更多的信息

这里是C#中的base64编码和解码部分

 public static string Base64Encode(string plainText) { var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); return System.Convert.ToBase64String(plainTextBytes); } public static string Base64Decode(string base64EncodedData) { var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); } 

无论如何,你可以忽略关于C#部分,因为你只做iPhone部分。

你可以使用下面的链接来testing你的编码base 64是否合适。

base64toimage转换器

更新1这是确认收到的string是否为base64格式的代码

  private bool IsBase64String(string str){ try{ // If not exception is caught, then it is a base64 string MemoryStream stream = new MemoryStream(Convert.FromBase64String(str)); return true; } catch{ // If exception is caught, then I assumed it is a normal string return false; } } 

参考

下面的代码将在Images文件夹下为给定的到达的base64数据文件名例如duraiamuthan.jpg)创build一个图像,并返回图像path,以便您可以在数据库中更新它(它将检查是否到达数据是在base64或二进制[WCF框架的情况下,将base64内部转换为二进制])

  public string Getpath_CreateImageFromEncodedData(string Base64EncodedData, string fileName) { string fileHandle = ""; try { if(IsBase64String(Base64EncodedData)) byte[] imageBytes = Convert.FromBase64String(Base64EncodedData); else byte[] imageBytes= Base64EncodedData; MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length); ms.Write(imageBytes, 0, imageBytes.Length); fileHandle = System.Web.HttpContext.Current.Server.MapPath("Images/" + fileName); FileStream fsObj = new FileStream(fileHandle, FileMode.Create, FileAccess.Write); ms.WriteTo(fsObj); fsObj.Close(); ms.Close(); return fileHandle; } catch (Exception ex) { return ""; } } 

更新2 (用于超时问题)

  • NSURLRequest和NSMutableURLRequest的默认超时时间是60秒,具体取决于互联网连接,networking服务器上的互联网stream量传输,ImageCreating时间以及所有这些可能不够用。因此,您可以设置比使用以下语法更高的值[urlReqObj setTimeoutInterval:180]; 超时间隔仅以秒为单位。

  • 在IIS中增加ConnectionTimeout默认值是120秒,如果请求中的请求队列太多的话会失败。增加ConnectionTimeOut会有帮助。(这个超时也是连接的空闲时间)。在IIS高级设置中点击你service in IIS Manager -> Advanced Settings -> Connection Limitsservice in IIS Manager -> Advanced Settings -> Connection Limits ,在那里你可以设置超时,或者你可以简单地覆盖web.config的连接超时。

  • Keep-alive in IIS启用Keep-alive in IIS以便重复使用相同的连接,从而提高IIS的效率。 service in IIS Manager -> Advanced Settings -> Connection Limits -> Enable HTTP Keep-Alives单击您的service in IIS Manager -> Advanced Settings -> Connection Limits -> Enable HTTP Keep-Alives

  • 如果您打算将图像的二进制文件存储在DB中,则可以增加connectiontimeoutstring中的数据库connectiontimeout connectionstring或者可以增加sqlcommandtimeout

希望这可以帮助。 随意问你是否有任何疑问

嗨,我有我的问题是

在服务器端,它期待一个字节数组,

所以,我要发送我的请求如下。

将base64string转换为字节数组

 postStr = [NSString stringWithFormat:@"<?xml version=\"1.0\"?>\n" "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" "<s:Body>\n" "<InsUpdDelActivityInfo xmlns=\"http://tempuri.org/\">\n" "<objEventsContent xmlns:d4p1=\"http://schemas.datacontract.org/2004/07/iCampuslite.Model.ActivityStream\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\n" "<d4p1:ActCommentId i:nil=\"true\" />\n" "<d4p1:ActSubTypeCd i:nil=\"true\" />\n" "<d4p1:ActType>Status</d4p1:ActType>\n" "<d4p1:ActTypeCd>1</d4p1:ActTypeCd>\n" "<d4p1:ActivityAnswersList />\n" "<d4p1:ActivityComments />\n" "<d4p1:ActivityId i:nil=\"true\" />\n" "<d4p1:ActivityLike />\n" "<d4p1:ActivityName>%@</d4p1:ActivityName>\n" "<d4p1:ActivityStreamImagesBytes dt: dt:"Base64Binary"><dt:length>%d</dt:length><dt:byte>%@</dt:byte>......................................</d4p1:ActivityStreamImagesBytes>\n" "<d4p1:AnswerDesc i:nil=\"true\" />\n" "<d4p1:AnswerId>0</d4p1:AnswerId>\n" "<d4p1:CommentDesc i:nil=\"true\" />\n" "<d4p1:CommentId i:nil=\"true\" />\n" "<d4p1:CreatedUserId>%@</d4p1:CreatedUserId>\n" "<d4p1:CreatedUserName i:nil=\"true\" />\n" "<d4p1:FileOrLinkName i:nil=\"true\" />\n" "<d4p1:IsLiked>0</d4p1:IsLiked>\n" "<d4p1:IsTotalSchool i:nil=\"true\" />\n" "<d4p1:LikeCount>0</d4p1:LikeCount>\n" "<d4p1:LinkImage i:nil=\"true\" />\n" "<d4p1:ObjTypeCdId i:nil=\"true\" />\n" "<d4p1:ObjTypeId i:nil=\"true\" />\n" "<d4p1:OperationMode>I</d4p1:OperationMode>\n" "<d4p1:OperationType i:nil=\"true\" />\n" "<d4p1:OperationTypeId i:nil=\"true\" />\n" "<d4p1:OrganizationId>%@</d4p1:OrganizationId>\n" "<d4p1:OtherActivityId i:nil=\"true\" />\n" "%@\n" "</objEventsContent>\n" "<ismobile>true</ismobile>\n" "</InsUpdDelActivityInfo>\n" "</s:Body>\n" "</s:Envelope>", statusText, [byteArray length], byteArray[0], byteArray[1], .................................., [appDelegateObj.loginUserInfoDict valueForKey:@"a:UserId"], [appDelegateObj.loginUserInfoDict valueForKey:@"a:OrgId"], workspaceStr]; 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@blah....blah....blah....", appDelegateObj.baseURL]]]; NSString *messageLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postStr length]]; [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request addValue:@"http://tempuri.org/blah......blah.....blah............" forHTTPHeaderField:@"SOAPAction"]; [request addValue:messageLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; NSError *error = nil; NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];

我已经主持了服务,在那里我看到了请求的XML格式。 任何方式谢谢你@ Duraiamuthan.H