Previously, I discussed how I worked around a firewall issue where the HTTPS port was re-mapped, and the return URL was different than the request URL as a result of that remapping. So I trudged on, and hit a real stumper. Here’s the new issue:
The underlying connection was closed: Could not establish secure channel for SSL/TLS. Inner Exception: The function completed successfully, but must be called again to complete the context
I ran across Jan Tielen’s blog post (http://weblogs.asp.net/jan/archive/2004/05/08/128394.aspx) where he provided a code snippet to override the GetWebRequest method in the Reference.cs file. I implemented it, and it worked great --- on my development machine! However, when rolled out to the same test environment, the problem remained. However, I modified it futher, and got it to work..
/// <summary>
/// Set web request properties here
/// </summary>
/// <param name="uri">uri </param>
/// <returns></returns>
protected override System.Net.WebRequest GetWebRequest(System.Uri uri)
{
System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)WebRequest.Create(uri);
webRequest.AllowWriteStreamBuffering = true;
webRequest.KeepAlive = false;
return webRequest;
}
Sort of. When I tried to use DIME with the above code, it gave me an error “Client found response content type of '', but expected 'text/xml'”. That was not going to work. I found some more code, and it seemed to work great once again, until I tried to make a DIME call. Here was that attempt.
protected override System.Net.WebRequest GetWebRequest(System.Uri uri)
{
WebRequest request = base.GetWebRequest(uri); ;
if (requestPropertyInfo==null)
requestPropertyInfo = request.GetType().GetProperty("Request");
HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request,null);
webRequest.KeepAlive = false;
webRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
return request;
}
Once again, it worked fine during my WSE calls, but failed when trying to use DIME attachments with the following error: found response content 'application/dime', but expected 'text/xml'
To save any readers some time, I will go through everything I tried to resolve the problem, and finally, how I ended up resolving it. Here’s the items which didn’t work:
-- tried setting the SoapActor
-- tried turning off the Document protocol
-- tried setting the request and return URI
-- tried overding the GetWebRequest function a few different ways
-- tried using wsdl instead of asmx in setting up the Web Reference
-- tried setting the URI target/destination seperately
-- moved web service to the same machine as the calling web site (but still had to make an external call)
-- turned on tracing input and output and analyzed the logs created by WSE 2.0
So what finally worked? I ended up abandoning DIME, and encoded the file as a string, and passed it as an element of my XML. Here’s the code to encode the file as a string.
/// <summary>
/// Encodes the file in a Base64 string format.
/// </summary>
/// <param name="file">Name of the file.</param>
/// <returns></returns>
private string EncodeFile(HtmlInputFile file)
{
try
{
if (file.PostedFile.ContentLength > 0)
{
byte[] fsBytes = new byte[file.PostedFile.ContentLength];
System.IO.Stream fileStream = file.PostedFile.InputStream;
fileStream.Read(fsBytes, 0, file.PostedFile.ContentLength);
return Convert.ToBase64String(fsBytes);
}
else
return String.Empty;
}
catch (Exception ex)
{
//Handle the Error
return String.Empty;
}
}
What a trip it was to get there, but the resulting service has performed well, and I don’t have the issues I had with DIME. Don’t get me wrong, DIME worked great. But deployment of the web service in a secure environment proved to be quite a challenge. If you need more detail in resolving your issue, feel free to leave a comment or shoot me an email, and I will be glad to save you some of the pain I had to go through!