应用于Web API收益400无效的主机名

时间:2013-01-05 02:36:00

标签: android asp.net http asp.net-web-api

我有一个奇怪的问题。从我的Android应用程序,我正在调用ASP.NET Web API。我可以在应用程序中发出一个没有问题的POST请求。但是,当我去发出GET请求时,请求返回“400 bad request invalid hostname”。这很奇怪,因为我可以发出POST请求,而不是获取。我使用的URL是http://10.0.2.2/webapp/api/controllername(10.0.2.2,因为android模拟器使用127.0.0.1;这是已发布的解决方法)。我确实启用了互联网权限。

我目前正在调试Web API,我可以调试发布请求。我可以手动在Internet Explorer中键入get请求,然后点击服务器。这就是我知道它的工作方式。我有一个application_beginrequest的处理程序只是为了看到我甚至打到服务器,它是为了发布请求。但我甚至都没有看到get请求进入服务器。

要发出Android GET请求,我使用了以下内容(添加了附加信息的评论)。

//Creation of get request
HttpGet request = new HttpGet(url); //correct URL; verified
for(NameValuePair h : headers)
{
    //6 headers added; verified OK
    request.addHeader(h.getName(), h.getValue());
}
//Calls method shown below
return executeRequest(request, url);

 private ResponseInformation executeRequest(HttpUriRequest request, String url) throws Exception
{
    HttpClient client = new DefaultHttpClient();
    HttpResponse httpResponse;

    try {
        //Get the response and check the code/message
        httpResponse = client.execute(request);
        responseCode = httpResponse.getStatusLine().getStatusCode();
        message = httpResponse.getStatusLine().getReasonPhrase();

        HttpEntity entity = httpResponse.getEntity();
        ResponseInformation info; // just a DTO for my needs

        if (entity != null) {
            InputStream instream = entity.getContent();
            //Response is an XML document listing the 400 error information
            response = convertStreamToString(instream);
            info = new ResponseInformation(responseCode, response, message);
            instream.close();
        }
        else
            info = new ResponseInformation(responseCode, message);

        return info;

    }
    .
    .
}

所以我不确定是谁在拒绝?为什么我会收到此错误?它永远不会遇到Application_BeginRequest,因此它永远不会进入我的Web API服务,但是POSTS确实......很奇怪。

3 个答案:

答案 0 :(得分:4)

我使用Web API自我主机遇到同样的问题,无法通过GET或POST发送请求。

如果传入的主机和400 Invalid Hostname标头 已配置的IIS或自托管主机名相同,则Web API会生成Host ,见this。 我在我的主机中使用RawCap(WireShark无法在Windows中监控环回IP),在Android模拟器中使用tcpdumpHost标题以某种方式自动设置为10.0.2.2。

使用Fiddler无法看到此问题,因为在没有10.0.2.2解决方法的情况下,您可以获得127.0.0.1。

只有当我们使用10.0.2.2特殊IP并且Android应用程序中的Http客户端库自动将Host标头设置为IP时,才会发生这种情况。就我而言,我使用Retrofit由于Host标题10.0.2.2与127.0.0.1或localhost不同,因此Web API产生400无效的主机名。

然后我将Host标题覆盖到localhost:port,它只是起作用:

RestAdapter.Builder builder= new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
     @Override
     public void intercept(RequestFacade request) {
         if (HOST.contains("10.0.2.2")) { // HOST = "http://10.0.2.2/api";
             request.addHeader("Host", "localhost");
         }            
     }
 });

只需确保Android应用中的Host标题正确无误。

答案 1 :(得分:2)

尝试“wireshark”来捕获网络流量,看看出了什么问题。 然后尝试模拟使用wget或curl看到的HTTP请求。 这样你应该能够找出导致服务失败的原因。

答案 2 :(得分:1)

您的get请求完全可能失败,并且正在执行重定向到不存在的错误页面。该重定向可能不使用10.0.2.2 ip地址。

你看到它直接工作的常见原因(IE / Fiddler / Whatever)但你的应用程序中没有这种情况是因为应用程序实际上并没有通过其他方式发送完全相同的东西。

最好的办法是简单地让android记录或以其他方式显示它试图调用的确切查询字符串。然后确保您的外部测试正在执行该呼叫。

我会进一步调查您可能拥有的任何类型的标准错误页面,可能会将其关闭,直到您看到实际问题为止。