Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug HttpWebRequest or HttpWebResponse doesn't work well in Silverlight 2 beta1
35 replies. Latest Post by twinae on November 4, 2008.
(0)
mchlsync
Star
14606 points
2,730 Posts
03-14-2008 12:19 PM |
Hello,
I think that HttpWebRequest or HttpWebResponse doesn't work well in Silverlight 2 beta1 because I always got null in EndGetResponse().
The following code works well in C# winform but doesn't work in Silverlight 2 beta1.
private void InvokeAsync() { //http://msdn2.microsoft.com/en-us/library/system.net.httpwebrequest.begingetrequeststream.aspx string serviceURL = "http://localhost:52976/SL2Astoria_Web/WebDataService.svc/Products/"; pMessage = "{" + Environment.NewLine; pMessage += "ProductName:\"jetli\"" + Environment.NewLine; pMessage += "}" + Environment.NewLine; // Create a new HttpWebRequest object. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceURL); //// Set the ContentType property. request.ContentType = "application/json"; // Set the Method property to 'POST' to post data to the URI. request.Method = "POST"; // Start the asynchronous operation. request.BeginGetRequestStream(new AsyncCallback(ReadCallback), request); // Keep the main thread from continuing while the asynchronous // operation completes. A real world application // could do something useful such as updating its user interface. allDone.WaitOne(); // Get the response. request.BeginGetResponse(new AsyncCallback(ResponseCallback), request); } private static void ResponseCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse resp = (HttpWebResponse)request.EndGetResponse(asynchronousResult); Stream streamResponse = resp.GetResponseStream(); StreamReader streamRead = new StreamReader(streamResponse); string responseString = streamRead.ReadToEnd(); Console.WriteLine(responseString); // Close the stream object. streamResponse.Close(); streamRead.Close(); // Release the HttpWebResponse. resp.Close(); } private static void ReadCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; // End the operation. Stream postStream = request.EndGetRequestStream(asynchronousResult); string postData = pMessage; // Convert the string into a byte array. byte[] byteArray = Encoding.UTF8.GetBytes(postData); // Write to the request stream. postStream.Write(byteArray, 0, postData.Length); postStream.Close(); allDone.Set(); }
Am I missing something or Is that a bug?
jjy2
Member
354 points
155 Posts
03-14-2008 12:35 PM |
Hi mchlsync,
When I remove event object and called BeginGetResponse at the end of ReadCallback, it works ok.
I think it is something to do with SL threading stuff?
03-14-2008 12:49 PM |
I think also your event is already signalled so allDone.WaitOne() may be doesn't block anything?
(so that ResponseCallback called before request is sent)
Because when I call WaitOne, it blocks everything and it will just hang. I think this was one of threading issue some people were discussing about.
03-14-2008 1:18 PM |
Actually, I have tested this code in winform and it's working fine. but not in Silverlight.
jjy2:When I remove event object and called BeginGetResponse at the end of ReadCallback, it works ok.
I tried like that too but it doesn't work.
The reason that I put "allDone" is that it's for waiting the calling is completed.
jjy2:I think also your event is already signalled so allDone.WaitOne() may be doesn't block anything?
No. no. It blocks the thread. I'm not sure why I got null..
BeSilver
76 points
38 Posts
03-15-2008 4:36 AM |
Michael, try invoking the BeginGetResponse() method from within your BeginGetRequest() callback and get rid of the Wait handle. So do not invoke it in your main thread. Does it help?
03-15-2008 4:45 AM |
Two more things I've noticed: You might want to use a StreamWriter when writing to the request stream and I believe (I have not yet looked into it in a debugger), the problem with your code is, that the request in your main thread (the object itself) is not tied to the ones you're creating in the callbacks. You should really chain things from within your callbacks instead of returning the response execution back to your calling scope. Have you tried laying things out EXACTLY as in the tutorial on my blog (http://www.24100.net)? If this helps would be great if you mark my answer!
03-15-2008 4:47 AM |
thanks for your reply. I tried to do that. but it doesn't work.... I found other work around for dealing with Astoria in SL. but I just want to know whether HttpWebRequest and HttpWebResponse are working or not.
03-15-2008 7:39 AM |
Michael,
just to be 100% sure: You do have cross domain access policy files in the root of the servers your services are hosted on, don't you?
Also: If you email me the solution, I'd be happy looking into it and trying to identify what's the issue.
03-15-2008 9:25 AM |
BeSilver:just to be 100% sure: You do have cross domain access policy files in the root of the servers your services are hosted on, don't you?
It's in same domain.
BeSilver:Also: If you email me the solution, I'd be happy looking into it and trying to identify what's the issue.
Thanks a lot. I uploaded the zip file so that all other people also can also find out what the issue is. . Please download from this link. http://michaelsync.net/demo/SL2Astoria-HttpWebRequest-HttpWebResponse_Issue.zip
03-15-2008 10:07 AM |
I think you may have found a bug.
Try this,
<Grid x:Name="LayoutRoot" Background="White" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown" >
and call InvokeAsync from there. It then work. ??? It's something to with Button AGAIN??
03-15-2008 10:14 AM |
Nope sorry that was false alarm. I don't know I was changing something and once I got response stream right.
I now get null. Still testing
03-15-2008 10:36 AM |
What is the content type for json? Is it application/json correct?
application/x-www-form-urlencoded
03-15-2008 10:44 AM |
I think it is something to with IIS 7 after service pack 1 is patched??
03-15-2008 10:47 AM |
jjy2:what content type are we suppose to use???
We have to use "application/json" for content-type.
03-15-2008 10:52 AM |
jjy2:I think it is something to with IIS 7 after service pack 1 is patched??
I don't know .. what is that? The code that I provided is working fine if you are using in winform.
03-15-2008 10:57 AM |
mchlsync: think it is something to with IIS 7 after service pack 1 is patched??
No that was just mistake. One moment I thought I was running your app on using IIS7
How peculiar...
03-15-2008 11:08 AM |
This may be reason. I can't be sure.
It's may be lack of MIME type support in ASP.NET Development server. http://forums.asp.net/p/1230087/2217745.aspx
03-15-2008 11:13 AM |
jjy2:It's may be lack of MIME type support in ASP.NET Development server.
I'm not sure, man. but If casini doesn't support MIME then it should not work if I I use this code in C# winform, right? I created one win app and tried to invoke the web service. It's working fine. but not in SL. it's weird.
03-15-2008 11:49 AM |
mchlsync:. It's working fine. but not in SL. it's weird.
Agreed. It's maybe SL2's Special Feature
It works with IIS7 :)
03-15-2008 12:16 PM |
jjy2:It works with IIS7 :)
Are you sure about that? Does it insert the record to database? or you got the stream from response? I also have IIS7 in my vista home premium. I will test it..
03-15-2008 12:26 PM |
I thought you wanted know why response stream is null?I just removed Astoria stuff and let the Your default [web service] page to return string "AAA" and I got "AAA" I think IIS 6 should work arlight. if II7 works why not 6?
03-15-2008 2:33 PM |
I downloaded the solution and the Button did not even have an Event Handler attached to the Click event. Is the solution supposed to work?! :-)
03-15-2008 11:20 PM |
BeSilver:I downloaded the solution and the Button did not even have an Event Handler attached to the Click event. Is the solution supposed to work?! :-)
:) sorry about that. there were a lot of codes in my application so that I cleaned them up and I think I accidentally remove the event handler.. :)
I thought you wanted know why response stream is null?
I just removed Astoria stuff and let the Your default [web service] page to return string "AAA" and I got "AAA"
I think IIS 6 should work arlight. if II7 works why not 6?
Yes. I want to know why response steam is null. but I'm not sure why it doesn't work with Astoria. I'm very sure that Astoria service is working fine since I have tested. maybe, HttpWebRequest or HttpWebResponse are missing some features?
03-15-2008 11:32 PM |
mchlsync:Button did not even have an Event Handler attached to the Click event
However with the same thing when that App runs on IIS, It work with application/json MIME type. I think SL maybe reading MIME type from header when response is returned from server?? Maybe?? And it gives up because you requested json type but it returned OCTET type or something...??
03-16-2008 12:10 AM |
Hi Michael,
{
Response.StatusCode = 200;
Response.End();
}
03-16-2008 12:29 AM |
In short, answer to this is to
1. use IIS
2. make HTTP Handler or something if you don't have IIS
I gotta go, fat controller is looking for me
03-17-2008 7:28 PM |
Have you tried your app in IIS yet? I am not sure what I suggested was relevant to you,
Anyhow, It would be nice to hear from you if some hours of my study helped you somewhat.
03-18-2008 3:33 AM |
Hi jjy,
I haven't tried yet. but I mailed to Yi-lun (Microsoft) about this problem. I'm waiting his reply. I hope he will be able to confirm whether this is a known issue or not.
Thanks for your solution too. but it's a workaround, right? Hosting Astoria and SL on IIS instead of cassini, using web handler, using xmlhttprequest wrapper might solve the problem but those are workarounds. I would like to know whether this is my mistake in my coding or HttpWebRequest & HttpWebResponse are missing something. What do you say?
03-18-2008 4:20 AM |
It's good you did that Michael, It's always good to hear a defnite answer and avoid unnecessary workround whenever possible.
I read your latest blog, that seems a fine solution too.Thanks for letting me know :-)
mchlSync
03-18-2008 5:29 AM |
You are welcomed. jjy. I also like to say "thank you" for all of your replies too. :)
dworthem
68 points
32 Posts
03-23-2008 1:10 AM |
It appears that the AsyncCallback delegate handler for BeginGetRequestStream and BeginGetResponse runs on the same thread as the calling thread, the UI thread (ManagedThreadId of 1). I thought these were supposed to execute on another worker thread?
Dennis
Yi-Lun L...
All-Star
25052 points
2,747 Posts
03-25-2008 4:59 AM |
Hi, Michael, sorry for the late response. Got a lot of work these days.
I don’t know much about Astoria. But from Silverlight perspective, currently the only supported status are OK and Not Found. The limitation is due to the browser APIs that we use for networking requests. The NPAPI (Netscape Plug-in API, used by Firefox and Safari) only returns success/failure without providing the status code.
That said, your application works fine on the server. I can see the new record successfully added to the database. However, each time the response is null with a status “Not Found”. Then I turned on ASP.NET Tracing on the server, and found that the actual response’s status code is 201 Created. I think this is the desired behavior since indeed there was a new item created. Unfortunately 201 is not recognized by Silverlight… I think this may be the problem.
03-25-2008 5:15 AM |
HI Yi-Lun,
Thanks a lot for your response.
Yi-Lun Luo - MSFT:sorry for the late response. Got a lot of work these days.
No problem. :)
Yi-Lun Luo - MSFT:Then I turned on ASP.NET Tracing on the server, and found that the actual response’s status code is 201 Created. I think this is the desired behavior since indeed there was a new item created. Unfortunately 201 is not recognized by Silverlight… I think this may be the problem.
Oh. I see.. The problem occurred because of the status code 201. I didn't know that I got 201. I will try again.but actually, the "completed" event shouldn't be invoked if Sliverlight doesn't recognize this status code. Maybe, we should get the "failed" event instead.
Is this an issue of Silverlight or ASP.NET development server (casini)? I guess, it might be some issues with ASP.NET development server. Because if it's an issue of Silverlight, it should not work with IIS too.
Is there any workaround to make it work on ASP.NET development server (casini) ?
OR,
Will it be fixed in next release of VS service pack or Silverlight 2 beta2?
Thanks again.
03-25-2008 5:23 AM |
mchlsync:Is this an issue of Silverlight or ASP.NET development server (casini)? I guess, it might be some issues with ASP.NET development server. Because if it's an issue of Silverlight, it should not work with IIS too.
Maybe unsupported MIME type generates status code something rather than 200 in cassini?Michael, you were right. it's good to know definite answer :-)
03-25-2008 5:37 AM |
jjy2:Michael, you were right. it's good to know definite answer :-)
Yes. but it's also good to know the workarounds too. I want to say "thank you" for the workarounds that you mentioned. :)
twinae
26 points
19 Posts
11-04-2008 8:41 AM |
Hello, I am new with Silverlight and while trying to work with HttpWebRequest and ADO.Net Data Service I get the same problems mentioned here.I am working with the last release of Silverlight.Do you know if this issue was solved somehow in this final release?
Thank you in advance for the response.