Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Very light weight XmlHttpRequest wrapper - Make synchro... RSS

32 replies

Last post Mar 17, 2011 03:04 AM by LanceM

(0)
  • jackbond

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

  • mchlSync

    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?  

    (If this has answered your question, please click on "Mark as Answer" on this post. Thank you!)

    Regards,
    Michael Sync
    Silverlight MVP

    Blog : http://michaelsync.net
  • jackbond

    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

    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

    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

    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

    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.

  • JohnSpurlock

    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

    jackbond

    ...but don't have access to a Mac. Any Mac users out there willing to test it out?
    The code above also works using FF2 & Safari3 on mac os 10.4 and 10.5. Hope that helps, - John
  • timstallc

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

        }

    Tim Stall
    http://timstall.dotnetdevelopersjournal.com
  • jackbond

    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;

    }

    }

  • timstallc

    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,

     

    Tim Stall
    http://timstall.dotnetdevelopersjournal.com
  • jackbond

    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.