【问题标题】:NSJSONSerialization encoding?NSJSON序列化编码?
【发布时间】:2014-11-10 19:38:45
【问题描述】:

我正在尝试将我的 NSDictionary 转换为 json 字符串,然后通过 HTTPBody(POST 请求)将数据发送到我的 Web api。我像这样将我的字典转换为 json:

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];

我发现上述方法没有对我的数据进行编码(至少没有处理像&符号这样的特殊字符)。所以服务器端接收到的数据乱七八糟,无法正常读取。

有关正在发生的事情的更多详细信息,请假设以下字典:

"salutation":"Mrs."
"companyName":"T & F LLP"
"firstName":"Tania"
"country":"Canada"

这个字典用上面的方法转换成NSData,后面这样使用

[request setHTTPBody:nsDataFromJson];

我在服务器端收到什么?我明白了

{"contact":"{\"firstName\":\"Tania\",\"salutation\":\"Mrs.\",\"company\":\"Aird 

我只获取到特殊字符 & 的数据,我只能假设这种情况正在发生,因为我提到的第一种方法不是编码像 & 这样的特殊字符

所以我通过将字典转换为 json 字符串然后用 %26 替换每个 & 然后从这个新字符串创建 NSData(处理特殊字符)来解决这个问题(只是暂时)。然后我在我的服务器上获取完整的主体。

那么知道如何正确处理这个问题吗?

顺便说一句,如果我也使用 SBJSON,也会出现同样的问题。

【问题讨论】:

  • 您显然是在使用一种破坏它不喜欢的数据的技术来传输 JSON 数据。这不是 JSON 的问题,但是鉴于您选择的协议,您选择了错误的协议,或者您没有以某种方式转义数据。
  • @Daij-Djan - 以 ASCII 格式读取不会导致 & 出现问题。
  • 那么我的问题可能是如何正确编码 HTTPBody?更具体地说,我如何'html逃脱'HTTPBody?例如,在我的 android 应用程序上,当我将字典转换为 json 时,我得到 \uc0026 而不是与号,当我将数据发送到我的服务器时,我收到完整的有效负载并且我的服务器很高兴。 @HotLicks,我的请求是通过普通的 NSUrlRequest 完成的,网络服务是一个 .NET asmx 网络服务
  • 我对字符编码的想法显然是错误的。 hot licks 几个小时就知道答案了,也许他现在会发布它
  • 最好的方法是使用将 JSON 视为纯二进制的协议。这是您在 HTTP 请求中分配的类型的函数,并使用 IIRC、POST 和 PUT。

标签: ios json dictionary url-encoding nsjsonserialization


【解决方案1】:

已经3个月了,所以我想问题应该已经解决了。

接收到的 JSON 数据损坏的原因是解析器将 &(与号)解释为 URL 地址的一部分。借用this link的一些代码,我写了这个函数来对&和其他一些可能会混淆的字符进行百分比编码:

+ (NSDictionary*) percentEncodeDictionayValues:(NSDictionary*) dict
{
    NSMutableDictionary* edict=[NSMutableDictionary dictionaryWithDictionary:dict];

    NSMutableCharacterSet* URLQueryPartAllowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
    [URLQueryPartAllowedCharacterSet removeCharactersInString:@"?&=@+/'"];

    for(NSString* key in [dict allKeys])
    {
        if([dict[key] isKindOfClass:[NSString class]])
            edict[key] = [dict[key] stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet];
    }
    return edict;
}

因此,您可以在输入 NSJSONSerialization 之前使用此函数预处理您的 NSDictionary 对象,并且接收到的数据将保留 & 和其他字符。

【讨论】:

    猜你喜欢
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多