Thursday, November 26, 2009

Windows Server 2008 IIS7 SSL Host Header

I’ll start off with the bad.  You cannot set this up using the IIS Manager.  Also, once you have it setup, you can view the settings from the IIS Manager, but if you make any changes, the ssl host header settings will be removed.  Very convenient.

The good news is, once you figure out the command line to set it up, it works great.  I have been using it on a couple of test servers for quite a while now to host different test urls on a single ip address.

Assuming you have IIS setup and a cert ready to use, here are the steps I followed.

1. Go ahead and add an SSL binding with your certificate to the website.  The reason for this is to get the certificate hash and Application ID.  You can also get the certificate hash by viewing the details of the cert.  As for the Application ID, this is the only way I could find to get it.  It is probably also the the IIS metabase xml file as well.

2.  In a command prompt run the following command and save the certhash and appid.

  • netsh http show sslcert

showsslcert 

3.  Change directories in the command window to c:\Windows\System32\inetsrv and run

  • appcmd.exe set config -section:system.applicationHost/sites /+"[name='test.mydomain.com'].bindings.[protocol='https',bindingInformation='127.0.0.1
    443:test.mydomain.com']"
    /commit:apphost

appcmd

  • Note: The name= parameter is the name of the site in IIS manager.

4.  The last step is to bind the ssl certificate to the site.

  • netsh http add sslcert ipport=127.0.0.1:443 certhash=1f5596aa6ed348243056eec325fe1fbc326c2d3a appid="{4dc3e181-e14b-4a21-b022-59fc669b0914}"

addsslcert

  • Note: Make sure you put in the values for certhash and appid that you copied earlier.

Finally, the end result….

iis

Labels:

Friday, November 13, 2009

TFS 2008 Remove Alerts

Today I had the need to remove alerts for a user no longer on the project.  It is easy to edit build alerts/notifications using Team Explorer or the TFS Power Tools.  But, I could not find a way to remove Work Item alerts for a user.  Maybe I was missing something simple, but I like to think I wasn’t.  Plus, with the user being a contractor, the email address that was used was not in exchange or tied to the domain account.  After some digging around, I found where TFS stores alert subscriptions in the database and simply deleted the rows.  I found them at

TfsIntegration.dbo.tbl_subscription

So far, this appears to work.  I anyone has a better/cleaner way, I would love to hear about it.

Thursday, August 7, 2008

WCF Client Proxy IDisposable - Generic WCF Service Proxy

I have run into this issue on several clients now.  The basic issue is when using WCF on the client, using ClientBase<>, and you do not close the channel, you can tie up the server until the channel times out.  So, once the max instances, sessions, or concurrent calls is reached and the clients are not closing their channels, the server will block and queue up subsequent calls.  The un-closed client channels will eventually timeout, which causes a fault on the client, and the next set of calls will then make it through.

When I first hit this issue, my thought was to wrap my client base code in a using () statement so Dispose() would then be called.  But, ClientBase<> does not implement IDisposable.  Here is some info on the issue...

Guidance on factory close and message faults

Why does ClientBase Dispose need to throw on faulted state

So, after lots of testing to understand all the WCF knobs to tweak, I came up with a generic class I called ServiceProxy for clients to use when creating/using client channels.  This has been through several revisions and here is what I have ended up with.  The idea to add support for the delegate came from this blog entry

iServiceOriented.com

Here is the code for my generic service proxy wrapper...

public class ServiceProxy<TInterface> : ClientBase<TInterface>, IDisposable where TInterface : class

    {

        public delegate void ServiceProxyDelegate<T>(TInterface proxy);

 

        public ServiceProxy()

            : base(typeof(TInterface).ToString())

        {

        }

        public ServiceProxy(string endpointConfigurationName)

            : base(endpointConfigurationName)

        {

        }

 

        protected override TInterface CreateChannel()

        {

            return base.CreateChannel();

        }

 

        public TInterface Proxy

        {

            get

            {

                return this.Channel;

            }

        }

 

        public static void Call(ServiceProxyDelegate<TInterface> proxyDelegate)

        {

            Call(proxyDelegate, typeof(TInterface).ToString());

        }

 

        public static void Call(ServiceProxyDelegate<TInterface> proxyDelegate, string endpointConfigurationName)

        {

            ChannelFactory<TInterface> channel = new ChannelFactory<TInterface>(endpointConfigurationName);

 

            try

            {

                proxyDelegate(channel.CreateChannel());

            }

            finally

            {

                if (channel.State == CommunicationState.Faulted)

                {

                    channel.Abort();

                }

                else

                {

                    try

                    {

                        channel.Close();

                    }

                    catch

                    {

                        channel.Abort();

                    }

                }

            }

        }

 

        public void Dispose()

        {

            if (this.State == CommunicationState.Faulted)

            {

                base.Abort();

            }

            else

            {

                try

                {

                    base.Close();

                }

                catch

                {

                    base.Abort();

                }

            }

        }

    }

 

