未指定content-type时,Web服务返回SOAP

时间:2012-09-18 19:38:14

标签: android .net web-services spring content-type

几年前,我们为移动应用程序开发了一个.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请求,那么也非常感谢!

谢谢!

3 个答案:

答案 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; }
    }