4

首先,我意识到对于 PUT 请求,请求参数应该在请求正文中传递。但是,我正在使用一个 API(我只是在使用,而不是开发),它期望请求参数作为 PUT 请求的查询字符串附加。

我正在使用 AFHTTPClient 的子类。对于我所指的特定 PUT 请求,我使用getPath:parameters:success:failure:

到目前为止,我找到的解决方案是手动构造路径变量以包含我要传递的参数。当然,这并不理想,我想知道是否还有其他不易出错的选项。

简而言之,有没有办法使用 AFHTTPClient (的子类)发送 PUT 请求,并将传递的参数附加(和编码)作为查询字符串(就像 GET 请求一样)?

4

3 回答 3

4

AFHTTPClient.m 中的 getPath:parameters:success:failure 方法调用 requestWithMethod:path:parameters。在后一种方法中,根据某些值检查 HTTP 方法以确定如何将参数附加到请求中。如您所见,默认情况下,参数仅应在 GET、HEAD 或 DELETE 请求的情况下附加到 URL。由于您也需要在 PUT 请求的情况下将它们附加到 URL,因此修改 requestWithMethod:path:parameters 如下:

    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method 
                                      path:(NSString *)path 
                                parameters:(NSDictionary *)parameters 
{   
    NSURL *url = [NSURL URLWithString:path relativeToURL:self.baseURL];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
    [request setHTTPMethod:method];
    [request setAllHTTPHeaderFields:self.defaultHeaders];

    if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"]) {
        [request setHTTPShouldUsePipelining:YES];
    }

    if (parameters) {        
        if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"] || [method isEqualToString:@"DELETE"] || [method isEqualToString:@"PUT"]) {
            url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding)]];
            [request setURL:url];
        } else {
            NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
            switch (self.parameterEncoding) {
                case AFFormURLParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding) dataUsingEncoding:self.stringEncoding]];
                    break;
                case AFJSONParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFJSONStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
                    break;
                case AFPropertyListParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/x-plist; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFPropertyListStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
                    break;
            }
        }
    }

    return request;
}
于 2012-07-16T08:23:09.750 回答
3

您可以在不修改底层 AFNetworking 代码的情况下执行 datwalk 答案中的代码正在执行的操作。使用 AFNetworking 创建包含 URL 参数的路径:

NSDictionary *mutableParameters = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"csv",@"format", @"0",@"level", @"2013-10-25", @"keydate", nil];

NSString *urlPath = [NSString stringWithFormat:@"applications/%@/Planning?%@", name, AFQueryStringFromParametersWithEncoding(mutableParameters, NSUTF8StringEncoding)];

NSString *apiFunctionPath = [urlPath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[self putPath:apiFunctionPath
   parameters:nil
      success:^(AFHTTPRequestOperation *operation, id XML) {
          NSLog(@"%@",XML);
      }
      failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          NSLog(@"%@",error);
      }];
于 2013-10-25T19:00:19.553 回答
1

对于我的 API,更改 AFHTTPClient 对象的编码解决了这个问题:

myAFHTTPClient.parameterEncoding = AFJSONParameterEncoding;
于 2013-06-11T19:58:55.167 回答