【问题标题】:request.Method = "POST" working but NOT request.ContentLengthrequest.Method = "POST" 工作但不是 request.ContentLength
【发布时间】:2014-03-04 09:15:42
【问题描述】:

有时简单的事情会让你难过,这就是我的一个。

我想做一个简单的网络请求来验证用户名和密码。它在 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.

那么为什么我不能像 doco 所说的那样在标题中包含“POST”?任何帮助将不胜感激。

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

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

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

在响应 Domniks 对代码的请求时,我附上了带有错误消息的代码块图像。再次感谢您的帮助。 我已经附上了我的屏幕图像,它不会acc

【问题讨论】:

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


    【解决方案1】:

    您并没有真正发布信息,因为您的所有数据都在 URL 中。您可以尝试将方法更改为 GET,因为这就是您正在做的事情。或者您可以将发布数据写入请求对象的请求流并真正发布。请参阅here 以获取快速示例。

    【讨论】:

    • 感谢您的回复。 GET 给了我相同的结果,就好像我根本没有包含 request.Method 一样。网络响应给了我以下输出: {"logged_in":false,"success":null,"message":null,"full_login":null} 并且成功应该返回 true 或 false 而不是 null
    【解决方案2】:

    GET 参数像您的 URL 一样经过 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();
    

    【讨论】:

    • 感谢 Dominik,所以 loginParams 是整个 url 字符串,包括 ?username=me&password=v 吗?我怀疑是这样,所以我会试一试。再次感谢。
    • loginParams 只是您分配的字符串。 teamResponse 应该只是 URL,没有 loginParams。 loginParams = "username=" + logInUserIdString + "&amp;password=" + logInPasswordString;string teamResponse = "https://mysite.com/mystuff/LoginApp";
    • 是的,明白了。愚蠢的我,错误消息中的最后一行应该告诉我问题出在哪里。“远程服务器返回错误,需要长度”。有时我们会寻找复杂问题的复杂答案,而答案在 99% 的情况下非常简单,只是我们看不到而已。修复后,我将发布完整的答案。再次感谢您的帮助。
    • 仍在解决这个问题,似乎无法理解为什么我无法设置 httpwebrequest 的内容长度。我可以执行以下 request.Method = "POST" 但无法输入 request.ContentLength?
    • 我看到你更新了你的答案,但我没有看到任何设置 Content 或 ContentLength 的代码。能否请您添加它,以便我可以给出正确的答案。在我的程序中,我可以毫无问题地设置 ContentLength
    【解决方案3】:

    解决了!!!

    使用 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 的帮助,因为您的 cmets 将我带向了这个解决方案的方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 2014-07-04
      • 2018-10-16
      • 2017-11-27
      • 2018-02-06
      • 2014-06-23
      • 1970-01-01
      相关资源
      最近更新 更多