4

几年前,我们为移动应用程序开发了一个 .NET Web 服务。iPhone/Android/Blackberry/WindowsPhone 和第三方开发的所有本机应用程序正在调用此服务。我们添加了对 JSON 的支持,因此一些应用程序使用 JSON 调用访问此服务,而一些应用程序使用 SOAP。

仅当使用 HTTP 标头发送请求时,Web 服务才会返回 JSON Content-type: application/json

我们遇到了一个 Android 平台(特别是 Galaxy Nexus)的问题,其中Content-Type缺少 GET 请求的标头。我们的第三方应用程序开发人员尝试了许多解决方案,但找不到强制发送 GET 请求的 Content-Type 的方法。

但是,我们确实注意到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-TypeGET 请求的标头的解决方案,我们也将不胜感激!

谢谢!

4

3 回答 3

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);
}

编辑:更新了响应请求

于 2012-09-27T05:05:51.343 回答
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;
    }

干杯!

于 2012-09-27T11:17:59.260 回答
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; }
    } 
于 2012-09-27T12:00:56.243 回答