简体   繁体   中英

How to wait till call to a web service is completed?

I am trying to get the FedAuth Cookie from a web service. But what is happening is that before I get the result from the web service, the other method GetFedAuthCookieFromSOAPResponse method is getting executed and the parameter passed to it is becoming null . Hence I am getting the exception:

startIndex cannot be larger than length of string. Parameter name: startIndex

How do I wait till I get the soap response from the web service and then excute the method GetFedAuthCookieFromSOAPResponse ?

static void Main(string[] args)
        {
            string url = "https://server/site";
            string soapResponse = GetSOAPResponse(url, "http://site/server/exapmle.asmx");
            Console.WriteLine(GetFedAuthCookieFromSOAPResponse(soapResponse));
            Console.WriteLine("Press ENTER to close program");
            Console.ReadLine();
        }
        internal static string GetSOAPResponse(string url, string serviceURL)
        {
            using (WebClient client = new WebClient())
            {
                string request = "<?xml version=\"1.0\" encoding=\"utf-8\"?><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:Body><GetFedAuthCookie xmlns=\"http://tempuri.org/\"><requestUrl>" + url + "</requestUrl><userName></userName><password></password></GetFedAuthCookie></soap:Body></soap:Envelope>";
                client.Headers.Add(HttpRequestHeader.ContentType, "text/xml; charset=utf-8");
                client.Headers.Add("SOAPAction", "http://tempuri.org/GetFedAuthCookie");
                string soapResult = string.Empty;
                client.UploadString(new Uri(serviceURL), request);
                client.UploadStringCompleted += new UploadStringCompletedEventHandler(delegate(object sender, UploadStringCompletedEventArgs e)
                {
                    soapResult = e.Result;
                });                
                return soapResult;
            }
        }
        internal static string GetFedAuthCookieFromSOAPResponse(string soapResponse)
        {
            string openingTag = "<GetFedAuthCookieResult>";
            string closingTag = "</GetFedAuthCookieResult>";
            int startIndex = soapResponse.IndexOf(openingTag) + openingTag.Length;
            int length = soapResponse.IndexOf(closingTag) - startIndex;
            return soapResponse.Substring(startIndex, length);
        }

UploadString is already a synchronous method. Meaning that when the method returns the operation has completed. UploadStringCompleted is used only when dealing with asynchronous methods like UploadStringAsync or UploadStringTaskAsync .

UploadString returns a string which is the response from server.

You simply need

string soapResult = client.UploadString(new Uri(serviceURL), request);
return soapResult;

This is where you respond to the completion of the web service request:

client.UploadStringCompleted += new UploadStringCompletedEventHandler(delegate(object sender, UploadStringCompletedEventArgs e)
{
    soapResult = e.Result;
});

So you can perform your follow-up logic there:

client.UploadStringCompleted += new UploadStringCompletedEventHandler(delegate(object sender, UploadStringCompletedEventArgs e)
{
    Console.WriteLine(GetFedAuthCookieFromSOAPResponse(e.Result));
    Console.WriteLine("Press ENTER to close program");
    Console.ReadLine();
});

Or you could refactor that logic out into a method and call that method from in there, etc.

But essentially since this is an asynchronous operation, you don't "wait until it's completed" but instead you "respond to its completion event".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM