使用Windows 8手机应用的HttpWebRequest

4

当我尝试创建HttpWebRequest时,它会返回System.Net.ProtocolViolationException错误。

private void txtGo_Click(object sender, RoutedEventArgs e)
    {
        WebRequest client =
            WebRequest.Create("http://api.worldweatheronline.com/free/v1/weather.ashx?q=London&format=json&num_of_days=5&key=jdbcn8yuwebwybxjpqzzxyhy");
        client.ContentType = "application/json";
        client.BeginGetResponse(ReadWebRequestCallBack, client);
    }

    private void ReadWebRequestCallBack(IAsyncResult callBackResult)
    {
        var myRequest = (HttpWebRequest) callBackResult.AsyncState;
        if(myRequest != null)
        {
            try
            {
                var response = (HttpWebResponse)myRequest.EndGetResponse(callBackResult);
                txtContent.Text = response.StatusCode.ToString();
            }
            catch(WebException ex)
            {
                txtContent.Text = ex.Message;
            }
        }
    }

当我移除这一行代码 client.ContentType = "application/json"; 时,会出现一个不同的错误,如下所示。
 {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult  asyncResult)
  at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
  at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at MyClimate.MainPage.ReadWebRequestCallBack(IAsyncResult callBackResult)}
base: {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult as yncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.   <EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at MyClimate.MainPage.ReadWebRequestCallBack(IAsyncResult callBackResult)}
   Response: {System.Net.Browser.ClientHttpWebResponse}
   Status: UnknownError

移除 ContentType 后,仅出现了 远程服务器返回错误:未找到。 错误。 - user1618825
谢谢,我创建了控制台应用程序,它运行良好,但不支持Windows Phone 8。 - user1618825
2
是的,但这就是安装Wireshark的目的。这样你就可以看到网络流量。 - Jon Skeet
嗨,实际上我认为问题与网络有关。连接到API需要互联网连接。但是当我尝试在模拟器的Internet Explorer中访问Google时,它无法连接。那么这是否与互联网连接有关?如何配置模拟器的网络以连接到互联网? - user1618825
1
通过Visual Studio调试器检查响应头。我得到了与你相同的错误,并且返回的HTTP头具有一个名为X-Mashery-Error-Code的头,其值为ERR_504_GATEWAY_TIMEOUT错误。你看到了同样的东西吗? - Chris Koenig
显示剩余12条评论
3个回答

4
您会收到此错误 System.Net.ProtocolViolationException,是因为您没有任何Postget方法。希望这能帮助您。
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Uri);

        request.ContentType = "application/x-www-form-urlencoded";
        request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; Touch)";
        request.CookieContainer = cookie;
        request.AllowAutoRedirect = true;
        // Set the Method property to 'POST' to post data to the URI.
        request.Method = "POST";

        // start the asynchronous operation
        request.BeginGetRequestStream(new AsyncCallback(CRequest), request);

3

这里有三个问题。首先,移除 client.ContentType = "application/json";,因为您的请求方法是 GET,在 GET 中,ContentType 没有意义。
其次,检查模拟器的互联网连接,检查 Emulator 虚拟机的设置。

  • 在 Hyper-V 管理器中
  • 单击 Emulator 虚拟机设置
  • 单击 Windows Phone Emulator External Interface,选择其名称以您物理网络设备名称开头的虚拟交换机。

更多信息请参见Troubleshooting the Windows Phone 8 Emulator

enter image description here 第三个问题是从 UI 线程之外的另一个线程更新 UI 控件(TextBox)。

更改

   txtContent.Text = response.StatusCode.ToString();

to

   Deployment.Current.Dispatcher.BeginInvoke(() =>
   {
      txtContent.Text = response.StatusCode.ToString();
   });

+1,感谢点赞。问题是由于网络原因,需要点击模拟器虚拟机设置。 - user1618825

0

您可以像这样使用,它将适用于您的代码

只需在txtGo_click按钮中编写client.ContentType =“application/x-www-form-urlencoded”;client.Method =“POST”; ,并在您的代码中使用此方法即可

    private void ReadWebRequestCallBack(IAsyncResult callBackResult)
    {
        var myRequest = (HttpWebRequest)callBackResult.AsyncState;
        if (myRequest != null)
        {
            try
            {
                HttpWebResponse response = (HttpWebResponse)myRequest.EndGetResponse(callBackResult);
                Dispatcher.BeginInvoke(delegate() { txtContent.Text = response.StatusCode.ToString(); });
            }
            catch (WebException ex)
            {
                Dispatcher.BeginInvoke(delegate() { txtContent.Text = ex.Message; });
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接