Jeroen Swart

.NET Architect

HttpWebRequest, HttpWebResponse and cookies

For one of my projects I'm working with HttpWebRequest and HttpWebResponse to retrieve data from a webserver. The code on the server is in PHP which uses cookies to keep track of sessions.

After some research I found the CookieContainer is to be created once and set on each request. My code initially looked something like this:

CookieContainer cookieContainer = new CookieContainer();

HttpWebRequest firstRequest = (HttpWebRequest)HttpWebRequest.Create(url);
request.CookieContainer = cookieContainer;

HttpWebResponse firstResponse = (HttpWebResponse)firstRequest.GetResponse();

HttpWebRequest secondRequest = (HttpWebRequest)HttpWebRequest.Create(url);
request.CookieContainer = cookieContainer;

HttpWebResponse secondResponse = (HttpWebResponse)secondRequest .GetResponse();

At first it appeared to work. After the first request, the cookies came back in both the response and the CookieContainer. But the second request didn't work, at least the server responded as if no cookies were sent.

With the aid of wireshark, I discovered that the cookies simply weren't sent. And after some debugging I found that the CookieContainer stores the cookies per domain in a domaintable. Although the domainname on each cookie is correct, the domainname in the table is prefixed with a dot ('.'). I'm assuming that the cookies aren't sent, because the prefixed domainname doesn't match the domain I'm sending the next request to.

If I add the cookies to the CookieContainer myself, after getting the response, the cookies are sent as they should and all he requests work fine. With some checks added, the code looks as follows:

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.Cookies != null && response.Cookies.Count > 0)

I still feel I must have missed something because, according to each example I've found, just setting the CookieContainer should be enough for all to work. If anyone has a suggestion, please leave a comment. For now, I'm sticking with my workaround.

Executing powershell scripts

I'm using powershell a lot for performing upgrade actions on an existing Sharepoint installation. I try to keep the manual tasks to a minimum, since the (exact) same actions must be executed on different environments (DTAP).

Powershell scripts won't execute like a command file (like double-clicking in the explorer). Instead you need to open a commandline, navigate to the correct folder, start the powershell environment and then you can execute the powershell script. This is not so much an issue when a whole set of scripts need to be executed, but when I just want to run a single script this feels like a lot of work just to start a single script. So to make executing a powershell script a little easier, I've created a simple command file that will execute a single script. It works simply by dropping the desired powershell script on it in the explorer.

Create a command file with a name like 'ExecutePowershell.cmd' and put in the following code:

@echo off.
echo Execute powershell:
echo %1%

powershell.exe "& "%1%""
@echo on

The trick here is of course in the way powershell is started. You can use this syntax to run scripts from a file, like so:

powershell "& .\scriptfile.ps1"

