Skip to main content
Home Forums Silverlight Programming Programming with .NET - General Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
25 replies. Latest Post by fatihpiristine on April 1, 2009.
(0)
jackbond
Contributor
2820 points
725 Posts
03-13-2008 8:00 AM |
I used to send a notification message via web services when a user navigated away from my silverlight app, but with the shift to async services, the app would exit before my call had a chance to complete. So I took the time to write the following managed wrapper for XmlHttpRequest. It won't work in browsers that don't expose XmlHttpRequest, but it's better than nothing.
{
}
//Here's how I use it:
mchlSync
Star
14606 points
2,730 Posts
03-13-2008 9:02 AM |
Hey Jack,
that's so cool, man... I'm gonna try your code.. thanks a lot for that.. Is it possible for you to attach the project?
03-13-2008 3:44 PM |
mchlSync:Is it possible for you to attach the project?
Sorry, I can't attach the entire project, you can see it though at www.ascendingintegration.com/khetdemo As far as I know, it's still the only multi-user online Silverlight game. I've tested "SyncToTheRescue" on Firefox 2.0.0.12 and IE7, but don't have access to a Mac. Any Mac users out there willing to test it out?
ot42
Member
40 points
21 Posts
03-14-2008 5:56 PM |
Thanks so much!
I really hope that MS will put the option of making synchronous calls back into SL2 at some point, but until then, your code is a life saver.
03-14-2008 7:31 PM |
ot42: Thanks so much! I really hope that MS will put the option of making synchronous calls back into SL2 at some point, but until then, your code is a life saver.
Thanks for the feedback, and I'm glad it's helping you out.
JohnSpur...
94 points
28 Posts
03-14-2008 9:43 PM |
jackbond:...but don't have access to a Mac. Any Mac users out there willing to test it out?
timstallc
260 points
36 Posts
03-15-2008 4:20 PM |
Hey - this is great, thanks. I'm trying to make a simplied method - one that just downloads an xml file (doesn't even do the extra work of calling a web service). I was able to modify your code to work in IE, but it just returns null in fireFox. The goal is to have a single, sync, static method that just gets the xml file for you. For example, you request a local xml file on your own web server, specify the appropriate URL, and it returns the file content. Do you know what I'm doing wrong such that this doesn't work with FireFox?
public static string DownloadXmlStringSync(string url) { ScriptObject _XMLHttpRequest; StringBuilder _Body; XmlWriter _Writer; StringBuilder _Result = new StringBuilder(); try { _XMLHttpRequest = HtmlPage.Window.CreateInstance("XMLHttpRequest"); _Body = new StringBuilder(); _Writer = XmlWriter.Create(_Result); _XMLHttpRequest.Invoke("open", "GET", url, false); _XMLHttpRequest.Invoke("setRequestHeader", "Content-Type", "text/xml; charset=utf-8"); _Writer = XmlWriter.Create(_Result); _Writer.WriteStartDocument(); _Writer.WriteStartElement("soap", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/"); _Writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); _Writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); _Writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/"); _Writer.WriteEndDocument(); _Writer.Flush(); _XMLHttpRequest.Invoke("send", _Result.ToString()); ScriptObject dom = (ScriptObject)_XMLHttpRequest.GetProperty("responseXML"); string strXml = (string)dom.GetProperty("xml"); return strXml; } catch (Exception ex) { throw; } }
03-15-2008 10:02 PM |
I have not tested this extensively. Let me know if it works for you.
03-15-2008 10:49 PM |
Thanks for the reply. It works great in IE, but it still fails in FireFox. Except, now it throws an exception (instead of just returning null).
It fails on this line:
_XMLHttpRequest.Invoke("send");
And throws this exception:
[System.InvalidOperationException] {System.InvalidOperationException: [ScriptObject_InvokeFailed]Arguments:Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=8.0.30226.2&File=System.Windows.Browser.dll&Key=ScriptObject_InvokeFailed at System.Windows.Browser.ScriptObject.Invoke(String name, Object[] args) at Stall.SilverlightUtilities.XmlHelper.DownloadXmlStringSync(String url) at Stall.Test.Page.Button_Click(Object sender, RoutedEventArgs e)} System.InvalidOperationException
I'd be appreciative for any ideas.
Thanks again,
03-15-2008 10:54 PM |
Which version of Firefox is it failing on? It worked for me on Firefox 3.
03-16-2008 12:00 AM |
Good point. I'm using FireFox 2.0. In more detail: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
I think many of my users would still be using 2.0, so I can't ask them all to upgrade.
Thanks,
03-16-2008 12:19 AM |
Try this:
03-16-2008 2:50 PM |
Thanks for the new code. It works great in IE, but still no luck in FireFox 2.0.
It fails again on the same like:
request.Invoke(
Similar error:
[ScriptObject_InvokeFailed]\r\nArguments:\r\nDebugging resource strings are unavailable
I see what you're trying to do, and it makes sense (calling XmlHttpRequest, similar to what ajax does in a browser), but still no luck on FF 2.0. Is there anything else I can provide to shed some light?
03-16-2008 6:08 PM |
Hi Tim,
I've got so many dev environments, that I got mixed up which version of Firefox I was running. It is actually working on Firefox 2.0.0.12 for me with the following code:
Are you able to set a breakpoint on the server to see if the request is actually making it through?
mchlsync
03-16-2008 9:58 PM |
I used this wrapper for communicating with Astoria from Silverlight (You can read it here.) Some said that they are having the problem..
I get the following error when deleting or updating
An exception of type ‘System.ArgumentException’ occurred in System.Windows.Browser.dll but was not handled in user code
Additional information: [ScriptObject_TypeDoesNotExist] Arguments:XMLHttpRequest Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=8.0.30226.2&File=System.Windows.Browser.dll&Key=ScriptObject_TypeDoesNotExist
I can’t retrieve the data too, error on this line _xmlHttpRequest = HtmlPage.Window.CreateInstance(”XMLHttpRequest”);
{System.ArgumentException: [ScriptObject_TypeDoesNotExist] Arguments:XMLHttpRequest Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=8.0.30226.2&File=System.Windows.Browser.dll&Key=ScriptObject_TypeDoesNotExist Parameter name: typeName at System.Windows.Browser.HtmlWindow.CreateInstance(String typeName, Object[] args) at SL2Astoria.XMLHttpRequestWrapper.DoPost(Uri url, String httpVerb, String param) at SL2Astoria.XMLHttpRequestWrapper.DoPost(Uri url, String httpVerb) at SL2Astoria.Page.retrieveButton_Click(Object sender, RoutedEventArgs e)}
Actually, I mentioned three operations (Insert, delete and retrieve) in that article. that guy is having some problems in deleting. I'm not sure why. It is working on my machine..
03-17-2008 12:16 AM |
Tim, I think you are going to be VERY happy when you run this code:
As for why it worked for some people and not others: Firebug has its own observer effect
03-17-2008 10:14 AM |
Yes! Works perfectly in both. I also love how clean and simple it now is.
Thanks so much
Psychlis...
6040 points
973 Posts
03-17-2008 10:21 AM |
Very nicely done. :)
For other folks who may stumble on this code in the future, though, it should be said that this doesn't support some of new things in SL2 like cross-domain policies or anything MSFT does with secure service calls in the future. Often not a deal-killer, but useful to know.
Pete
03-17-2008 4:44 PM |
Psychlist1972:it should be said that this doesn't support some of new things in SL2 like cross-domain policies or anything MSFT does with secure service calls in the future.
Unfortunate, but true. I developed this code because there was no way to call a web service during application exit. I actually hope in the next beta, or sometime before RTM this code becomes entirely irrelevant. I fear however that this code is going to get a lot of usage.
vchoudhary
14 points
15 Posts
05-01-2008 6:06 AM |
If I want to use this code in an application that uses cross domain policies,then what changes should I make in the code so that the code works properly.
Or is there any other method by which the same error gets removed in application that uses cross domain policies
fatihpir...
8 points
4 Posts
01-20-2009 6:36 PM |
code is below
samcov
Participant
969 points
379 Posts
01-20-2009 6:46 PM |
Could you format that better, or attach a project?
Sam...
01-20-2009 7:01 PM |
I have modified the code to make it work with ie6, ie5.5 etc. here is the code. have test on IE6, IE7, FF2, FF3, Opera and Safari. worked fine. you may need clientaccesspolicy.xml link: http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx namespace SyncCall { public class AjaxCall { protected static System.Windows.Browser.ScriptObject XMLHttpRequest; protected static System.String Result = System.String.Empty; /// <summary> /// Makes XMLHttpRequest /// </summary> /// <param name="Url">relative or absolute url as string</param> /// <param name="Method">GET or POST</param> public static void MakeCall(string Url, string Method) { // Backward compat System.Windows.Browser.HtmlPage.Window.Eval("if(typeof XMLHttpRequest==\"undefined\"){XMLHttpRequest=function(){var a=[\"Microsoft.XMLHTTP\",\"MSXML2.XMLHTTP\",\"MSXML2.XMLHTTP.3.0\",\"Msxml3.XMLHTTP\"];for(var b=0;b<a.length;b++){try{return new ActiveXObject(a[ b ]);}catch(ex){}}};}"); // create the instance XMLHttpRequest = System.Windows.Browser.HtmlPage.Window.CreateInstance("XMLHttpRequest"); // request data from server XMLHttpRequest.Invoke("open", Method.ToUpper(), Url, false); // send. !!! do not replace it with "null" as it throws exception XMLHttpRequest.Invoke("send", ""); // get result as string. as gecko based browsers does not return xml Result = XMLHttpRequest.GetProperty("responseText").ToString(); } /// <summary> /// Returns result from request as string /// </summary> public static System.String GetResult() { return Result.ToString(); } } }
namespace SyncCall { public class AjaxCall { protected static System.Windows.Browser.ScriptObject XMLHttpRequest; protected static System.String Result = System.String.Empty; /// <summary> /// Makes XMLHttpRequest /// </summary> /// <param name="Url">relative or absolute url as string</param> /// <param name="Method">GET or POST</param> public static void MakeCall(string Url, string Method) { // Backward compat System.Windows.Browser.HtmlPage.Window.Eval("if(typeof XMLHttpRequest==\"undefined\"){XMLHttpRequest=function(){var a=[\"Microsoft.XMLHTTP\",\"MSXML2.XMLHTTP\",\"MSXML2.XMLHTTP.3.0\",\"Msxml3.XMLHTTP\"];for(var b=0;b<a.length;b++){try{return new ActiveXObject(a[ b ]);}catch(ex){}}};}"); // create the instance XMLHttpRequest = System.Windows.Browser.HtmlPage.Window.CreateInstance("XMLHttpRequest"); // request data from server XMLHttpRequest.Invoke("open", Method.ToUpper(), Url, false); // send. !!! do not replace it with "null" as it throws exception XMLHttpRequest.Invoke("send", ""); // get result as string. as gecko based browsers does not return xml Result = XMLHttpRequest.GetProperty("responseText").ToString(); } /// <summary> /// Returns result from request as string /// </summary> public static System.String GetResult() { return Result.ToString(); } } }
01-21-2009 2:09 AM |
This appears to only be able to do a "GET", request, and not a "POST".
kobruleht
159 points
572 Posts
04-01-2009 11:01 AM |
I tried to call it at application exit event handler using
AjaxCall.MakeCall("Stockservice.asmx", "Logout");
but got InvalidOperationException at line
Andrus.
System.InvalidOperationException was unhandled by user code Message="Invalid argument." StackTrace: at System.Windows.Browser.ScriptObject.Invoke(String name, Object[] args) at SyncCall.AjaxCall.MakeCall(String Url, String Method) at AWSilverlightLOB.App.Application_Exit(Object sender, EventArgs e) at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args) at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName) InnerException:
04-01-2009 4:46 PM |
is it happening when you closing the browser window? if yes, on browser exit, it disposes everything before it exists.
i can suggest you to do one thing to try this out, run your solution with firefox, from firebug modify silverlight object position property to absolute,
it will exit and run the application again, if you are not getting this error, then it is related to browser window.