And, here are some usages samples...

//delegate example1

            string response = null;

            ServiceModel.ServiceProxy<IUnitTestService>.Call(p =>

            {

                response = p.DoStuff("ServiceProxyUsingTest");

            }

            );

 

            //delegate example2

            string response = null;

            ServiceProxy<IUnitTestService>.Call(p => response = p.DoStuff("ServiceProxyUsingTest"));

 

            //using example

            string response = null;

            using (ServiceProxy<IUnitTestService> service = new ServiceProxy<IUnitTestService>())

            {

                response = service.Proxy.DoStuff("ServiceProxyUsingTest");

            }

Tuesday, June 3, 2008

WCF Presentation at South Colorado .Net User Groupo

Here is the content from my WCF presentation today at the South Colorado .Net User Group. The zip file includes the powerpoint, code, and a sql backup file of the demo database. Feel free to email me with any questions.


WCFDemo.zip

Wednesday, May 28, 2008

Server 2008 Virtual Cluster with Hyper-V

I spent the last few days building out a virtual Server 2008 clustered environment in Hyper-V RC0 (I hvae not upgraded to RC1 yet) to do some prototyping for a project. After some playing, I found out you cannot create a shared vhd for multiple virutals to share. So the challenge is how do I setup a shared drive for my cluster quorum and storage. After some research, I found this blog entry (which is right-on, worked great!)
http://blogs.technet.com/pfe-ireland/archive/2008/05/16/how-to-create-a-windows-server-2008-cluster-within-hyper-v-using-simulated-iscsi-storage.aspx

You basically need to create a virtual san on another virutal server using iSCSI to create your shared disks for the cluster. I had the StarWind software up and running in no time. NOTE: If you get an error that the StartWind software cannot obtain exclusive access to the drives in the VM, try closing windows explorer if you were browsing that drive. :) I was also able to install StarWind into a virtual running Server 2008 standard without any problems.






Another note...after getting everything up and running, I was adding a second cluster resource and needed a another cluster storage drive. After shutting down the virtual running the StarWind software, I added another SCSI vhd through the Hyper-V management console. Once I started the virtual back up, I was unable to format the new drive for use. I had to shutdown the StarWind service before I was able to format the drive, even though that drive was not yet added as a device in StarWind.

I am now in the process of setting up a couple of clustered MSMQ queues to use with WCF and some backend processing applications. As this comes together and hopefully works, I will post more information.

Wednesday, May 7, 2008

Team Foundation Server 2008 Hardware Migration

In the last two weeks, I have been through two TFS hardware migrations, neither of which went smoothly. The first migration involved moving to a new server on a new domain and the second was a new server on the same domain. Neither installation is that large so we have both TFS and SQL running on the same box.

First, I started by following the documentation from Microsoft
http://msdn.microsoft.com/en-us/library/ms404869.aspx

The part that did not work was moving the data tier. It would fail with a variety of errors. I checked the connection string web.config in the Services virtual under the Team Foundation Server site hosted on port 8080. It was right, but TFS would not work. After some digging around in the event log, I saw that it was still trying to connect to the old database server. Thinking I missed some steps, I started back over from the beginning and ran into the same issues again. I was not able to find any other connection string in any of the TFS website structure, so I started digging into the database. This sure was starting to feel like a BizTalk database recovery (which is much worse!!). In the TFSIntegration database, there is a table called tbl_database (just in case being in the Tables collection wasn't enough of a clue that it was a table). And there they were, serveral entries with the old database server name. So, I manually changed these to the new db server and tfs was working!!! After that, everyone was able to sync up their source just fine and we were working again. The team project sites were even working.

This same fix worked on both TFS migrations. After running into the same issue on the second migration, I did find this article http://msdn.microsoft.com/en-us/library/bb909757.aspx, which made me feel a little better about our hack solution.

In the end, two successful migrations. In reading some of the issues others have run into, the migration doc needs some work. I still don't know why following the doc didn't work for the data tier and what the right way is (maybe this is it!).

Sunday, December 16, 2007

AppDomain CreateInstanceAndUnwrap w/ Visual Studio 2008

I recently converted a project form Visual Studio 2005 to Visual Studio 2008 RTM. I am using AppDomain.CurrentDomain.CreateInstanceAndUnwrap to dynamically create an instance similar to the following

string assembly = "Test.dll";
string type = "Test.MyClass";
MyClass obj = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assembly, type) as MyClass;

This worked fine in 2005 but gets an exception in 2008 - "could not load file or assembly or one of it's dependancies". Looking at the fusion log, which is now in the exception info window in Studio (very nice), I could see that it was looking for Test.dll.dll, Test.dll.exe. So, the extension is being appended to the end of the assembly name. After removing ".dll" from the name of the assembly, the code works fine.