Don't forget the .\ if you're running a script from the current directory (or powershell won't find the script). And when the path to the script contains spaces, place it between double double quotes (because the quotes are used within an, already quoted, string), like so:

powershell "& ""Installation Scripts\scriptfile.ps1"""

Or run a single (or several) statements, like so:

powershell "& get-process"

BlogEngine.NET code-formatting issues

With a previous post, I had some trouble with the code-formatting in BlogEngine.NET. I didn't have time to investigate, so I quickly fixed it with some inline styling. But planning to post some more code in the future, I decided to look into it today. Quickly I found my problem: I had forgotten to put the language into the code-element. So in that particular case I added ':js' and it all worked fine.

Now I had code-formatting working, but I wasn't very pleased with the results. Having looked at the code, I found the options for adding line-numbers and alternating line-styles. A first issue was that the line-numbers didn't align correctly. I thought it would be a minor styling issue. But then, adding more lines of code, my whole page layout got messed up. After a quick look at the code I found the problem: an alternating row is started with a p-tag, but is ended with a div-tag. This is fixed with a small modification as demonstrated below:

  • Open the SourceFormat.cs file in the App_Code/Extensions/CodeFormatter folder
  • Locate the FormatCode method (the one with parameters source, lineNumbers, alternate, embedStyleSheet & subCode); mine is at line 186
  • In this method, locate the following code (it's near the top of the while-loop):
    if (alternate && ((i % 2) == 1))
        sb.Append("<p class="alt">");
  • Change the p in <p class="alt"> into div, so the code will look like:
    if (alternate && ((i % 2) == 1))
        sb.Append("<div class="alt">");
  • Save the changes and upload the file

Another thing I noticed, was that the tabs or spaces in front of a line didn't show. This happens because browsers render multiple spaces as a single space. The code formatter changes a tab into a number of spaces, which I decided to change as follows:

  • In the same SourceFormat.cs, locate the following line (almost at the top of the method):
    sb.Replace("\t", string.Empty.PadRight(_tabSpaces));
  • Replace it with the following code:
    StringBuilder tabSpaces = new StringBuilder();
    for (int tabIndex = 0; tabIndex < _tabSpaces; tabIndex++)
        tabSpaces.Append(" ");
    sb.Replace("\t", tabSpaces.ToString());
  • Again, save the changes and upload the file

This only correctly replaces tabs in the code, not spaces. I guess a better solution would be to leave the original Replace, and then replace all leading spaces with &nbsp;. But that's for another time ;-).

IE6 focus problem

Today I had some trouble with setting the focus on an input element within an overlay panel in IE6. To be more specific: I had to set the focus on the lastname textbox in the search-argument panel for the people-search page in Sharepoint. Calling the focus() method worked in every opther browser except, of course, IE6.

The code that was causing the problem is as simple as this:


Apparently this is an ancient IE6 bug. Luckily the problem is easily fixed by using the setTimeout function. Just wrap the offending code like so:

setTimeout(function() { document.all['lastname'].focus() }, 0);

Debugging in the GAC

When you want to debug an assembly that has been deployed to the GAC (e.g. an assembly that is part of a Sharepoint solution), the easiest way is to change one of the settings in Visual Studio (2005, 2008 or 2010):

  • Open the Visual Studio Options dialog (Tools -> Options)
  • Select Debugging in the left pane
  • In the right pane, locate the Enable Just My Code (Managed only) node
  • Uncheck all the childnodes under the Enable Just My Code (Managed only) node
  • Uncheck the Enable Just My Code (Managed only) node
  • Select OK

BlogEngine.NET tag casing

I'm not sure why, but BlogEngine.NET converts all tags to lowercase. I like my tags to appear as I entered them (like ASP.NET & LINQ), so I decided to change the way my BlogEngine.NET installation handles tags. Luckily, the only needed modification is in the code that stores the tags:

  • Open the Add_entry.aspx.cs file in the admin/Pages folder
  • Locate the btnSave_Click method
  • In this method, locate the following line:
  • In this line remove the ToLowerInvariant part, changing it into:
  • Save the changes and upload the page
  • Since the tags were stored as lowercase when you added or updated your posts and pages, you need to manually update the tags in the existing posts and pages

HttpHandler configuration

Sometimes you have a problem for which the solution is so simple and obvious, you can't believe you've overlooked it.

It happened to me a short while ago with an HttpHandler in a website that is using a presentation-service for the presentation-logic (I'll post about this service later). All the pages in the website are dynamically build, based on the results of a call to the presentation-service. The url's don't refer to existing pages and the HttpHandler is supposed to handle all incoming requests. Except, all I got was 404's. I had configured the necessary wildcard mapping, but it took me a while to find that the "Verify that file exists" option was checked. With this option checked, the HttpHandler is only called when the request matches to a physical file on disk. Which of course defeats the purpose of my HttpHandler.

Here's how to correctly configure a wildcard mapping in IIS6:

  1. Open the IIS Manager (Start -> Administrative Tools -> Internet Information Services (IIS) Manager)
  2. Find the node for the website or virtual directory you want to configure (expand the computer node and the Web Sites node if needed)
  3. Right-click the node and select Properties
  4. Select Configuration......
  5. In the Application Extensions list, select the row with extension '.ascx' and click Edit
  6. Make sure the entire content of the Executable field is selected, then right-click inside the Executable field and select Copy; this ensures that we have the correct path to the aspnet_isapi.dll
  7. Select Cancel to close the dialog without changes
  8. Select Insert...
  9. Right-click inside the Executable field and select Paste
  10. Uncheck the Verify that file exists checkbox
  11. Select OK three times to store the new wildcard application mapping and to close all the dialogs
  12. The configuration is finished, you can close the IIS Manager

New Year

So, here it is, my new year's resolution for 2009 2010. To finally write content for my blog.

I'll be writing about my experiences and the problems & solutions I encounter during my work and hobbies.

Happy new year everybody!