Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>One solution is to use a generic handler and outsource the processing to the server on an asynchronous request. Here is a step by step: </p> <p><strong>First:</strong></p> <p>Create a generic handler in your <strong><em>web project</em></strong>. Add an ASHX file with the following code for your ProcessRequest (<em>simplified for brevity</em>): </p> <pre><code> public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string xml = context.Request.Form["xml"].ToString(); string xpath = context.Request.Form["xpath"].ToString(); XmlReader reader = new XmlTextReader(new StringReader(xml)); XDocument doc = XDocument.Load(reader); var rawResult = doc.XPathEvaluate(xpath); string result = String.Empty; foreach (var r in ((IEnumerable&lt;object&gt;)rawResult)) { result += r.ToString(); } context.Response.Write(result); } </code></pre> <p>It should be noted that there are some namespaces you will need references to for xml processing: </p> <ol> <li><p>System.IO</p></li> <li><p>System.Xml</p></li> <li><p>System.Xml.XPath</p></li> <li><p>System.Xml.Linq</p></li> </ol> <p><strong>Second:</strong> </p> <p>You need some code that would allow you to make an asynchronous post to the generic handler. The code below is lengthy, but essentially you pass the following:</p> <ol> <li><p>The Uri of your generic handler</p></li> <li><p>A dictionary of key value pairs (assuming the xml document and the xpath)</p></li> <li><p>Callbacks for success and failure</p></li> <li><p>A reference to the dispatch timer of the UserControl so that you can access your UI (if necessary) in the callbacks.</p></li> </ol> <p>Here is some code I've placed in a utility class: </p> <pre><code>public class WebPostHelper { public static void GetPostData(Uri targetURI, Dictionary&lt;string, string&gt; dataDictionary, Action&lt;string&gt; onSuccess, Action&lt;string&gt; onError, Dispatcher threadDispatcher) { var postData = String.Join("&amp;", dataDictionary.Keys.Select(k =&gt; k + "=" + dataDictionary[k]).ToArray()); WebRequest requ = HttpWebRequest.Create(targetURI); requ.Method = "POST"; requ.ContentType = "application/x-www-form-urlencoded"; var res = requ.BeginGetRequestStream(new AsyncCallback( (ar) =&gt; { Stream stream = requ.EndGetRequestStream(ar); StreamWriter writer = new StreamWriter(stream); writer.Write(postData); writer.Close(); requ.BeginGetResponse(new AsyncCallback( (ar2) =&gt; { try { WebResponse respStream = requ.EndGetResponse(ar2); Stream stream2 = respStream.GetResponseStream(); StreamReader reader2 = new StreamReader(stream2); string responseString = reader2.ReadToEnd(); int spacerIndex = responseString.IndexOf('|') - 1; string status = responseString.Substring(0, spacerIndex); string result = responseString.Substring(spacerIndex + 3); if (status == "success") { if (onSuccess != null) { threadDispatcher.BeginInvoke(() =&gt; { onSuccess(result); }); } } else { if (onError != null) { threadDispatcher.BeginInvoke(() =&gt; { onError(result); }); } } } catch (Exception ex) { string data2 = ex.ToString(); } } ), null); }), null); } } </code></pre> <p><strong>Third:</strong></p> <p>Make the call to your utility class and pass your xml and xpath: </p> <pre><code> private void testButton_Click(object sender, RoutedEventArgs e) { Dictionary&lt;string, string&gt; values = new Dictionary&lt;string, string&gt;(); values.Add("xml", "&lt;Foo /&gt;"); values.Add("xpath", "/*"); //Uri uri = new Uri("http://eggs/spam.ashx"); Uri uri = new Uri("http://localhost:3230/xPathHandler.ashx"); WebPostHelper.GetPostData(uri, values, (result) =&gt; { MessageBox.Show("Your result " + result); }, (errMessage) =&gt; { MessageBox.Show("An error " + errMessage); }, this.Dispatcher); } </code></pre> <p>Let me reiterate that the code here is <strong><em>simplified for brevity</em></strong>. You may want to use a serializer to pass more complex types to and from your generic handler. You will need to write null guard "sanity checks" in a defensive way when you get values from the context.Request.Form collection. But the basic idea is as documented above.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload