Web 服务请求中的特殊字符
Special Characters in Webservice Request
过去我一直使用以下代码将数据从我的应用程序发送到将数据保存在我公司服务器上的网络服务(网络服务是用 asp.net 编写的)。
- (NSArray *) callWebserviceWithPost:(NSString *)post andWithParser:(MyNSXMLParserDelegateClass *)parser
{
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://www.example.com/mywebservices/mywebservice.aspx"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
[request setTimeoutInterval:600];
NSHTTPURLResponse *response = nil;
NSError *err = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
if (!responseData)
{
NSString *msg = [NSString stringWithFormat:@"Response not recieved from web service"];
[Globals throwError:msg withCode:20 inMethod:_cmd onClass:[self class]];
return [NSArray arrayWithObject:errorString];
}
else
{
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if ([[responseString substringToIndex:1] isEqualToString:@"<"])
{
// Create and init NSXMLParser object from data return by web service
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:responseData];
[nsXmlParser setDelegate:parser];
BOOL success = [nsXmlParser parse];
if (success)
{
return parser.allItems;
}
}
}
}
其中 post 看起来像
NSString *post = @"NewUser=<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<data>
<username>GeneralMike</username>
<status>Awesome</status>
</data>
</xml>"
到目前为止,这对我需要做的一切都很有效。
但是,现在我需要在我的数据中发送一些特殊字符
...<username>"Frank"</username>...
我做了一些研究 discovered I can escape the special characters with certain codes。所以这个例子会变成
...<username>"Frank"</username>...
当我使用添加了转义符的 post 调试我的 web 服务项目时,它工作正常。但是,当我尝试从我的应用程序调用网络服务时,我在响应中收到错误消息
Unexpected end of file has occurred. The following elements are not closed: username,data. Line 1, position ....
根据提供的位置计算,我发现这个错误是在 &
第一次转义的地方抛出的。
我还发现了很多建议我需要使用 stringByAddingPercentEscapesUsingEncoding
或 CFURLCreateStringByAddingPercentEscapes()
的东西,但是我尝试使用它们的每一种方式,网络服务都无法识别请求是。
为什么当我将它们直接放入 web 服务项目时,我链接的转义符工作正常,但当我尝试从我的应用程序发送它们时却丢失了?我需要更改什么才能让它们正常工作?
由于我控制了网络服务和使用它的平台,所以我能够制定自己的惯例来处理特殊字符。我知道对于我现在发送的内容,我不太可能有一个包含双下划线的值,而且下划线似乎对我目前所见的一切都是合法的,所以我开发了一个系统,我拼出一个字符并用下划线包围它。所以我会有类似
的东西
...<username>__QUOTE__Frank__QUOTE__</username>...
在我的新系统中。我可以在从我的应用程序发送请求或从网络服务发送响应之前查找特殊字符,并进行简单的字符串替换。然后,一旦我收到 XML,寻找替换项,并在使用数据之前将它们变回特殊字符(例如在屏幕上显示或保存到数据库中)。
我不是特别喜欢这个解决方案。我宁愿赞成一个更普遍的公约。由于我似乎找不到那个约定,如果存在这样的约定,现在就可以了。
过去我一直使用以下代码将数据从我的应用程序发送到将数据保存在我公司服务器上的网络服务(网络服务是用 asp.net 编写的)。
- (NSArray *) callWebserviceWithPost:(NSString *)post andWithParser:(MyNSXMLParserDelegateClass *)parser
{
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://www.example.com/mywebservices/mywebservice.aspx"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
[request setTimeoutInterval:600];
NSHTTPURLResponse *response = nil;
NSError *err = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
if (!responseData)
{
NSString *msg = [NSString stringWithFormat:@"Response not recieved from web service"];
[Globals throwError:msg withCode:20 inMethod:_cmd onClass:[self class]];
return [NSArray arrayWithObject:errorString];
}
else
{
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if ([[responseString substringToIndex:1] isEqualToString:@"<"])
{
// Create and init NSXMLParser object from data return by web service
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData:responseData];
[nsXmlParser setDelegate:parser];
BOOL success = [nsXmlParser parse];
if (success)
{
return parser.allItems;
}
}
}
}
其中 post 看起来像
NSString *post = @"NewUser=<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<data>
<username>GeneralMike</username>
<status>Awesome</status>
</data>
</xml>"
到目前为止,这对我需要做的一切都很有效。
但是,现在我需要在我的数据中发送一些特殊字符
...<username>"Frank"</username>...
我做了一些研究 discovered I can escape the special characters with certain codes。所以这个例子会变成
...<username>"Frank"</username>...
当我使用添加了转义符的 post 调试我的 web 服务项目时,它工作正常。但是,当我尝试从我的应用程序调用网络服务时,我在响应中收到错误消息
Unexpected end of file has occurred. The following elements are not closed: username,data. Line 1, position ....
根据提供的位置计算,我发现这个错误是在 &
第一次转义的地方抛出的。
我还发现了很多建议我需要使用 stringByAddingPercentEscapesUsingEncoding
或 CFURLCreateStringByAddingPercentEscapes()
的东西,但是我尝试使用它们的每一种方式,网络服务都无法识别请求是。
为什么当我将它们直接放入 web 服务项目时,我链接的转义符工作正常,但当我尝试从我的应用程序发送它们时却丢失了?我需要更改什么才能让它们正常工作?
由于我控制了网络服务和使用它的平台,所以我能够制定自己的惯例来处理特殊字符。我知道对于我现在发送的内容,我不太可能有一个包含双下划线的值,而且下划线似乎对我目前所见的一切都是合法的,所以我开发了一个系统,我拼出一个字符并用下划线包围它。所以我会有类似
的东西...<username>__QUOTE__Frank__QUOTE__</username>...
在我的新系统中。我可以在从我的应用程序发送请求或从网络服务发送响应之前查找特殊字符,并进行简单的字符串替换。然后,一旦我收到 XML,寻找替换项,并在使用数据之前将它们变回特殊字符(例如在屏幕上显示或保存到数据库中)。
我不是特别喜欢这个解决方案。我宁愿赞成一个更普遍的公约。由于我似乎找不到那个约定,如果存在这样的约定,现在就可以了。