【问题标题】:AFJSONParameterEncoding in AFNetworking 2.x.xAFNetworking 2.x.x 中的 AFJSONParameterEncoding
【发布时间】:2014-03-31 00:57:47
【问题描述】:

我正在实施以下贝宝 REST API:

curl -v https://api.sandbox.paypal.com/v1/vault/credit-card \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {accessToken}' \
-d '{
 "payer_id":"user12345",
 "type":"visa",
 "number":"4417119669820331",
 "expire_month":"11",
 "expire_year":"2018",
 "first_name":"Joe",
 "last_name":"Shopper"
}'

我已经使用以下代码在 AFNetworking 1.3.3 中成功实现了这个 api。其中PPWebServiceAFHTTPClient 的子类

[[PPWebService sharedClient] setParameterEncoding:AFJSONParameterEncoding];
    [[PPWebService sharedClient] setDefaultHeader:@"Content-Type" value:@"application/json"];
    [[PPWebService sharedClient] setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Bearer %@", accessToken]];

    [[PPWebService sharedClient] postPath:@"vault/credit-card"
                               parameters:creditCard
                                  success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSDictionary *response = [self JSONToObject:operation.responseString];

        creditCardId = response[@"id"];

        if(creditCardId)
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Credit card" message:@"Saved !!" delegate:nil cancelButtonTitle:@"on" otherButtonTitles:nil];

            [alert show];
        }
    }
                                  failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Credit card" message:error.description delegate:nil cancelButtonTitle:@"on" otherButtonTitles:nil];

        [alert show];
    }];

我想在我的项目中使用 AFNetworking 2.x.x。但是我不能用这个新版本来做到这一点。

我有子类AFHTTPRequestOperationManager。我搜索互联网,人们建议我使用AFJSONRequestSerializer。所有其他代码都非常相似。但是我也收到了错误的请求错误。

那么如何在 AFNetworking 2.x.x 中使用 POST 方法发送原始 JSON 字符串?

编辑

Code for AFNetworking 2.X.X

错误状态:404 Bad Request

回应

{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/docs/api/#MALFORMED_REQUEST","debug_id":"ab3c1dd874a07"}

我使用 Postman 得到了正确的响应,如下图所示。

【问题讨论】:

  • 你能发布你尝试的代码,以及具体的错误吗?
  • 您能否使用 charlesproxy 之类的工具准确查看您发送到服务器的内容,并将该信息以及代码添加到您的问题中。
  • @Aaron Brager 我有更新问题的代码,所以请看一下。
  • @JosephH 感谢您向我推荐该工具。我会使用它并尽快回来。
  • 我的猜测是您需要对您的 accessToken 进行 UFT8Encode,您是否在显示的代码之外的其他地方执行此操作?

标签: ios rest paypal afnetworking-2


【解决方案1】:

所以我终于得到了答案。我使用AFHTTPSessionManager 的子类在我的项目中实现API。并将其与单例对象一起使用。所以这是我的单例方法。

+ (MASWebService *)APIClient
{
    static MASWebService *_sharedClient = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^
    {
        NSURL *baseURL = [NSURL URLWithString:BaseURL];

        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

        _sharedClient = [[MASWebService alloc] initWithBaseURL:baseURL sessionConfiguration:config];

        _sharedClient.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];

        _sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];

        [_sharedClient.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    });

    return _sharedClient;
}

主要的关键行是将Request Serializer HTTP Header“Content-Type”设置为“application/json”

如果您没有继承 AFHTTPSessionManager 并将 AFHTTPRequestOperationManager 用于单个请求,那么它也将起作用,因为 AFHTTPRequestOperationManager 也符合 AFURLRequestSerialization 协议作为 AFHTTPRequestSerializer 的属性。我还没有做,但它应该是这样的。

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSDictionary *parameters = @{@"foo": @"bar"};

    manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];       
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

    [manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

我希望这会奏效。如果我在某处错了,请在评论中告诉我。

来源AFNetworking 2.0 POST request working example code snippet

【讨论】:

    【解决方案2】:

    那么如何在 AFNetworking 2.x.x 中使用 POST 方法发送原始 JSON 字符串?

    在尝试将 SOAP+XML 数据与 AFHTTPRequestOperationManager 一起使用时,我遇到了同样的问题。显然,请求序列化程序应该被子类化以满足您的特殊序列化需求,但这种方式似乎更容易:

    NSError *error = nil;
    NSData *envelopeData = [NSJSONSerialization dataWithJSONObject:params options:options error:nil];
    
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"POST"
                                                                   URLString:path
                                                                  parameters:nil
                                                                       error:&error];
    // In my case, I also needed the following: 
    // [request setValue:action forHTTPHeaderField:@"SOAPAction"]; 
    
    [request setHTTPBody:envelopeData];
    
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] init];
    operation = [self HTTPRequestOperationWithRequest:request
                                              success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        // parse response here
    }
                                              failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        // parse response here
    }];
    

    它劫持 AFHTTPRequestOperationManager 创建的请求序列化器,将参数数据插入 HTTP 正文,然后将这个新请求传递给 AFHTTPRequestOperation。

    【讨论】:

    • 我找到了更简单的解决方案,请查看我的新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多