Thursday, February 26, 2009

Serving File to User - Frustration!!

For several years now I've had a neat little ASP.Net method which simply serves up a file to the end user. It sets all the headers so that the user is prompted to save or open the file, and handles large files and so on. No trouble.

Today, there was trouble.

I had an application where Internet Explorer, upon having the file served to it, opened the file contents in the browser instead of asking how to handle it. It was a PDF and the raw contents of the PDF were appearing.

It wasn't happening under Firefox or Chrome, but was consistently happening under IE.

Over an exceedingly frustrating day, I tried very many things. I tried using Release mode instead of Debug, in case Debug was adding something to the Headers that was causing grief. I tried cache-busting. I tried running the page in a full window as opposed to the pop-up that it was intended to be in... all to no avail.

In the end, the solution was straightforward but a little surprising. The page in question contained some JavaScript which initiated AJAX calls - basically to monitor if the file was ready to be downloaded or not, and to giving a constantly updating ETA. When the file was being served by ASP.Net, the code ended with a Response.End - which I mistakenly assumed that the rest of the page wasn't rendered.

However, when I put the JavaScript into a MultiView and ensured that it was only displayed if we WEREN'T serving the file, it all suddenly worked.

So... if you are serving a file, make sure that your page doesn't output any javascript. I assumed the Render would be bypassed after the Response.End but... mistaken was I.

Tuesday, February 24, 2009

HyperLinkField doesn't like mailto

Just came across a "feature" of ASP.Net's GridView which I hadn't hit before.

If you have a HyperLinkField and point the DataNavigateUrlFields to a property or field that returns "mailto:x@y.com", it doesn't work. The entire link gets short circuited and only the text returns.

Apparently this is for security purposes, although it would be nice to be able to override it, EnableEventValidation-style (who knows - maybe you can and I've missed it...)

I thought you might be able to use BoundField, but it turns out that it HtmlEncodes everything, so it looks like a template is the one way to go...

Friday, February 20, 2009

Code Documentation in Visual Basic .NET 2008

In Visual Studio 2008, Visual Basic finally inherited code documentation shortcuts. This is simply the very convenient mechanism by which typing 3 apostrophes on the line before a method declaration or similar will automatically resolve through intellisene or macroing or some kind of magic woven by the IDE pixies into a template for entering the documentation for that method.

For example:

''' <summary>
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
''' <remarks></remarks>

Great stuff! As long as it's enabled. I had two projects in the one solution where typing ''' resolved into a documentor template as above for one of the projects, but merely sat there gathering dust in the other.

After spending more time than I care to admit trying to figure out what IDE settings option I needed to change in order to enable it, or even what library I needed to import in order to get it to work (yes, I was getting desperate and trying everything...) I found the solution, which in the end makes some sense but is definately lateral as an answer to this particular question.

I'd check the Project settings, but none of them were editor-related: they all seemed compile-related. Which they are. But it turns out that if you don't have "Generate XML document file" ticked in your Visual Basic project, the IDE won't offer up XML documentation comments to you.

Thursday, February 19, 2009

IIS Processes that Bloat

One of the peskiest problems in maintaining a web server is IIS processes that bloat. The whole server runs like a dog and when you check the Task Manager, you find that one service is taking up 80% of the CPU cycles and half a GB of RAM...

You have the PID of the process through Task Manager, but I used to have difficulty nailing down which process was causing the problem from there.

The simple trick is to run the command line command iisapp. This script simply lists all running application pools and their PIDs. It lets you pick the faulty PID straight away (as long as you can remember the name of the command...)

Thursday, May 8, 2008

Cookie glitch in Vista/IE7?

Hrm...

Found an odd one. My login code, which has worked fine for years, was having trouble today. Jane at Logosdor complained that she couldn't log in. I tried to test it on mine, only to find that I couldn't log OUT!

Pretty extensive debugging and diagnostics ensued, only to find that:

* It all worked perfectly under Firefox
* Under IE, the authentication cookie was not being saved on my machine
* My cookie file for the site APPEARED to have not been updated since January (4 months), according to IECV (Inernet Explorer Cookie Viewer).

So... was IE7 under Vista failing to update my cookie files? I performed ye olde "delete cookies" and... it worked fine afterwards.

Be nice to get to the bottom of this one day. Until then, might have to hand out the obligatory "delete all your cookies" advice to anyone having trouble. Making me sound just like a Microsoft technician...

Actually... the Net was playing up today. A bit slow. This hasn't happened before... I wonder if cookies were somehow being stripped from the web response? Nah... if that's the case it should have still failed after the mass deletion.

Thursday, May 1, 2008

AjaxControlToolkit TabContainer not maintaining ActiveTabIndex between postbacks - Workaround

Problem
The AjaxControlToolkit TabContainer does not maintain the state of its ActiveTabIndex if the postback is caused by a GridView or DataList.

Workaround
Add the following javascript to your page:

<script type="text/javascript">
function OnTabContainer_ActiveTabChanged(sender, args)
{
sender.get_clientStateField().value = sender.saveClientState();
}
</script>

And add the following attribute to your TabContainer:


OnClientActiveTabChanged="OnTabContainer_ActiveTabChanged"