# Monday, March 27, 2006
A humorous story I remember from my adventures as a consultant...
Monday, March 27, 2006 4:49:48 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, March 22, 2006
Easy solution..
All Things | C# | General | Tools
Wednesday, March 22, 2006 11:00:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
Re-inventing an outdated but very useful wheel....
All Things | ASP.Net | C# | CSharp | General | Tools
Wednesday, March 22, 2006 3:44:55 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 21, 2006

Is it just my installation, or is WinCV missing from the latest version of .Net? Granted, I can still use the old WinCV by changing the config file, but why was such a useful tool pulled from VS2005?

If you've never used WinCV, check it out for VS2003 and prior version. It essentially lets you search the framework for a certain keyword. For example, if you want to find out which namespace "Registry" is in, type it in, and see the entire implementation. By using the configuration file, you can add additional assemblies for WinCV, to search your own libraries or those of third party vendors.

 

Tuesday, March 21, 2006 1:48:01 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, March 17, 2006

I've been playing a bit of poker recently, and having mixed results. Earlier this year, I was on a tear, and couldn't lose. Lately though, it's been a bit dry. I played in a tournament on Sunday at a local casino, and finally made the final table again, and even did ok in te cash game leading up to it.

Tonight was a humorous night though. I decided to play again, as I am in the running for a finals tournament at the casino I placed on Sunday. First, I played against a handicapped player, and we came up with a device to help quadraplegics to play poker with less assistance than it normally takes. Now I just have to find the parts and see if I can put it together, as it looks like a very viable solution to help him. But secondly, I have to say tonights tournament was the "worst" I have ever had. Although I managed to stay alive for 2.5 hours (mainly due to the lack of playable hands or situations), I did not win a single hand. However, I DID manage to chop one, so I will count that as 1/2 of a hand, but all I won were half the blinds. If you count the cash game I played prior to the tournament, I think you could take that losing streak to 4 hours of not winning one hand. Fortunately, losses were minimal, as the hands I was starting with were poor quality, and I just rode out the blinds. I think that is the longest I have ever gone. What a test of patience!

Such is poker...

Friday, March 17, 2006 5:39:58 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 16, 2006

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!

Thursday, March 16, 2006 5:19:42 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, March 14, 2006

Just a little tip, as I didn't read the error message generated as closely as I should have. I was working this weekend on the Microsoft Code Template for Building a Provider Based Feature and was migrating some existing libraries I had for VS2003 to take advantage of the features in VS2005.

First, let me say I love things in VS2005 like Generics, and the implementation of the Provider Model. I was migrating my data access libraries and error handling libraries, and was setting up some tests in nUnit as part of ongoing testing. Although I haven't changed my data and error handling models in a long time, I figured it was a great design idea to be able to change them dynamically using the Provider Model.

To make a long story short, I was running my tests for the data library, and when I invoked my Data Access classes, I was getting a "TypeInitializationException" error. I checked and double-checked my configuration file, and it appeared to all be correct. I looked at the InnerException, and it didn't seem to be much more help. However, I went further to look at the InnerException of the InnerException, and there's where I found the solution. The Rosetta Stone?

  • Only one <configSections> element allowed per config file and if present must be the first child of the root <configuration> element.

A quick check indicated that I hadn't made the configSection the first element. Doh!

So there are a few lessons to learn here. 1) Make sure your configSections is first (normally not a problem, just a cut and paste issue here) and 2) Make sure you dig REAL deep into the InnerExceptions for the details and 3) the new Visualizers in vs2005 were too cool and very helpful.

Hats off to the VS2005 IDE team! It's spawned a few visualizers I can think of, so if time permits in the future, I will be publishing those right here!

Tuesday, March 14, 2006 5:52:31 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, March 09, 2006

At my current client, security is taken to a whole new level, which is a good thing. But as a result, sometimes there is more of a challenge to resolve issues you may not normally encounter. For example, I was tasked with writing a web service which would facilitate file transfers of documents and images from a web page (and Windows client), store them on a secured server, and serve them up to an authenticated user on the internet. To do so, we have to deal with proxy server issues and firewall issues.

After writing and testing the web service locally, I deployed it to our production server. Locally, it all worked fine. However, when I deployed the web portion of the application to our test server outside our intranet, the real fun began. The next several posts I will discuss the problems I encountered, and how I ultimately resolved the issue. Hopefully this will help any readers out there who have a similar issue, as well as become documentation for the process I used so I can later reference it.

The first issue I saw was the following error:

The <To> header must match the value of an incoming message's HTTP Request Url if the soap receiver does not have an actor name.

I'd love to give the person I found the solution at credit, but it's been such a long time I can't find the original document I used. I modified the solution to make it a little more "generic" so that the web service can be moved without requiring a recompile of the application.

First, you'll need to locate the Reference.cs file for the web service reference(for C# users. Reference.vb is the similar file for VB.Net, but all code here will be in C#). In this file, add the following reference:

using Microsoft.Web.Services2.Addressing;

Next, locate the consructor for the WSE portion of the Reference.cs. In this case, mine will be FileServiceWse(). Here's the code you'll need to replace the this.Url reference already in there.

public FileServiceWse()

        {

            //these two setting are the <TO> and Response URLs. For example, in our case the response was

            //coming back with the redirected port appended to the url.

            //The Web service <TO> looked like https://mycompany.com/FileService/FileService.asmx

            //but the response was https://mycompany.com:1234/FileService/FileService.asmx

            //The endpointreference call to the Destination tells the application to expect the return url to look differently than the

            //<TO> reference

            string urlSetting = System.Configuration.ConfigurationSettings.AppSettings["FileService"];

            string urlReturnSetting = System.Configuration.ConfigurationSettings.AppSettings["FileService.ReturnURL"];

            if ((urlSetting != null) && (urlReturnSetting != null))

            {

                Uri sourceUri = new Uri(urlSetting);

                Uri returnUri = new Uri(urlReturnSetting);

 

                this.Destination = new EndpointReference(sourceUri, returnUri);

            }

            else

            {

                if ((urlSetting != null))

                {

                    this.Url = string.Concat(urlSetting, "");

                }

                else

                {

                    //this is the default URL of the file service if all else fails.

                    this.Url = "https://mycompany.com/FileService/FileService.asmx";

                }

            }

 

        }

 

What this code does is set the Destination property (if the FileService and FileService.ReturnURL settings are placed in the web.config file) to expect a different response than the requested web service URL. In our case, since our request was going through a firewall which remapped the ports, we had a port attached to the url for our web service which triggered this error.

The code also has failover. If I forget to make the settings, it will try the original URL reference. In my case the call won't work, but I believe in at least attempting to code some failover when human error can take place in moving files, etc.

But this only solved one of the many challenges I encountered in deploying this web service. Stay tuned for the next resolution to tricky WSE issues!

Thursday, March 09, 2006 4:12:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

It's not a record for longest time between posts, but it sure has been a while. I finlly got off my butt and upgraded das Blog to the latest version, and enabled comments again. So now maybe it will be worthwhile to begin blogging again!

The past few months have been interesting to say the least. I have a catalog of things to post about, such as solving some bizarre web service issues with DIME (well, solution is not quite the word... a workaround is more like it) as well as beginning the trek into VS2005.

So if there's anyone still out there readin this, I do have a ton to write about, now lets see if I can find the time to do it!

Thursday, March 09, 2006 4:52:50 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |