Archive for August, 2008

Smart Client Deployment To Different Servers

Aug 28

For my current client we have an environment where the application is handed over to a deployment team that installs it onto varying test servers. For good reason these servers are locked down and the development teams can not access them. This ensures a clean install and ensures that the version in the test environments gets moved forward only if there are no issues.

Problem 1 – Setup.exe has “baked in” URL

This plays a bit of havoc when deploying smart client applications. One of the reasons for this is that the setup.exe bootstrapper has the URL baked into it so when we try it on a development machine it is actually looking for the install files on the machine that the click once application was developed on!

Now one way to get around this is to set the Installation Folder URL in the click once projects “publish” tab but that would mean we would need to create unique assemblies with the URL baked into them for each environment.

I did happen upon a way to change the setup.exe bootstrapper to have a variable URL though. On the server that the click once application is being deployed from run:

setup.exe /url=http://mytestserver/testfolder/

This will cause the exe to “patch” itself with the new URL.

Problem 1 solved!

Problem 2 – Changing a config file on the server invalidates the application.manifest

Once we have the files installed onto the deployment server we need our deployment team to adjust the WCF bindings in the client.exe.config file that gets downloaded so that the client application talks to the right WCF service. A neat thing with smart client applications is that it generates a manifest file stating all the files the application needs to run and a checksum of those files. Because the team is changing one of those files the checksum of the file changes and so we need to generate a new manifest file with the new checksum for the file in it. This leads to a new problem as there is a deployment file that has a checksum of the applications manifest in it as well so we need to regenerate that as well! Here are the steps I took to create this application:

In Visual Studio:

  1. Goto Project Properties -> Publish
  2. Set the publishing folder to a local folder
  3. Set the install URL to “http://dummy” (this is to prevent the app from running if a later step is not completed)
  4. Click “Options”
  5. Uncheck the “Use .deploy file extension” (this is not 100% necessary but made my life easier when generating the manifests later)
  6. Publish the application

Creating The Deployment Package

For me I then added the outputed files from the publish into my WCF deployment project. This allows me to have one deploy package that installs my WCF service and my smart client to the same spot easily

  1. Added the setup.exe file outputed from the publish tab
  2. Added mage.exe from the Windows SDK (we will need this to recreate our manifest files)
  3. Added configure.bat (see below)
  4. I created a “Client” folder
  5. added all .exe, .config, and .dll files to the “Client” folder. I did not include the .manifest and .application files as I we are going to recreate them with our configure.bat file
  6. Build the project

Now all our team needs to do is:
1. Open the [pathtoapplication]\Client\[appname].config file
2. Adjust any settings
3. Change the app url in the configure.bat file
4. Run [pathtoapplication]\Configure.bat

Configure.bat will use the mage.exe application (found in the windows SDK) to generate all application manifest for the client, the deployment manifest for our deployment, and repath the bootstrapper

Contents of Configure.bat

set Version=”1.0.0.11″
setup.exe /url=http://mytestserver/appname/
del “.\Client\myapp.exe.manifest”
mage -new Application -fd “.\Client” -ToFile “.\Client\myapp.exe.manifest” -name “My Smart Client App” -version %version%
mage -new Deployment -ToFile myapp.Application -AppManifest “.\Client\myapp.exe.manifest” -install true -name “My Smart Client App” -version %version%

“setup.exe /url=….” sets the URL that the setup.exe file will be accessed on
I then delete the old manifest (might be there from previous runs)
“mage -new Appliction … ” generates our new application manifest with new checksums for the config files
“mage -new Deployment …” generates the deployment file (sits next to setup.exe) so that the application can be installed. This has a checksum in it for the application file we just generated.

Now one of the things I have completely removed from this is signing of our files (Done by unchecking the “Sign the clickonce manifests” checkbox under the “Signing” tab of the project). This should be on but unfortunately I have about 60 minutes left of my current contract and do not have time to implement signing on the manifests which is a very very very good security practice for this type of thing.

Things I Can Not Develop Without: Resharper

Aug 20

Resharper has to be one of the biggest boosts I have found to my productivity. This tool has so many little time saving features that I will probably gain days of productivity every month.

For anyone that has not heard of this tool, Resharper is a visual studio add-in made by JetBrains that adds a plethora of time saving shortcuts.

I thought I would share a few of my favourites:

alt+enter
some context sensitive help. For instance if you write a line like this: ICustomer customer = new Customer();
and the Customer class does not exist you can hit alt+enter and it will generate the class for you.

alt+insert
Used to generate code in your class. If you had something like this:
public class Customer
{
     private string firstName;
     private string lastName;
}

you could hit alt+insert in your class and have a few handy options. The ones that I use the most are generate constructor which would create a constructor for the class based on the private fields

public Customer(string firstName, string lastName)
{
    this.firstName = firstName;
    this.lastName = lastName;
}

we can also use this to generate properties based on fields too!

public property FirstName { get; set; }
public property LastName { get; set; }

F2
F2 does a rename on whatever you have selected. It searches out all usages of that item and renames it. A neat thing to it as well is that it searches comments for that variable and will rename it in the comments if you so desire.

F6
F6 allows you to move things around easily. If you have a nested class in a class and want to move it to the outer scope you can easily do it. If you have 2 classes in one file and want to move one of them to its own file it will do that too as well as keep the namespaces and imports handy.

ALT+Space
This one is smart intellisense. Lets say you start typing this:

var sb = new StringBui

but you can’t remember what namespace the stringBuilder class is in. Simply hit alt+space and it will show a list of classes that start with StringBui in everything you have referenced in your class. If you select System.Text.StringBuilder it will add an import/using statement for System.Text and complete the line for you.

CTRL+ALT+F
Reformats the current document. Based on what you select this can clean up using/import statements, fix any messy indentation, and even change types to use the var keyword where appropriate (if you like this setting). It is a handy tool to cleanup code in seconds

CTRL+B
This is a shortcut that will take you to the implementation of the item you are on (i.e. it works like right clicking and going to definition)

Those 7 commands I use fairly often and just starting there will save lots of time. There are hundreds of other shortcuts and features in Resharper which makes it such a productivity booster that I have no idea how I worked without it.

Filed Under: General

Things I Can’t Develop Without: Removing Pain

Aug 19

Recently I have been helping several other developers in the shop I am consulting at and realized another item for this series: Removing Pain. I am amazed by how many times I see developers repeating the same things over and over again.

Builds/Deployments
Builds should be the simplest and most repeatable thing you do in a day. If you have a checklist on your desk of steps then stop and automate. It is such a time saver to have a script that will do the things you need it to do. Wether it is using a build system like nANT, msBuild, finalBuilder, a batch file, or adding automation to visual studio (pre and post build events can be quite handy in a project). I have even used Auto Hot Key to build a macro to repeat some tasks that I could not automate via code.

Coding
Well I am a huge fan of resharper. I probably owe JetBrains about 400 hours of my life so far. There are lots of great tools to help you be productive in your IDE so try some of them out! I am not a fan of code generators but if you are doing tasks that feel like copy,paste, change 1 or 2 things then you should extract it to a generic way of doing it OR if that will not work then look at code generators

Frameworks
There are lots of great tools out there that enable you to do things faster. Things like ORMs for your data access, logging frameworks to make your life easier, and testing frameworks to help you increase or maintain the quality of your code.

If something is painful to do at work that is the first thing you should address. By removing the things that eat away your time you will have more time to be productive and just get more done.

Filed Under: General, Rants

Debugging WCF

Aug 6

I think WCF is a pretty sweet technology stack. It makes things work with each other quite easily….. until you use it for more than the default it was setup to handle. This usually results in some strange and hard to diagnose error messages.

The #1 tip I have so far is to use the SvcConfigEditor.exe file that comes with the Windows SDK to edit your configuration files as it allows you to edit the configuration in a simple and visual fashion and makes it much harder to make errors in your config file.

Problem: The content type text/html; charset=utf-8 of the response message does not match the content type of the binding.
Usual Reason: Your service is returning an HTTP error and not a WCF message. This most often occurs because your config file is not valid or the page is not found.
Solution: The first thing is to narrow down the error by opening the service in your browser and making sure it can return wsdl (i.e. http://localhost/MyFirstService/HelloWorldService.svc?wsdl). This will point you to the problem 99% of the time (and for me 99% of the time was I put in some configuration that was not valid)
Problem: The Server was unable to process the request due to an internal error.
Usual Reason: The service probably threw an exception so the message could not be returned.
Solution: On the server turn on IncludeExceptionDetailInFaults so that the client can see the error message if that is what you desire. Otherwise fix the reason why the application is throwing an exception.
Problem: The message could not be processed. This is most likely because the action ‘…’ is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings
Usual Reason: The server says it is behaving in one fashion and the client expects another.
Solution: You could look over the client and server configuration files until your eyes bleed or take what I have found to be the easy way out: Use the SvcConfigEditor.exe to regenerate your client configuration file.
Problem: Exceeded MaxItemsInObjectGraph quota. Maximum number of items that can be serialized or deserialized in an object graph is ’65536′.
Usual Reason: There amount of objects to be serialized exceeds the default limit. This is probably a limit put in place to prevent a denial of service attack so you can set this to be a reasonable level for your application.
Solution:

Change the server/client to increase the maximum objects serialized

Change the server:
<service behaviorConfiguration=”LargeMessageBehaviour” name=”MyFirstService.HelloWorldService”>
        <endpoint address=”
http://localhost/MyFirstService/HelloWorldService.svc
                    binding=”basicHttpBinding”
                    contract=”MyFirstService.IHelloWorldService” />
      </service>

<behaviors>
  <serviceBehaviors>
    <behavior name=”LargeMessageBehaviour”>
      <dataContractSerializer maxItemsInObjectGraph=”6553600″ />
    </behavior>
  </serviceBehaviors>
</behaviors>

Change the client:

 <client>
      <endpoint address=”
http://localhost/MyFirstService/HelloWorldService.svc
        behaviorConfiguration=”LargeMessageBehavior” binding=”basicHttpBinding” />
</client>

<behaviors>
  <endpointBehaviors>
     <behavior name=”LargeMessageBehavior” >
         <dataContractSerializer maxItemsInObjectGraph=”6553600″/>
      </behavior>
   </endpointBehaviors>
</behaviors>

Problem: System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly
Usual Reason: This is the really generic error message I find and can be for multiple reasons. So far I have only had it when hosting a service in IIS.
Solution: As there are several possible causes there are several possible solutions
1. If you are sending lots of data IIS will reject anything over a certain limit by default. You can change this setting with:
<system.web>
    <httpRuntime maxRequestLength=”734000″/>
</system.web>
2. If your request takes a long time to process IIS can timeout. You can change this via:
<system.web>
    <httpRuntime executionTimeout=”500″ />
</system.web>
3. Something else went wrong and instead of responding the webserver just decided to shut down. In this case you will have to enable tracing on the server and or client to narrow down the error (see debugging steps below)


Debugging Steps
Here are the usual steps I take to narrow down a problem. Each problem is unique though so some of these steps may not apply:
1. Open up the service wsdl in a browser to make sure that the service is working: (i.e. http://localhost/MyFirstService/HelloWorldService.svc?wsdl).
2.  Often issues arise because of configuration issues. I often find myself editing the configuration files using the SvcConfigEditor.exe file that comes with the windows SDK which can help you find the right spot to make configuration changes.
3.   I also find that mirroring my changes from the server behaviour to the client is a source of issues. You can use the SvcConfigEditor.exe tool to generate the client configuration based on a server configuration file.
4.   Enable tracing. This will allow you to log a lot more information about the client/server interaction and usually reveals more details about an issue. This is easiest to enable via the SvcConfigEditor.exe again and the logs can be easily viewed with the SvcTraceViewer.exe file (Both are part of the Windows SDK)

Filed Under: WCF

Great nHibernate Course Offering

Aug 1

If you have ever wanted to learn nHibernate from an experienced developer now is your chance. The one and only James Kovacs is offering a three day nHibernate course in Calgary this August that you don’t want to miss.

James is an expert in nHibernate and I could not think of a better person to offer this course.  Check out the announcement on his website:
http://www.jameskovacs.com/blog/CourseAnnouncementObjectRelationalMappingWithNHibernate.aspx

Filed Under: General