Most Excellent ASP.Net Workflow Forms Tutorials

Last week I was searching in vain for an updated version of an old sample I had back in the B2TR days when I stumbled across a comment in the ECM team blog from Robert Shelton. He has written what I believe is the best series of articles on developing workflows with ASP.Net forms (as opposed to InfoPath) that I have seen anywhere.

You can find them here:

I normally don’t post links, but a search on "ASP.Net workflow forms tutorial" has this site many pages back and these tutorials should be the first link on page 1.

Update: This is why you shouldn’t blog after working 16 hours. Simply adding ‘WSS’ to the search phrase shows he is number 1 on page 1. J Which is good because he deserves it!

Atlanta Holiday Loadfest and Game Night

The Atlanta .Net User Group, in association with the Atlanta Microsoft Professionals, and Microsoft is pleased to announce Holiday Loadfest and Game Night!!!

Bring your laptop!

The first 150 attendees will receive an evaluation copy of Visual Studio 2008 to install and play with and when the shrink wrap version is available (January), the 150 people will be given a fully licensed copy of VS2008 Pro.

Merry Happy Holidays!

Once everyone is good and loaded game night shall commence. There are 9 very large TV’s with 9 XBox 360 Elites each with four controllers. Halo 3 and Guitar Hero will be attending, and when you aren’t rocking out you can frag your buddy.

This should be by far the coolest holiday event since I became leader of ADNUG four and a half years ago, and I won’t be there! Drat!!!

Getting the w3wp.exe Process ID for Attach to Process

This is pretty well known and lots of others have posted about it over the years, but for the sake of completeness for those who read the last post and don’t know this already…

Often when you try to attach to the w3wp.exe process and debug an assembly there are multiple instances from which to choose. How do you know which one to pick?

Open a command prompt and run the iisapp.vbs script with no parameters as follows:

It will output a list of the currently running application pools and the associated PIDs.

Author: Doug Ware

You Don’t Need to Copy PDB Files to Debug in the GAC!

Following up on my last post, many developers choose to put assemblies into bin because they find them easier to debug. Usually, they do not create detailed CAS policies. Instead they simply set the trust level to full so they can ‘just make it work’. While this is a sentiment I can fully understand having wrestled with it myself, it’s not the best idea. Generally, I think most will agree that the closer the development environment’s configuration matches the production environment the better. So developing with assemblies in BIN with the web config set to full trust and then deploying them at the last minute to the GAC just makes me feel unclean.

Fortunately, it’s just as easy to debug in the GAC as it is in BIN if you configure the development environment correctly. Unfortunately, few know how to do this because the internet is polluted with pages full of bad information that is a held over from previous versions of .Net. You can spot these easily because they will say you need to copy the debug symbols (.pdb file) to the GAC. In and of itself, that will not work. These days it is also completely unnecessary.

To configure VS 2005 to debug the assemblies properly, do the following:

Open Tools | Options.

Check Show all settings if needed and locate Enable Just My Code (Managed only)

Uncheck it and click OK

Attach to the w3wp.exe process for the instance you want to debug.

There may be more than one. You can attach to all of them, but only the first one will be debugged. To verify that you are attached to the correct instance of w3wp.exe, open the Modules window by pressing CTRL-ALT-U.

If your assembly is listed, you picked the right one. If not, choose stop and attach to the next one until you find it.

In this example, the assembly is loaded. Note that the symbol file is loaded and that it was not copied to the GAC.

My breakpoints are hit! Yay!


P.S. Don’t forget the set debug="true" in the web.config or it won’t matter where you put the assembly! This can really trip you up if you forget to do it because the breakpoints will turn all nice and red, but it won’t stop.

Note: I renamed this post because I want people to read it and I decided that some might miss the message based on the earlier title.

Author: Doug Ware

Deploying Assemblies to BIN Versus GAC

I had a good conversation with a systems engineer recently about where feature assemblies should be installed. I think it’s worth sharing my opinion on this here. His opinion was based on common advice that web part assemblies should go in the BIN folder and include a proper CAS policy. My opinion is based on many years of .Net development and my assessment of what an organization should have in place before introducing the configuration management burdens CAS brings to the table.

The only thing that is inherently special about an assembly in the GAC in .Net is that it can be resolved and loaded based on its full name. The full name includes the public key token and version which are embedded in the assembly. The public key is used against a hash of the assembly (created with a private key) to verify the assembly is not altered. This is why the full name of a signed assembly is called a "strong name". And, this is part of the mechanism used to handle multiple versions of the same assembly.

The public key is the most commonly used evidence for code access security, and as a result, if you are creating a CAS policy for an assembly that is going in the BIN, you probably won’t skip code signing which is a requirement for installing an assembly to the GAC.

.Net gives assemblies in the GAC full trust by default.

Assemblies loaded from the GAC get the same amount of process isolation as assemblies loaded from anywhere else. If ten application domains load the same assembly, there are ten instances of the assembly loaded, not one. Assemblies don’t get loaded until a process in the app domain tries to invoke code in the assembly. So, putting an assembly in the GAC, or even referencing the assembly in an assembly manifest, will not cause the assembly to load or code to run. Putting an assembly in BIN on one site does prevent other sites from loading the assembly because their app domains can’t find the assembly to load it. Putting it in the GAC won’t cause them to load it.

Full trust does not mean that the assembly can do anything that it wants. It has permissions up to those of the identity it is executing under unless it uses impersonation to explicitly assume the identity of a more privileged account. This is a big difference between .Net and native code.

Anyway… In my opinion, the best argument to be made for putting assemblies into BIN instead of the GAC in a SharePoint site is that, assuming the CAS policies are tightly controlled by a group other than development, it requires the devs to explicitly state that the assembly needs to do something out of the norm and could potentially prevent a rogue dev from sneaking in code that is mucking with stuff on the disk, database, registry, etc.

But, this requires governance to affect.

Absent governance an assembly in BIN is no more or less dangerous to the overall stability of the server than an assembly in the GAC. And, in my opinion, if the environment is a farm and if the decision to put an assembly in BIN means that the environment now requires custom policies on a per web app basis, the BIN approach has a significant downside. You could mitigate by deploying policies directly based on a custom evidence, like a corporate-wide public key, but that would only really work if the dev group delay-signed the assemblies and another group completed the signing and built the solution.

But, absent strong and continuing governance and review with clear demarcation between dev and production and mature configuration management practices, putting bits into BIN is more likely to cause problems than simply putting them in the GAC.

So, to sum it up, there are times when CAS policies address clear requirements and in those cases, BIN might well be the way to go. But absent the ability to clearly trace the decision to an actual requirement, I contend that it is not by default ‘better’.

Author: Doug Ware