[英]Web service returns SOAP when content-type is not specified
We developed a .NET web service for mobile application several years ago. 几年前,我们为移动应用程序开发了一个.NET Web服务。 This service is being called by iPhone/Android/Blackberry/WindowsPhone and all native apps developed by a third party. 这项服务由iPhone / Android / Blackberry / WindowsPhone以及由第三方开发的所有本机应用程序调用。 We added support for JSON, so some apps access this service using JSON calls, and some using SOAP. 我们添加了对JSON的支持,因此一些应用程序使用JSON调用访问此服务,而一些应用程序使用SOAP。
The webservice returns JSON only when the request is sent with HTTP header Content-type: application/json
. 仅当使用HTTP标头Content-type: application/json
发送请求时,webservice才返回JSON。
We encountered a problem with one Android platform (specifically the Galaxy Nexus), where the Content-Type
header is missing for GET requests. 我们遇到了一个Android平台(特别是Galaxy Nexus)的问题,其中GET请求缺少Content-Type
标头。 Our third party app developer tried many solutions but could not find a way to force send the Content-Type for GET requests. 我们的第三方应用程序开发人员尝试了许多解决方案但无法找到强制发送Content-Type for GET请求的方法。
However, we did notice that the Accept
header is set correctly and sent, but I found no way to change the web service to use that header instead of Content-Type
to return JSON in those cases. 但是,我们确实注意到Accept
头设置正确并已发送,但我发现无法更改Web服务以使用该头而不是Content-Type
在这些情况下返回JSON。
Here is the example request, which results with XML response, and not JSON as needed. 下面是示例请求,它使用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
And excerpt from the webservice code: 并摘自Web服务代码:
[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);
}
Is there a way to force JSON response in some way, or inspecting the Accept
header to do so? 有没有办法以某种方式强制JSON响应,或者检查Accept
标头是否这样做? (Other than migrating to WCF?) (除了迁移到WCF?)
If not, I was told by the app developer they use the Spring framework to make HTTP requests. 如果没有,应用程序开发人员告诉我他们使用Spring框架来发出HTTP请求。 If there's a solution on how to make it work on the app side and force send the Content-Type
header for GET requests, it's also appreciated! 如果有关于如何使其在应用程序端工作的解决方案并强制发送GET请求的Content-Type
标头,那么也非常感谢!
Thanks! 谢谢!
You could try this (unable to test at the moment). 你可以尝试这个(目前无法测试)。
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);
}
Edit: Updated the Request to response 编辑:更新了响应请求
Thanks for the reply. 谢谢回复。
Although setting the content-type did not solve the issue, it did point me in the right direction. 尽管设置内容类型并没有解决问题,但它确实指出了我正确的方向。
The following solved it for me: 以下为我解决了这个问题:
[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));
}
and the actual conversion: 和实际转换:
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;
}
Cheers! 干杯!
Use the following to also wrap the whole thing with the expected "d" element: 使用以下内容还可以使用预期的“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; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.