2

我正在做一个需要将文件从 iphone 上传到 wcf 服务的项目。我没有 wcf 和 afnetworking 的经验。我已经坚持这一步好几天了,这是我取得的进展:

用于上传文件的 WCF 服务:请注意,我已从Codeproject 网站复制了此代码。

public interface ITransferService
{
[OperationContract]
RemoteFileInfo DownloadFile(DownloadRequest request);

[OperationContract]
 void UploadFile(RemoteFileInfo request); 
}

    public void UploadFile(RemoteFileInfo request)
{
    FileStream targetStream = null;
    Stream sourceStream =  request.FileByteStream;

    string uploadFolder = @"C:\upload\";

    string filePath = Path.Combine(uploadFolder, request.FileName);

    using (targetStream = new FileStream(filePath, FileMode.Create, 
                          FileAccess.Write, FileShare.None))
    {
        //read from the input stream in 65000 byte chunks

        const int bufferLen = 65000;
        byte[] buffer = new byte[bufferLen];
        int count = 0;
        while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
        {
            // save to output stream
            targetStream.Write(buffer, 0, count);
        }
        targetStream.Close();
        sourceStream.Close();
    }

}

上传代码在源代码附带的客户端程序上运行良好,我可以通过 wcf 服务上传任何大小和任何类型或文件。

我还发现 AFNetworking 框架在 ios 上非常流行,所以我决定使用它。这是我上传文件的代码:

我已经走了这么远,请在这种情况下帮助我。谢谢你的帮助

好的,这是新的信息:

首先,将文件上传到 wcf 服务的 c# 代码(正在工作)

protected void Button1_Click(object sender, EventArgs e)
{ 
if (FileUpload1.HasFile)
{
    System.IO.FileInfo fileInfo = 
           new System.IO.FileInfo(FileUpload1.PostedFile.FileName);
    FileTransferServiceReference.ITransferService clientUpload = 
           new FileTransferServiceReference.TransferServiceClient();
    FileTransferServiceReference.RemoteFileInfo 
           uploadRequestInfo = new RemoteFileInfo();

    using (System.IO.FileStream stream = 
           new System.IO.FileStream(FileUpload1.PostedFile.FileName, 
           System.IO.FileMode.Open, System.IO.FileAccess.Read))
    {
        uploadRequestInfo.FileName = FileUpload1.FileName;
        uploadRequestInfo.Length = fileInfo.Length;
        uploadRequestInfo.FileByteStream = stream;
        clientUpload.UploadFile(uploadRequestInfo);
        //clientUpload.UploadFile(stream);
    }
}
}

第二:用于将文件上传到服务器的remotefileinfo类:

  public class RemoteFileInfo : IDisposable
  {
    [MessageHeader(MustUnderstand = true)]
     public string **FileName**;

    [MessageHeader(MustUnderstand = true)]
    public long **Length**;

    [MessageBodyMember(Order = 1)]
    public System.IO.Stream **FileByteStream**;

    public void Dispose()
    { 
        if (FileByteStream != null)
       {
        FileByteStream.Close();
        FileByteStream = null;
       }
    }   
  }

从所有这些代码中,我了解到我需要创建一个包含“文件名”“文件长度”和文件数据“文件字节流”的请求。我在代码中尝试了一些东西,但是当我尝试使用此代码上传图像时服务器给出错误 415:

   AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://192.168.2.121:85"]];

UIImage *image = [UIImage imageNamed:@"test.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 0.2);

NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:@"test.jpg" forKey:@"FileName"];
[parameters setObject:[NSString stringWithFormat:@"%i",data.length] forKey:@"Length"];

NSMutableURLRequest *myRequest = [client multipartFormRequestWithMethod:@"POST" path:@"/webservice/Transferservice.svc/UploadFile" parameters:parameters constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
    [formData appendPartWithFileData:data name:@"RemoteFileInfo" fileName:@"test.jpg" mimeType:@"image/jpeg"];
}];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:myRequest];
[operation 
 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
     NSLog(@"success: %@", operation.responseString);
 } 
 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     NSLog(@"error: %@", operation.error);
 }
 ];

[[[NSOperationQueue alloc] init] addOperation:operation];

这里也是服务的 WSDL 链接:

WSDL 链接

我真的需要这样做,谢谢你的再次帮助......

4

3 回答 3

3

试试这个尺寸:

AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://192.168.2.121:85"]];

NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"test.jpg"], 0.2);

NSMutableURLRequest *myRequest = [client multipartFormRequestWithMethod:@"POST" path:@"/webservice/Transferservice.svc/UploadFile" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
    [formData appendPartWithFileData:data name:@"RemoteFileInfo" fileName:@"test.jpg" mimeType:@"image/jpeg"];
}];

AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:myRequest] autorelease];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *op, id responseObj) {
    NSLog(@"success: %@", operation.responseString);
} failure:^(AFHTTPRequestOperation *op, NSError *error) {
    NSLog(@"[Error]: (%@ %@) %@", [operation.request HTTPMethod], [[operation.request URL] relativePath], operation.error);
}];

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];

您不需要在您的帖子参数中传递文件的名称或大小,您可以在接收表单上获取它。不要忘记appendPartWithFileData服务器端脚本应该使用名称部分来识别文件上传。

以上所有内容在 PHP 中都是相关的,但对于 ASP.NET 应该同样适用。

也像上面的链接不起作用。

干杯

于 2011-11-25T22:30:20.280 回答
1

最后,我成功通过文件流将文件上传到 WCF。问题是之前的代码在正文中需要一个标题和一个流,我找不到这样做的方法。相反,我发现我需要编写一个只接受一个流作为参数的代码,没什么,然后文件名和其他东西将在服务器端完成。

我从这个问题中得到了 wcf 服务的上传代码:WCF service to accept a postcoded multipart/form-data

完全按照答案中的内容做了。在 iphone 端,我为我的操作设置了一个输入流。这是用于将文件上传到 wcf 服务的 AFNetworking 的代码:

AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:@"http://192.168.2.121:85"]];

UIImage *image = [UIImage imageNamed:@"test.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 0.2);
NSInputStream *stream = [[[NSInputStream alloc]initWithData:data] retain];
NSDictionary *parameters = nil;

NSMutableURLRequest *myRequest = [client requestWithMethod:@"POST" path:@"/uploadservice/service1.svc/Upload" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:myRequest];

 [
 operation 
 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
     NSLog(@"success: %@", operation.responseString);
 } 
 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     NSLog(@"error: %@", operation.error);
 }
 ];

operation.inputStream = stream; //Thats where you put your stream!

[[[NSOperationQueue alloc] init] addOperation:operation];

感谢大家的耐心等待,即使您的回复也不是完整的答案,您的回复使我找到了正确的答案...

于 2011-11-27T14:09:32.313 回答
0

您从远程 Web 服务器收到 404 或“未找到”错误。

这可能意味着您的 URL 路径或服务器名称不正确 - 关于服务器端设置的信息不足,我们无法推断出正确的 URL 是什么。

于 2011-11-23T14:36:57.233 回答