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.
public class
SyncToTheRescue
{
ScriptObject
_XMLHttpRequest;
StringBuilder
_Body;
XmlWriter _Writer;StringBuilder
_Result =
new StringBuilder();
public SyncToTheRescue(string
url, string
nspace, string
method)
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?
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?
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,
Tim Stall
http://timstall.dotnetdevelopersjournal.com
jackbond
Contributor
5812 Points
1559 Posts
Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 13, 2008 12:00 PM | LINK
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.
public class SyncToTheRescue{
ScriptObject _XMLHttpRequest; StringBuilder _Body; XmlWriter _Writer;StringBuilder _Result = new StringBuilder();
public SyncToTheRescue(string url, string nspace, string method){
_XMLHttpRequest = HtmlPage.Window.CreateInstance("XMLHttpRequest"); _Body = new StringBuilder(); _Writer = XmlWriter.Create(_Result); _XMLHttpRequest.Invoke("open", "POST", url, false); _XMLHttpRequest.Invoke("setRequestHeader", "Content-Type", "text/xml; charset=utf-8"); _XMLHttpRequest.Invoke("setRequestHeader", "SOAPAction", string.Concat(nspace, method)); _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.WriteStartElement(null, method, nspace); }public void AddArgument(string arg, string val){
_Writer.WriteStartElement(arg); _Writer.WriteValue(val);_Writer.WriteEndElement();}
public string Send(){
_Writer.WriteEndDocument(); _Writer.Flush(); _XMLHttpRequest.Invoke("send", _Result.ToString()); ScriptObject dom = (ScriptObject)_XMLHttpRequest.GetProperty("responseXML");return (string)dom.GetProperty("xml");}
}
//Here's how I use it:
SyncToTheRescue sttr = new SyncToTheRescue("KhetServices.asmx", "http://tempuri.org/", "LeaveRoom"); sttr.AddArgument("roomId", roomId); sttr.Send();Khet - The first Silverlight multiplayer game
Zork I: The Great Underground Empire
mchlSync
Star
14968 Points
2799 Posts
Re: Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 13, 2008 01:02 PM | LINK
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?
Regards,
Michael Sync
Silverlight MVP
Blog : http://michaelsync.net
jackbond
Contributor
5812 Points
1559 Posts
Re: Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 13, 2008 07:44 PM | LINK
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?
Khet - The first Silverlight multiplayer game
Zork I: The Great Underground Empire
ot42
Member
40 Points
21 Posts
Re: Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 14, 2008 09:56 PM | LINK
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.
jackbond
Contributor
5812 Points
1559 Posts
Re: Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 14, 2008 11:31 PM | LINK
Thanks for the feedback, and I'm glad it's helping you out.
Khet - The first Silverlight multiplayer game
Zork I: The Great Underground Empire
JohnSpurlock
Member
94 Points
28 Posts
Re: Very light weight XmlHttpRequest wrapper - Make synchronized web service calls again
Mar 15, 2008 01:43 AM | LINK
timstallc
Member
260 Points
36 Posts
How to make this just return an xml string (not even call a web service)?
Mar 15, 2008 08:20 PM | LINK
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;
}
}
http://timstall.dotnetdevelopersjournal.com
jackbond
Contributor
5812 Points
1559 Posts
Re: How to make this just return an xml string (not even call a web service)?
Mar 16, 2008 02:02 AM | LINK
I have not tested this extensively. Let me know if it works for you.
public static string DownloadXmlStringSync(string url){
ScriptObject request; try{
request = HtmlPage.Window.CreateInstance("XMLHttpRequest"); request.Invoke("open", "GET", url, false); request.Invoke("send");return (string)request.GetProperty("responseText");}
catch (Exception ex){
throw;}
}
Khet - The first Silverlight multiplayer game
Zork I: The Great Underground Empire
timstallc
Member
260 Points
36 Posts
Re: How to make this just return an xml string (not even call a web service)?
Mar 16, 2008 02:49 AM | LINK
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,
http://timstall.dotnetdevelopersjournal.com
jackbond
Contributor
5812 Points
1559 Posts
Re: How to make this just return an xml string (not even call a web service)?
Mar 16, 2008 02:54 AM | LINK
Which version of Firefox is it failing on? It worked for me on Firefox 3.
Khet - The first Silverlight multiplayer game
Zork I: The Great Underground Empire