This code is look fine for me, I suppose nothing wrong to use return statement inside using statement, but compiler said that not all code path return value. How should I fix this to be able return string result?
public static string CallWebService(string an, string xmlcommand)
{
//test
//Dim _url = "http://testapi.interface-xml.com/appservices/ws/FrontendService"
//live
dynamic _url = "http://212.170.239.18/appservices/ws/FrontendService";
try
{
string soapResult = null;
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(xmlcommand);
HttpWebRequest webRequest = CreateWebRequest(_url, an);
webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
asyncResult.AsyncWaitHandle.WaitOne();
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (BufferedStream bs = new BufferedStream(webResponse.GetResponseStream()))
{
using (GZipStream gz = new GZipStream(bs, CompressionMode.Decompress))
{
using (StreamReader rd = new StreamReader(gz))
{
if (an == "HotelValuedAvailRQ")
{
soapResult = rd.ReadLine();
}
else
{
soapResult = rd.ReadToEnd();
}
return soapResult; //This is what I want to return
}
}
}
}
}
catch (TimeoutException ex)
{
StringBuilder s = new StringBuilder(2000);
s.AppendFormat("<b>К сожалению превышено время ожидания.</b>: {0} <br /><b>Источник</b>: {1}<br /><a href='javascript:history.back();'>Вернуться</a>", ex.Message, ex.InnerException);
HttpContext.Current.Session["bug"] = s.ToString();
HttpContext.Current.Response.Redirect("../errors/error.aspx");
}
}
The problem isn't your using
statement, but your try
statement: excecution could abort anywhere in your try
block before it gets to return
, then code would enter your catch(TimeoutException ex)
handler, but you don't have a return
statement in there.
I see your code seems to be part of a web-application, however this looks like a "backend" method that returns content to a consuming method. You should not write to Response
from here, instead return null
or don't catch the exception and instead let the caller of your CallWebService
be responsible for displaying an error message.
I see you're making a few other mistakes like using dynamic
instead of String
, this is how I would write your code:
public static string CallWebService(string an, string xmlcommand)
{
String url = @"http://212.170.239.18/appservices/ws/FrontendService";
try
{
String soapResult = null;
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(xmlcommand);
HttpWebRequest webRequest = CreateWebRequest(_url, an);
webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
using(HttpWebResponse response = webRequest.GetResponse())
using (Stream s = webResponse.GetResponseStream())
using (StreamReader rd = new StreamReader(gz))
{
if (an == "HotelValuedAvailRQ")
{
soapResult = rd.ReadLine();
}
else
{
soapResult = rd.ReadToEnd();
}
return soapResult;
}
}
catch (WebException)
{
return null;
}
catch (TimeoutException)
{
return null;
}
}
dynamic
incorrectly. dynamic
is not equivalent to VB's Dim
statement.HttpWebRequest
but blocking, so you might as well just use the blocking methods (GetResponse
)BufferedStream
, just use it directly.using
blocks together.HttpWebResponse
does this automatically: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.automaticdecompression.aspxCallWebService
in an unknown state, instead the consumer should check to see if CallWebService
returns null and if so, render the error message.Note that in both catch
blocks, you might want to log the exceptions because their details are being swallowed. They may indicate a downed service or other problem.