Одним из решений является использование универсального обработчика и передача обработки на сервер по асинхронному запросу. Вот шаг за шагом:
Первый:
Создайте универсальный обработчик в вашем веб-проекте . Добавьте файл ASHX со следующим кодом для вашего ProcessRequest ( упрощено для краткости ):
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<object>)rawResult))
{
result += r.ToString();
}
context.Response.Write(result);
}
Следует отметить, что существуют некоторые пространства имен, на которые вам понадобятся ссылки для обработки XML:
System.IO
System.Xml
System.Xml.XPath
System.Xml.Linq
Второй:
Вам нужен код, который позволил бы вам сделать асинхронную запись в общий обработчик. Код ниже является длинным, но по существу вы передаете следующее:
Uri вашего универсального обработчика
Словарь пар ключ-значение (при условии, что документ xml и xpath)
Обратные вызовы для успеха и неудачи
Ссылка на таймер отправки UserControl, чтобы вы могли получить доступ к своему пользовательскому интерфейсу (при необходимости) в обратных вызовах.
Вот код, который я поместил в служебный класс:
public class WebPostHelper
{
public static void GetPostData(Uri targetURI, Dictionary<string, string> dataDictionary, Action<string> onSuccess, Action<string> onError, Dispatcher threadDispatcher)
{
var postData = String.Join("&",
dataDictionary.Keys.Select(k => 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) =>
{
Stream stream = requ.EndGetRequestStream(ar);
StreamWriter writer = new StreamWriter(stream);
writer.Write(postData);
writer.Close();
requ.BeginGetResponse(new AsyncCallback(
(ar2) =>
{
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(() =>
{
onSuccess(result);
});
}
}
else
{
if (onError != null)
{
threadDispatcher.BeginInvoke(() =>
{
onError(result);
});
}
}
}
catch (Exception ex)
{
string data2 = ex.ToString();
}
}
), null);
}), null);
}
}
Третье:
Сделайте вызов вашему служебному классу и передайте xml и xpath:
private void testButton_Click(object sender, RoutedEventArgs e)
{
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("xml", "<Foo />");
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) =>
{
MessageBox.Show("Your result " + result);
},
(errMessage) =>
{
MessageBox.Show("An error " + errMessage);
},
this.Dispatcher);
}
Позвольте мне повторить, что код здесь упрощен для краткости . Возможно, вы захотите использовать сериализатор для передачи более сложных типов в и из вашего универсального обработчика. Вам нужно будет написать «защитные проверки» нулевой защиты защитным способом, когда вы получите значения из коллекции context.Request.Form. Но основная идея описана выше.