Tobi + C# = T#

If you want to serve up files or other content that has not much in common with the webforms or mvc engine, you should serve them using http handlers. The corresponding interface is IHttpHandler. They are light-weight and give great performance, especially when combined with IIS 7.

The basics - registering a custom handler

Http handler can be registered on multiple levels within IIS. One of the most common one is within the confines of the web application. That is done using web.config. If you have a handler defined in the class Com.Hertkorn.TaskBasedIHttpAsyncHandler.Www.Handlers.SampleAwaitHttpAsyncHandler which is in the dll Com.Hertkorn.TaskBasedIHttpAsyncHandler.Www use the following syntax:

Make sure you understand the ramifications of the verb setting, before you copy and paste the above code.

Now the http handler listens under the URL testAwait.axd for incoming requests.

Taking it up a notch - async

Using async handlers, when done correctly, will offload IO bound work to IO completion ports and therefore will free up the http pipeline threads to work on other requests. In high-stress situations this is crucial in order to achieve high throughput. IHttpAsyncHandler though is not for every situation, a introduction into the advantages and disadvantages can be found on msdn.

The original interface for an async IHttpHandler is called IHttpAsyncHandler and is implementing like this:

Of course this is not an easy and "modern" interface into the async world. Nowadays we are trying to expose async operations using the Task class. So ideally an asynchronous handler would look something like this:

Today I want to talk about an addition to RegisterObject. The IIS does check if an app pool is busy or idle and may initiate a shutdown simply because it wants to save resources by shutting down long idle app pools. So simply put, even though one correctly uses RegisterObject, the app pool still does not know that there is stuff going on, which is relevant and should mark the app pool as busy.

Like RegisterObject this is done using the System.Web.Hosting.HostingEnvironment class, specifically IncrementBusyCount() and DecrementBusyCount(). With a busy count larger than zero the app pool is marked as busy.

When running task I would recommend that any given tasks does two things before starting its work: Register an object as managed by the hosting environment using RegisterObject and increment the busy counter.

It goes without saying that it must be guaranteed that a task, even a failed one, does a proper cleanup, unregistering and decrementing the busy count.

Final side-note: Please do realize that the IIS will still initiate app pool shutdowns even on busy app pools. So there is still the need to use RegisterObject.

Have I told you that I really enjoy ASP.NET MVC 3 Razor? Damn, that's nice to work with. I am doing a small, fun project for a friend of mine and I stumbled across the situation that I wanted to have an image as an ActionLink. And since the @Html.ActionLink syntax is really sexy, I wanted to write an Extension method that does the same with an image.

We return a MvcHtmlString, so we can indicate that this sting is not supposed to be html encoded after we return it to the templating engine. Plus we use the handy AnonymousObjectToHtmlAttributes helper method in order to enable us to pass html attributes to the img tag using anonymous classes, just as we are used to by now.

Unfortunatelly we can not tell the helper.ActionLink call to not html encode what we pass as linkText - therefore we fall back on using a place holder that we replace after the fact.

You can create event receivers that react on events of these list types.

To create a custom list definition you should use the visual studio template "List Definition" shipped with the VSeWSS 1.1. If you create a custom list with base type "document library" its id will also be 101. It's just a copy of the template you selected.

First line of schema.xml after creating the custom list definition project:

What are SharePoint Timer Jobs?
SharePoint timer jobs are tasks executed on a scheduled basis by the SharePoint Timer service.

SharePoint comes by default with a lot of timer jobs, like profile synchronisation between Active Directory and SharePoint. To see all currently installed timer jobs go to Central Administration > Operations > Timer Job Definitions.

Developing your own SharePoint Timer Job
To create your own SharePoint 2007 timer job you have to perform the following steps:

Create a class library project.

Create a class derrived from SPJobDefinition that contains the business logic.

Create a class derrived from SPFeatureReceiver that can be deployed and functions as an installer for the timer job.

Nobody wants to do all these steps for each new timer job. So in order to make it simpler to start a new timer job project, I created a visual studio template containing all the neccessary stuff you need.

Visual Studio 2005 Project Template
Andrew Connell wrote a good article on his blog on how to create a SharePoint timer job and to modify the visual studio project to get a deployable .wsp file after building the project. Based on his article I created a reusable visual studio template. In addition I included a setup.bat file that can deploy and undeploy the .wsp file.

Create a new project using the "Custom SharePoint Job" template (Be careful to not use a dot in the project name).

Write your logic inside the Execute method.

Build the project.

Run the setup.bat in your project folder to install, deploy and activate your job (Do not copy it into your bin folder, just run it. Everything is taken care for you. ).

If no errors are shown your timer job is listed in the Timer Job Definition list of the central administration. Navigating to Timer job status you can find out if your job was executed and if there were any errors. In case of an error exception messages are written to the EventLog by SharePoint.

Tip: Before you start customizing your project (namespace, assembly version, file names) look inside every file to get an overview on how everything fits together.

Well, a couple of days ago a coworker and I came across a very strange behaviour concerning Expression Blend while binding to a generic list of an interface. And we were able to reproduce the same behaviour in Visual Studion 2008 as well.

In our example ObservableCollection, where Mitarbeiter is the German word for employee. Sorry about the German throughout the example, but I am currently waiting to board my plane and I did not have enought time to reproduce the screenshot with a purely English example. Well, treat it as your first lesson in German.

Anyway, so IMitarbeiter is the interface describing an employee and here is the important part: it is derived from another interface IPerson (where you are in luck, because German Person = English person. Great stuff, hugh?)

So. As I said the interface IMitarbeiter is now used to define a generic list ObservableCollection which we now want to bind to a WPF interface using Expression Blend. We do not worry about where this ObservableCollection comes from (since I know you are going to as: it come from some distant, well capsulated business tier, going through a GUI specific processing layer using MVP and blablabla... ), we are stricktly concerned with interface matters.

So we are firing up Expression Blend and start doing the object binding, go to the "Create Data Template" Dialog and see this:

So we ONLY see the stuff defined in IMitarbeiter. No Fields coming from IPerson! Why that is is absolutely not clear. Most likely the deverloper of the code that does the reflection to analyse the interface did pass the wrong value that controlled the walking of the inheritance tree. The fun part is: This behaviour is totally reproducable in ASP.NET's databinding as well.

I have to emphasis, this is absolutely a GUI bug. When handcoding against the interface's properties everything works as expected.

I am sorry about this hurried post - but actually we started boarding and I am the last person sitting out her - and the nice lady behind the counter is starting to give me some nasty looks. Gotta go.

The ObjectDataSource is a great new tool in ASP.NET 2.0. But unfortunatelly its primary intended way of using it, is by using static methods or methods of objects that get created using the default constructor. But this is very limiting when building complex websites. Especially complex websites that should be maintainable. That means it is not easy using the ODS when employing software cells, a Model View Presenter approach, capsulation of logic, etc. Especially MVP suffers from a considerable amount of work-around-uglyness, when using the standard ObjectDataSource. Sure, it is possible to override the default object creation process by attaching to the ObjectCreating event.

Ha, EAAAAAAASY to do, right? Just override the method onObjectCreating of the base class ObjectDataSource in the new class AdapterDataSource. Well, if you look at the specs you will realize that the Event is not actually raised in ObjectDataSource - just made public there. The actual event is raised inside ObjectDataSourceView. But still no problemo, right:

thrownewSystem.Exception("The method or operation is not implemented.");

// e.g. return m_owner.CustomDataBinding;

}

}

So now, all we have to do is override the one method of ObjectDataSource in the AdapterDataSource that generates those ObjectDataSourceView instances, right... WRONG. No method seems to be responsible for creating the view.

Using the reflector I found out what was really happening behind the scenes.

The method used is called getView() inside the .NET Framework provided by Microsoft - and it is private! Yeah, baby. All those protected methods inside the ObjectDataSource class are just for show - because the main step in the process of creating the actual view can not be overridden.

But I wasn't going to give up that easily. How about overriding all methods that depend on GetView(). That way I could retire the private GetView() and great my own view creation algorithm. So full of hope I fired up the Analyser. But when I saw the following I started sobbing quietly:

Well, to make a long story short - I did try to do the overriding and stuff - but unfortunatelly those methods sometimes use Attributes that are internal and all kind of crazy stuff that makes you want to beat the programmer that did put that little innocent "private" in front of GetView().

Because it is 3 in the morning and I am really tired I did use this shortcut:

UUUUUUUUUUUUUUUUUGLY! And it breaks when using Mono - because there it's a private property called DefaultView. And the best part about this: There actually is a PROTECTED method called GetView(string viewName). But that does not get used, probably because it returns simply a DataSourceView instead of a ObjectDataSourceView...

