几年前,我们为移动应用程序开发了一个.NET Web服务。这项服务由iPhone / Android / Blackberry / WindowsPhone以及由第三方开发的所有本机应用程序调用。我们添加了对JSON的支持,因此一些应用程序使用JSON调用访问此服务,有些使用SOAP。
只有在使用HTTP标头Content-type: application/json
发送请求时,webservice才会返回JSON。
我们遇到了一个Android平台(特别是Galaxy Nexus)的问题,其中GET请求缺少Content-Type
标头。我们的第三方应用开发者尝试了许多解决方案,但无法找到强制发送内容类型以获取GET请求的方法。
但是,我们注意到Accept
标头已正确设置并发送,但我发现在这些情况下我无法更改Web服务以使用该标头而不是Content-Type
来返回JSON。
以下是示例请求,它使用XML响应,而不是根据需要使用JSON。
GET /mobile/service.asmx/Logon?system=2&username='test'&password='1234' HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
Connection: Keep-Alive
摘自网络服务代码:
[WebMethod(
BufferResponse = false,
CacheDuration = 0
)]
[ScriptMethod(UseHttpGet = true,ResponseFormat = ResponseFormat.Json) ]
public LogonResponse Logon(int system, string username, string password)
{
return service.Logon(system, username, password);
}
有没有办法以某种方式强制JSON响应,或者检查Accept
标头是否这样做? (除了迁移到WCF?)
如果没有,应用程序开发人员告诉我他们使用Spring框架来发出HTTP请求。如果有关于如何使其在应用程序端工作的解决方案并强制发送Content-Type
标头以获取GET请求,那么也非常感谢!
谢谢!
答案 0 :(得分:2)
你可以试试这个(目前无法测试)。
public LogonResponse Logon(int system, string username, string password)
{
string accept = HttpContext.Current.Request.Headers("Accept");
if (!string.IsNullOrEmpty(accept)) {
if (accept.ToLower.EndsWith("application/json")) {
HttpContext.Current.Response.ContentType = "application/json";
}
}
return service.Logon(system, username, password);
}
编辑:更新了回复请求
答案 1 :(得分:1)
感谢您的回复。
虽然设置内容类型并没有解决问题,但确实指出了我正确的方向。
以下为我解决了这个问题:
[WebMethod(
BufferResponse = false,
CacheDuration = 0
)]
[ScriptMethod(UseHttpGet = true,ResponseFormat = ResponseFormat.Json) ]
public LogonResponse Logon(int system, string username, string password)
{
return SetOutput<LogonResponse>(service.Identify(username, password));
}
和实际转换:
public static T SetOutput<T>(object response)
{
var accept = HttpContext.Current.Request.Headers["Accept"];
var ctype = HttpContext.Current.Request.ContentType;
if (string.IsNullOrEmpty(ctype) && !string.IsNullOrEmpty(accept))
if (accept.ToLower().EndsWith("application/json"))
{
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(response);
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(json);
HttpContext.Current.Response.End();
}
return (T)response;
}
干杯!
答案 2 :(得分:0)
使用以下内容还可以使用预期的“d”元素包装整个内容:
public static T SetOutput<T>(T response)
{
var accept = HttpContext.Current.Request.Headers["Accept"];
var ctype = HttpContext.Current.Request.ContentType;
if (string.IsNullOrEmpty(ctype) && !string.IsNullOrEmpty(accept))
if (accept.ToLower().EndsWith("application/json"))
{
var wrapper = new JSONWrapper<T> {d = response};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(wrapper);
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(json);
HttpContext.Current.Response.End();
}
return response;
}
public class JSONWrapper<T>
{
public T d { set; get; }
}