request.Method =“POST”工作但不是request.ContentLength

时间:2014-02-28 02:25:49

标签: c# xaml visual-studio-2013 windows-8.1

有时候简单的事情可能会让你感到困惑,这里有一个对我来说。

我想做一个简单的网络请求来验证用户名和密码。它在Windows Phone 8中运行得很好,但我似乎无法在Windows 8上使用相同的代码。

据我所知,我无法像使用Windows Phone一样进行GetResponse,所以我使用的是GetResponseAsync,如果工作正常则该部分。但是服务器的响应是它没有在标题中获得“ POST ”组件。

以下是在我的手机版

上正常运行的Windows Phone 8代码
 private async void VerifyUser()
        {
            //System.Diagnostics.Debug.WriteLine("aa"); 

            loginParams = "username=" + username + "&password=" + password;
            string teamResponse = "https://mysite.com/mystuff/LoginApp?" + loginParams;

            var request = HttpWebRequest.Create(teamResponse) as HttpWebRequest;
            request.Method = "POST";
            request.Accept = "application/json;odata=verbose";

            var factory = new TaskFactory();
            var task = factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);

            //System.Diagnostics.Debug.WriteLine("bb"); 


            try
            {
                var response = await task;

                System.IO.Stream responseStream = response.GetResponseStream();
                string data;
                using (var reader = new System.IO.StreamReader(responseStream))
                {
                    data = reader.ReadToEnd();
                }
                responseStream.Close();
                //System.Diagnostics.Debug.WriteLine("cc"); 
                webData = data;
                //MessageBox.Show(data);
            }
            catch (Exception e)
            {
                MessageBox.Show("There was a network error.  Please check your network connectivty and try again " + e);
            }

           // System.Diagnostics.Debug.WriteLine(webData);
            JToken token = JObject.Parse(webData);
            string success = (string)token.SelectToken("success");

以下是我使用Visual Studio 2013的Windows 8的内容

 private async void VerifyUser()
         {
            string data;      
            loginParams = "username=" + logInUserIdString + "&password=" + logInPasswordString;
            string teamResponse = "https://mysite.com/mystuff/LoginApp?" + loginParams;
            Debug.WriteLine(teamResponse);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(teamResponse);

            HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                data = sr.ReadToEnd();
            }

            Debug.WriteLine(data);
         }

这有效,但我得到一个简单的回复,建议用户登录或未登录。服务器的章节说请求标题中没有“POST”。

所以我添加了以下代码:

request.Method = "POST";
request.Accept = "application/json;odata=verbose";

这是完整的代码:

 private async void VerifyUser()
         {
            string data;      
            loginParams = "username=" + logInUserIdString + "&password=" + logInPasswordString;
            string teamResponse = "https://mysite.com/mystuff/LoginApp?" + loginParams;
            Debug.WriteLine(teamResponse);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(teamResponse);
            request.Method = "POST";
            request.Accept = "application/json;odata=verbose";
            HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                data = sr.ReadToEnd();
            }

            Debug.WriteLine(data);
         }

然后它只是抛出以下内容:

'web1.exe' (CLR v4.0.30319: Immersive Application Domain): Loaded 'C:\Windows\system32\WinMetadata\Windows.Foundation.winmd'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
A first chance exception of type 'System.Net.WebException' occurred in mscorlib.dll
An exception of type 'System.Net.WebException' occurred in mscorlib.dll but was not handled in user code
Additional information: The remote server returned an error: (411) Length Required.

那么为什么我不能在标题中包含“POST”,因为doco说我可以?任何帮助将不胜感激。

更新:我现在知道它与loginParams的长度有关。在我的IOS,Android和WindowsPhone应用程序中,我没有必要指定长度并且效果很好,但Visual Studio 2013 Windows应用程序不接受因某种原因设置内容长度。

这是错误: System.Net.HttpWebRequest不包含ContentLength的定义,也没有扩展方法ContentLength接受类型System.Net.HttpWebRequest的第一个参数可以找到(你是否缺少using指令或程序集引用?)

那为什么我不能添加request.ContentLength ???

响应Domniks对代码的请求,我附上了带有错误消息的代码块的图像。再次感谢您的帮助。 enter image description here 我附上了我的屏幕图像,它不会被识别

3 个答案:

答案 0 :(得分:1)

由于您的所有数据都在网址中,因此您并未真正发布信息。您可以尝试将方法更改为GET,因为这就是您正在做的事情。或者您可以将发布数据写入请求对象的请求流并实际POST。有关快速示例,请参阅here

答案 1 :(得分:1)

GET参数的URL编码类似于您的网址:"https://mysite.com/mystuff/LoginApp?" + loginParams 这意味着你总是发送GET参数,只是改变方法做POST不会改变任何东西。 如果要发送POST参数,请执行以下操作:

byte[] bytes = Encoding.UTF8.GetBytes(loginParams);
request.ContentLength = bytes.Length;
Stream stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
stream.Close();

答案 2 :(得分:1)

解决!!!

使用Visual Studio 2013执行Http Web请求和响应的正确过程是使用新的HttpClient类。我怀疑这将是一些像这样的新课,但却找不到它。我生命中的两天都被浪费了!!

所以这是执行Http请求的正确代码,例如登录或在我的情况下,只是根据用户ID和密码验证用户是否是有效用户。

 private async void VerifyUser()
         {
            loginParams = "username=" + logInUserIdString + "&password=" + logInPasswordString;
            string teamResponse = "https:// mySite.com?" + loginParams;
            Debug.WriteLine(teamResponse);

            HttpClient client = new HttpClient();

            try
            {
                HttpResponseMessage response = await client.PostAsync(new Uri(teamResponse), null);

                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();

                Debug.WriteLine(responseBody);
            }
            catch (HttpRequestException e)
            {
                Debug.WriteLine("\nException Caught!");
                Debug.WriteLine("Message :{0} ", e.Message);
            }

感谢dbugger和Dominik的帮助,因为你的评论让我朝着这个解决方案的方向前进。