Wednesday, January 28, 2009

IIS7 and url escaping

First off, sorry I'm such a slacker. Posting to this blog hasn't been one of my top priorities. I have a lot of draft posts that I've started or dropped a few thoughts into and never returned to. I'll work on getting through those. Enough of that.

I've been working on a community that's hosted on Community Server off and on for a while now. Recently my primary client upgraded the test environment server over to a new box with a new version of the OS, SQL Server, and IIS. This has caused some problems with some problems here and there but most of those were taken care of easily. One weird one was that the tagging system in Community Server wasn't working quite right anymore. Single token tags such as "foo" would work as expected however multi token tags "foo bar" were no longer working and I was getting a page not found error. After a lot of digging around I discovered the issue:

IIS6 treats "+" and "%20" in a url the same however IIS7 does not. Community Server uses "+" to indicate spaces in their tag url
s. So for a single token tag you have something like:

[url]/tags/foo/default.aspx

and for a multiple you have:

[url]/tags/foo+bar/default.aspx

At the suggestion of a developer I know I tried replacing the "+" w/ "%20" and low and behold it worked fine. The solution to this issue is to allow double url escaping by adding the following to your web config inside of the System.WebServer element:

<security>
    <requestFiltering allowDoubleEscaping="true" />
</security>



Blog Post on Breaking Changes on IIS7:
http://learn.iis.net/page.aspx/381/aspnet-20-breaking-changes-on-iis-70/

Community Server documentation on this issue here:
http://docswiki.communityserver.com/wikis/cs20085docs/configuring-iis7-for-community-server.aspx

Friday, April 11, 2008

Javascript onUnload and postback

So I just ran into an interesting scenario. I have a custom control where I need an event to fire before postback but I don't want to have to add an OnClientClick event in every page that uses the control. In fiddling with the javascript onunload event I found that oddly enough the unload event fires after postback to my aspx page. The solution? Use onbeforeunload instead:

window.onbeforeunload = unload;

function unload() {
alert("unload");
}

Wednesday, April 2, 2008

Asp Uploader Control Weirdness

It's been a while since my last post and I apologize for that, I need to post more often because I tend to run across interesting things to post about. I'm just lazy.

I ran into an issue the other day when working on a SharePoint site that had me confused for a while. For some reason when you access the Uploader.PostedFile.InputStream property twice (even when setting the Position in the file to zero manually upon setting up a new reference to it and wrapping things in a using statement) the second time you read it you’ll get an empty file. Which is fucked up.

Anyhow, I fixed that by accessing the Uploader.PostedFile.InputStream property in one of the instances where I wanted to access the file but didn't actually need an input stream. I haven’t really been able to make sense out of why it works this way but not the other but whatever. Life goes on.

Friday, January 11, 2008

GDI and Ampersand Rendering

Yesterday I spent a while tracking down a bug in a library that I wrote a while back. One of the things that the library is used for is drawing text in fonts that aren't web safe to be used as headings and whatnot. So if I want the phrase "Out Of Office" drawn in whatever font I just created (this isn't actually a real use case) I can just upload the ttf file to my fonts directory on the server and use the control to generate an image dynamically that will fit the space. The tool even provides caching so after a string with a given set of params has been requested N times it caches it and will load the image from the cache upon future requests. But enough about that.

The bug I tracked down yesterday was related to the ampersand character and the fact that for some reason when the string I wanted to draw contained the ampersand character then no text was being drawn. I wouldn't get any exceptions or anything I just wouldn't get any text. The result image was just the background color I'd requested the size that the text would require if it was in the image. Without the ampersand char it worked as expected.

In GDI when you go to draw a string via Graphics.DrawString you can optionally display hot keys (meaning underlining a specific key to specify that it's a shortcut visually). When I'm drawing a string I'm passing in a StringFormat object which contains some formatting information (horizontal alignment and such). One of the properties of StringFormat is HotkeyPrefix which is used to set the Hotkey functionality for the string (Hide, Show, or None). Now you might think that simply setting it to None (which is the default btw) would result in no Hotkey formatting being considered when rendering the string. But you'd be wrong.

After a great deal of trial and error I got the ampersand to render when I replaced each ampersand with 2 ampersands (an escape of sorts) and then set HotkeyPrefix to Hide. Why this worked I'm not sure and it's kind of counterintuitive but whatever. That's how I fixed it.

Monday, December 17, 2007

Seattle Startup Weekend

The next Startup Weekend has been announced and it's in Seattle. I've been somewhat involved in helping to get things going and am really excited to see how it turns out. The event will be Jan 25-27th. More details to follow.

You can register for the event or read up on what startup weekend is at the Seattle Weekend Announcement. It will likely fill up quickly.

Saturday, December 15, 2007

You know the fun Restart Now/Restart Later Windows pop-up that shows up when you have updates that you need to install? The one where if you click later it will just pop up again in a few minutes? I'm term serv'ed into a server that I don't have administrator rights on and it popped up. Only since I don't have shutdown/restart rights the restart button is grayed out. Since I have no choice in the matter why does the freakin thing even show up?

So I just drag the little window off to the edge of the screen where it will sit quietly and not bother anyone anymore.

Thursday, December 13, 2007

Creating Something Beautiful

I was catching up Joel Spolsky's blog earlier and he had a series of posts containing the transcription of a talk he gave at Yale (part 1, part 2, and part 3). The posts are long but I thought they were worth reading. In particular there were two things he touched on that I thought were interesting.

Testing
In part 1 he talks about testing and the fact that there's no realistic way you could have automated tests cover everything. He argues that at the very core the only thing you can do is check to ensure that one program behaves like another or according to a set of tests. Those tests however can't possibly cover everything that needs testing.

He gives an example of the move at Microsoft to more of an automated test process and the rumored laying off of testers who don't know how to code to bring in SDETs who can program those automated tests. He points out that those tests can't test a number of things that require someone actually look at the product such as whether thing were laid out in an orderly and logical fashion and whether the product has a feeling of continuity.

You can test a lot of things through automated testing but there's always going to be a need for someone with a sharp eye to go through and make sure everything is ship shape.

In-House Programming
In part 2 he writes about why an in-house programmer sucks. He gave three reasons and they are all very good but the one that really struck me was the second:

"So, the number two reason product work is better than in-house work is that you get to make beautiful things."

Numbers 1 and 3 are that you never get to do things the right way and that at a software company your business is software so there's more incentive for the company to treat developers like rock stars (and who doesn't want to be treated like a rock star now and again).

