Calling service using SOAP message (.NET)

If you need to call a web service at low-level this is a good post for you.

For this purpose, you have to use HttpWebRequest and HttpWebResponse for treating the call. With Visual Studio’s auto-generated proxy for calling web methods of a web service hides the communication language between client and server. You do not have any control about the SOAP message generated. The only way is to call web methods using low-level protocol (HttpRequest)

Look an example below:


HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("<<Url of your web method>>");

request.Headers["SOAPAction"] = <<web method URI>>;
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Accept = "text/xml";
request.Method = "POST";

As you can see I have created the request using the information related to the web service. Next step is to build the SOAP Envelope

//Global variable for helping

static string soapEnvelope = @"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Header></soap:Header><soap:Body></soap:Body></soap:Envelope>";


StringBuilder sb = new StringBuilder(soapEnvelope);
sb.Insert(sb.ToString().IndexOf("</soap:Header>"), String.Format("<AuthorizationToken xmlns=\"<<some URI>>"><Token>{0}</Token></AuthorizationToken>", authToken.Token));
sb.Insert(sb.ToString().IndexOf("</soap:Body>"), String.Format("<YOURMethod xmlns=\"<<some URI>>"><Parameter1>{0}</Parameter1><Parameter2>{1}</Parameter2></YOURMethod>", serviceName, methodName));

XDocument soapEnvelopeXml = XDocument.Parse(sb.ToString());

 

And finally, make the call


IAsyncResult result = request.BeginGetRequestStream((IAsyncResult asynchronousResult) =>
{

//inserting soap message in the request

using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
{
soapEnvelope.Save(postStream);
postStream.Close();
}

request.BeginGetResponse(new AsyncCallback(asyncresult =>
{
XElement res = null;
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
XDocument res = XDocument.Parse(responseString);
XNamespace ns = "<<your namespace>>";

streamResponse.Close();
streamRead.Close();

response.Close();

XElement results = res.Descendants(ns + "<<your method name>>Response").FirstOrDefault();
if (results == null)
{
}
else
{
res =  results.Elements().FirstOrDefault();
}
}), request);
}, null);

 

MediaElement y reproducir sonido en Windows Store y Windows Phone

Como ya dice el título, MediaElement es un control que nos permite reproducir sonido tanto en aplicaciones Windows Phone (MediaElement para Windows Phone) como en aplicaciones Windows Store (MediaElement para Windows Store). Con mi experiencia quiero contar algunas cosas respecto a este control.

Primero, en Windows Phone tiene algún que otro fallo, a veces no reproduce el sonido, sobretodo si la aplicación está trabajando duro, no sé, quizá cuando está cargando el archivo de audio.

Otro problema es si tenemos más de un MediaElement que quieren reproducir sonido declarados en XAML; en cuanto activamos el segundo el primero deja de reproducir. En este escenario debemos usar XNA Framework para reproducir el sonido.

También, la reproducción continua del mismo, por ejemplo un botón que al pulsar reproduce un sonido, si lo pulsamos muchas veces y de forma continua el sonido de la nueva pulsación corta la del anterior.

A favor debo decir que es la forma más fácil que tenemos de reproducir sonido en Windows Phone, con el permiso del control de comportamiento PlaySoundAction.

Segundo, en Windows Store es más estable. No he detectado en ningún momento que deje de reproducir sonido pase lo que pase.

Además, ya no tenemos el problema de que si hay más de un control MediaElement uno deja de hacer reproducir el otro. Es decir, en Windows Store podemos reproducir varios MediaElement a la vez.

Pero, SI continua el problema del botón que se pulsa repetitivamente y con mucha velocidad. El sonido que reproduce el boton corta el sonido de la pulsación anterior. Para arreglar tenemos dos opciones:

1) Des de código creas el control MediaElement para cada pulsación del botón y lo haces reproducir


storageFile = await installedLocation.GetFileAsync("Assets\\Sounds\\hahahaaa.wav");
sound = await storageFile.OpenReadAsync();
Sound = new MediaElement();
Sound.AutoPlay = true;
Sound.SetSource(sound, storageFile.ContentType);

Pros: Fácil e intuitivo

Contras: Este control no lanzará jamás ningún evento, por tanto la única opción es reproducir con el AutoPlay=true. Eso implica que no puedes controlar cuando se reproduce el sonido porque tienes el tiempo que tarda el archivo de audio a cargarse dentro del control MediaElement. Otro problema, es que produce bajadas de rendimiento aleatorios importantes donde deja el Thread UI ocupado durante media segundo más o menos, lo que hace que en algunos casos la interacción con tu aplicación sea un desastre.

2) Usar XAudio2 de DirectX

Consulta un buen ejemplo aquí: XAudio2 audio file playback sample

Pros: máximo rendimiento y reproducción perfecta

Contras: Programar con C++ (que si somos de .Net pues es un poco diferente) y trabajar con DirectX

Nota : Si eres un maestro en C++ y sabes de DirectX ya no tienes ningún contra. Así que adelante 🙂