/// <summary> /// Helper method to read from a web service asynchronously. /// </summary> public static void OpenReadAsync(Uri uri, object userState, EventHandler <OpenReadEventArgs> callback, bool forceBrowserAuth = false, string proxyUrl = null) { System.Diagnostics.Debug.WriteLine(uri.ToString()); if (m_browserAuthInProgress) { m_openReadRequests.Enqueue(new RequestInfo(uri, userState, callback, forceBrowserAuth)); } else { string id = "hiddenSLViewerAuthFrame"; bool iframeExists = HtmlPage.Document.GetElementById(id) != null; if (!iframeExists || forceBrowserAuth) { m_browserAuthInProgress = true; // The portal may be PKI-secured. Try injecting an iframe into the HTML DOM to hit the portal endpoint. // In IE, this will force the browser to perform client certificate authentication. If the initial request // to the portal endpoint fails, the client cert auth will not occur, so we must try this first. // Insert the iframe var iframe = WebUtil.insertHiddenIFrame("hiddenSLViewerAuthFrame"); var loadErrorTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(10) }; // Create a handler for the iframe's onload event EventHandler onloadHandler = null; onloadHandler = (o, e) => { loadErrorTimer.Stop(); loadErrorTimer.Tick -= onloadHandler; iframe.DetachEvent("onload", onloadHandler); doOpenRead(uri, userState, callback); }; // Register the handler with the iframe's onload event and the load error timer's tick event iframe.AttachEvent("onload", onloadHandler); loadErrorTimer.Tick += onloadHandler; // Set the source of the iframe to make it hit the portal. Append ticks to circumvent caching. var tempUrl = uri.ToString() + "&r=" + DateTime.Now.Ticks; iframe.SetAttribute("src", tempUrl); // Start the load error timer. If the timer ticks, the onload handler will be called. This is needed // in scenarios where the iframe's onload event never fires. loadErrorTimer.Tick += onloadHandler; loadErrorTimer.Start(); } else { doOpenRead(uri, userState, callback); } } }