NSURLSessionDataTask 无法将音频文件上传到服务器

问题描述 投票:0回答:1

我知道这个问题以前曾被问过。但所有答案都不适合我。

有什么要求:
在 iOS 应用程序上,用户能够录制一个短音频文件(30 秒),然后使用 https 请求将其上传到服务器。
手机上的录音和临时保存效果很好。
但我无法让上传部分工作。

我在 API 端上传文件的代码如下。用

Postman
测试过,效果很好。文件已收到并按预期保存。

[HttpPost]
public async Task<IActionResult> UploadFile([FromForm] IFormFile file, [FromForm] string name)
    {
        try
        {
            if(webHostEnvironment == null)
            {
                throw new SqlNullValueException("webHostEnvironment is null");
            }

            if (webHostEnvironment.ContentRootPath == null)
            {
                throw new SqlNullValueException("webHostEnvironment.ContentRootPath is null");
            }


            if(file == null)
            {
                throw new SqlNullValueException("File is null");
            }

            String path = Path.Combine(webHostEnvironment.ContentRootPath,  "uploads");              
            if (file.Length > 0)
            {
                string filePath = Path.Combine(path, file.FileName);
                using (Stream fileStream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }
            }
            return BuildResponse(Ok().StatusCode, name);
        }
        catch(Exception ex)
        {
            throw new Exception(ex.Message );
        }
    }

这是我上传文件的 Objective-C 代码:

-(void)uploadFile:(NSData*)fileData{
if(fileData != nil){
    NSString *fileName = self.temporaryRecFile.path.lastPathComponent;
    NSString *urlString = @"some url";//upload file url
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];
    NSString *boundary = @"---------------1234567890";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
    
    
    NSMutableData *bodyData = [[NSMutableData alloc] init];
    [bodyData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [bodyData appendData:[[NSString stringWithString:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n", fileName]] dataUsingEncoding:NSUTF8StringEncoding]];
    [bodyData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [bodyData appendData:[NSData dataWithData:fileData]];
    [bodyData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setHTTPBody:bodyData];
            
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
            NSInteger responseStatusCode = [httpResponse statusCode];
            
            if(error != nil)
                NSLog(@"error uploading file %@", error.localizedDescription);
            else{
                NSLog(@"response: %lu", responseStatusCode);
                NSLog(@"response: %@", data);
                NSLog(@"response: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            }
        });
    }];
    
    [dataTask resume];
}

} 我得到的答案是:

response: {"code":500,"reason":"File is null"}

而不是

NSURLSessionDataTask
我尝试使用
NSURLSessionUploadTask
但没有运气。我得到:

Failed to read the request form. Multipart body length limit 16384 exceeded

因为 Postman 可以很好地使用 API 端点上传文件。那么问题肯定出在iOS应用端。
任何想法可能是什么问题? 谢谢!

ios objective-c .net-core
1个回答
0
投票

感谢@Paulw11提到不一致问题。

重新审视我两边的代码,意识到我在 iOS 表单上犯了一个错误,将

file
称为
userfile
。 API 需要file。所以这里应该有两个选择:
1- 在此处更改并重命名用户文件:
Content-Disposition: form-data; name=\"userfile\";
file
,以便 API 识别它。
2- 或者保留您选择的任何自定义名称并修改 API,如下所示:

    public async Task<IActionResult> UploadFile([FromForm(Name = "userfile")] IFormFile file, [FromForm(Name = "filename")] string filename){
      //upload logic here    
    }

这解决了我的问题,文件现已上传!

© www.soinside.com 2019 - 2024. All rights reserved.