request.Method = "POST" working but NOT request.ContentLength

Some times the simple things can stump you and here is one for me.

I want to do a simple web request to verify a username and password. Its working just fine in Windows Phone 8 but I can not seem to get the same code to work on Windows 8.

I understand I can not do a GetResponse as I do with Windows Phone so I am using GetResponseAsync and that part if working fine. But the response from the Server is that it did not get the "POST" component in the header.

Here is the Windows Phone 8 code that is working fine on my Phone version

 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");

Here is what I have for Windows 8 using Visual Studio 2013

 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);
         }

That works but I get back a simple response advising only that the user is logged in or not logged in. The Server chap says that the request did not have "POST" in the header.

SO I added the following code:

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

And here is the full code:

 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);
         }

And then it just throws the following:

'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.

So why can I not include the "POST" in the header as the doco says I can? Any help would be much appreciated.

UPDATE: I now know its an issue with the length of the loginParams. In my IOS, Android and WindowsPhone apps I did not have to specify the length and it works great, but the Visual Studio 2013 Windows App does not accept setting the content length for some reason.

Here is the error: System.Net.HttpWebRequest does not contain a definition for ContentLength and no extension method ContentLength accepting a fist argument of type System.Net.HttpWebRequest could be found (are you missing a using directive or an assembly reference?)

So why can I not add request.ContentLength???

IN Response to Domniks request for the code I have attached a image of the block of code with the error message. Thanks again for helping. I have attached an image of my screen where it wont acc

Answers


You are not really posting information since all your data is in the URL. You can try changing the method to GET, because that is what you are doing. Or you can write the post data to the request object's request stream and really POST. See here for quick example.


GET Parameter are URL-encoded like your URL: "https://mysite.com/mystuff/LoginApp?" + loginParams That means you are always sending GET Parameter, just changing the Method do POST wont change anything. If you want to send POST Parameters, do the following:

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

Solved!!!

The correct process to do Http web requests and response with Visual Studio 2013 is to use the new HttpClient class. I suspected it would be some new class like this but just could not find it. 2 days of my life have been wasted!!

So here is the correct code to do a Http request to for example log in or in my case to just verify the user is a valid user based on the userID and password.

 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);
            }

And thanks heaps to dbugger and Dominik for your help as your comments moved me in the direction that got me to this solution.


Need Your Help

Scanning a single character in c

c char scanf

I have used the following code snippet to read several values but the single character constant variable rating is not accepting any value. It doesn't execute that particular scanf statement. How to