Number 2 stood out to me because it struck a chord somewhere and reminded me why I started getting interested in programming. I wanted to create something cool and useful and beautiful.

I played guitar for a long time and I didn't do it to pick up chicks (though I may have used it in that way a time or two), I did it because I wanted to create something. I wanted to write something that would touch someone or cause someone to open up their eyes to a new perspective or challenge an existing perspective. I wanted to create something beautiful. I used to sit and play for hours, now I only play around on the guitar here and there when my son (who is 18 months old on Saturday) points to it and either wants to watch me play and dance a bit here and there or wants to sit in the case after I've pulled the guitar out.

Currently I'm working on various small (on a scale of all development undertakings) projects. Some of them are pretty cool (like the one I'm working on now that I'll post about once it launches) and some of them aren't as cool (like forms). Though I can still work towards creating flexible and elegant solutions. In the grand scheme of things they may not be groundbreaking or hugely significant but they're still opportunities for elegance.

Someday I'd like to create something beautiful and significant. And I will.
I'm still so SO super busy. That said there's some sql stuff I wanted to post.

Copying One Table To Another
Want to copy all the data including the structure (with the exceptions of the constraints) to a new database?

Insert Into NewDatabaseName
Select * From OldDatabaseName

Want to just copy the structure without the rows?

Insert Into NewDatabaseName
Select * From OldDatabaseName
Where 1 = 2

What could be easier.

Unions
Unions are pretty cool. That said if you're using text, ntext, or image types you need to use a Union All. If you don't you'll get an ugly error like this:

Server: Msg 8163, Level 16, State 4, Line 1
The text, ntext, or image data type cannot be selected as DISTINCT.

Stored Procedure Output Parameters
If you're running a stored procedure that returns a data set you'll need to call SqlCommand.ExecuteReader(). If you also have an output parameter specified in the procedure you might be tempted to do something like this:

sqlDataReader = command.ExecuteReader();

string outputParam = command.Parameters["foo"].Value;

while (reader.Read()) {
//read your rows
}

reader.Close();
command.Connection.Close();

The above code will compile fine but you'll get strange exceptions on the line where you're reading out the param value. If you investigate you'll find that even though command.Parameters["foo"] isn't null command.Parameters["foo"].Value is. That's because when you're using a sql reader you need to close the reader before you can read the output param(s):

sqlDataReader = command.ExecuteReader();

while (reader.Read()) {
//read your rows
}

reader.Close();
string outputParam = command.Parameters["foo"].Value;
command.Connection.Close();

Now you know. And knowing is half the battle.

Friday, November 16, 2007

I've been crazy busy lately. I'm still crazy busy but I've decided to make a post here. I'm going to start posting little snippets of code that I've found useful or problems that I've resolved that I want to keep the solution to around.

Log story short I needed a TreeView to postback when the checkbox associated with an element changed. This search led me to This Post. The solution proposed there works great however there's one issue that took me a long time to hunt down. The last post on the page lists some script to spit out after you've created your object:

<script type=\"text/javascript\">
if (document.all) {
document.getElementById(YOURIDHERE).onclick = foo;
}
</script>

This code works great in IE but doesn't in Firefox. It took me a long time to figure out why but it's due to the document.all like. Firefox doesn't support document.all. If you see that somewhere and like supporting firefox users then don't use it. That's all for now.

Monday, October 22, 2007

On Prefix and Postfix Increment Operators

For those familiar with increment operators and their prefix and postfix usage skip down to just below the pseudo-code.

When you have a number and you want to increment it while stepping through a collection or something you can use the increment operator ("++"). That will add one to whatever number you pair with the operator. When using increment operators there are prefix and postfix forms. The prefix form is when you put the operator before the variable containing the number and the postfix is afterwards (++i vs. i++). Functionally these the placement results in very different functionality, if you use the prefix form then the number is incremented before it is evaluated whereas if you use postfix then it is evaluated after it's value is used. In other words (this is really simplified pseudo-code):

variable n = 0;
print n;
print n;

Will print the number 00.

variable n = 0;
print ++n;
print n;

Will print 11.

variable n = 0;
print n++;
print n;

Will print 01.

Awesome, let's continue.

The issue I have with this is that I can only use one at a time. I just came across a scenario where I actually got kind of excited about a line of code I had just written (which doesn't happen very often). The scenario was that I had a string containing tokens I needed however each token I needed was surrounded on both sides by tokens that I don't need. So I had something like:

;junk;ValueICareAbout;junk;junk;ValueICareAbout;junk;

This led me to writing the following lines of code:

for (int i = 0; i < tokens.Length; i++) {
  string token = tokens[++i++];
  Trace("Found Token: " + token);
}


Sadly the compiler informed me that what I had done is totally not allowed. Which made me sad. Because ++i++ looks awesome. And yes, I do realize that I'm a huge dork.