Blinq is a tool for generating ASP.NET websites for displaying, creating, and manipulating data based on database schema. Just point Blinq at a SQL database and it will create a website with pages that display sorted and paged data, allow you to update or delete records, create new records, and follow relationships between tables in your database. You don't need to write SQL queries to use Blinq; LINQ will generate optimized queries for you that request just the data you want to show. Blinq uses the May LINQ Community Tech Preview to access data. The code Blinq creates is simple and easy to customize to fit your needs. Everything in the website Blinq creates is meant as a starting point for a website that meets your needs perfectly, so have fun customizing the pages, experimenting with the code, and making it yours!

Preface

For a client of mine, I am currently working out a major best-practice guideline for developing reusable .NET 2.0 programs. Their situation calls for a program design that makes it as easy as possible to reuse modules on multiple websites and on multiple rich clients. So I chose an approach that is a mixture between MVP and software cells to make it easier to reuse a lot of code between a Web App and a Windows Forms App. Unfortunatelly that still calls for duplicated code between multiple web apps, since the Views (Custom Controls) will reside inside the Web Site Project. Therefore it will get increasingly cumbersum to share modules between different web solutions. I thought back to when I used VS 2003 and thought it was really unfortunate that Microsoft changed the web project's look and feel. Why couldn't I create multiple web projects, each representing all of one module's views. I remembered having blogged about WAP a while back - even though for a different reason. It is an optional project style released by Microsoft that provides the same project, build and compilation semantics as the web project model known from VS 2003. Using WAP it is possible to use multiple projects each containing custom controls. Using WAP, it should be possible to use a (simplified) project tree like this:

Com.Hertkorn.Infrastructure.Cells.Forum (Class Library) containing Presenter, BLL and DAL, the M and P part of MVP

Com.Hertkorn.Forms.Views.Forum (Windows Control Library) containing the V part of MVP for windows forms

Yeah, I know this a very crude representation of the actual assembly structure needed for real world MVP and Cells, but I made it simple enough to stress the main point: Now the multiple web solutions only need to reference Com.Hertkorn.Infrastructure.Cells.Forum and Com.Hertkorn.Website.Views.Forum in order to use the forum module. And Windows Applications use Com.Hertkorn.Infrastructure.Cells.Forum and Com.Hertkorn.Forms.Views.Forum. Therefore the duplicate code is reduced to a minimum.

But I had some trouble setting it up using VS 2005. I contacted Scott and he helped me through the process and I got it to work. For anybody else who is interested in the process, I decided to write it down. Even though right now I will not be able to use it. Unfortunatelly the May release of WAP does not render Custom Controls inside the designer that are contained in a different project. This issue will be fixed in the SP1 of VS 2005. That means there will still be no way around WSP and duplicated code til then.

How to set up multiple WAPs in one solution

Now let's get to the good stuff. This is mostly from an email Scott was kind enough to forward me. And even better - he allowed me to blog about it using his stuff. Thanks again for that, Scott!

As I said before - but I'll repeat it here for all of you who skipped the preface. Setting up multiple WAPs can be done with the current version (WAP May 2006 + VS 2005 no SP), but there are some limitations:

It only works for IIS webs.

Design view does not render controls outside the WAP project (to be fixed in SP1)

If you’d like to setup this up to see how it works here are the steps:

Add a new Web Application Project to the solution
C:\MyProjects\MainWeb\SubWeb1
(note this will not be a true IIS sub-web, it’s just a folder in the MainWeb)

Change the build output path to be the bin folder of the MainWeb
Project Properties/Build Tab/Output section.

Change the subweb to be a folder under the same VDIR as the MainWeb
Project Properties/Web Tab/Server Section
Check “Use IIS Web server”
Edit Project URL to http://localhost/MainWeb/SubWeb1

Save All, close and re-open the project properties
You should see application root URL set to http://localhost/MainWeb
This tells you that WAP is correctly detecting the subweb relationship.

There is only one IIS Web application in this model. http://localhost/MainWeb mapped to c:\MyProjects\MainWeb. However with this configuration the site is factored into several WAP projects that build into a common bin in the MainWeb.

To build and run a SubWeb project you must have the latest assemblies from the other projects in the MainWeb bin. Building the solution will take care of this for you.

The main advantage of this configuration is that it allows you to build the SubWeb folders independently into separate assemblies. This works great until you start creating dependencies by consuming controls from other SubWebs. Some sites I’ve seen have created a separate project with all the Controls to avoid this issue.

Depending on your scenario this maybe a good model. The alternative is to create this as a single project, which also works quite well.

The major disadvantage of using this approach is that the designer will not render controls outside it’s immediate project so the Control Project design above won’t render in design view. Unfortunately the WAP developers won’t be able to fix this scenario until Visual Studio SP1 later in the fall.