Tuesday, March 31, 2009

Defaulting a class to public from Visual Studio

Something that's been niggling at me over the years that I've used Visual Studio is that when a class is created in the IDE it's always created with no public access modifier and so defaults to internal access. E.g.
class Class1
{
}
What I want is the class to be created as such:
public class Class1
{
}
And I know that I'm not alone because when I ask my co-workers they agree. I asked this question on StackOverlow and was pointed in the right direction. On my 64 bit machine I still haven't solved this problem but on my 32-bit XP machine I have.
I first edited the Class.cs file inside the C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip package and added the public modifier to the class.
This didn't work.
I then found this folder: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplatesCache\CSharp\Code\1033\Class.zip and did the same addition on the Class.cs file in this folder and it worked.
I'm not sure if I can blow away this cache version of the ItemTemplates and it would be re-created? I didn't want to try because my development environment is too brittle to mess with at this level. I would guess that at some point the cache (if it is a cache) may become invalidated and so the first edit will be necessary and prevail in the long term.

The prefix cannot be redefined from within the same start element tag

The following snippet of code had me stumped for a while:

XDocument xDoc = new XDocument(new XDeclaration("1.0", 
                                       
"utf-8", "yes"),
   
new XComment("This is a comment"),
   
new XElement("elementName",
       
new XAttribute("xmlns", "http://fake/namespace"),
       
new XAttribute("version", "1.00"),
       
new XElement("innerelement",
           
new XAttribute("myAttribute", "att_value"))
           
));

// The prefix '' cannot be redefined from ''
// to 'http://fake/namespace'
// within the same start element tag..
string test = xDoc.ToString();

I was getting a  "The prefix '' cannot be redefined from '' to 'http://fake/namespace' within the same start element tag.." when running this.

The solution is to define the namespace before creating the XML document and prefixing this namespace to all elements that you create. Here is the working code.

XNamespace xn = "http://fake/namespace";

XDocument xDoc = new XDocument(new XDeclaration("1.0",
                                       
"utf-8", "yes"),
   
new XComment("This is a comment"),
   
new XElement(xn + "elementName",

       
new XAttribute("version", "1.00"),
       
new XElement(xn + "innerelement",
           
new XAttribute("myAttribute", "att_value"))
           
));
string test = xDoc.ToString();

 

Saturday, March 28, 2009

Hybrid ASP.NET MVC and WebForms app

I'm in the process of adding ASP.NET MVC to an existing ASP.NET WebForms app in Visual Studio 2008. One of the neat features of an ASP.NET MVC app is that when you right click on the Controllers folder in the Solution Explorer the "Add" menu item has a "Controller..." menu item on it and right clicking on the Views folder causes the "Add" menu item to have a "View..." sub-menu item on it.

It took me forever to work out how to get my WebForms app to also show those menu items. It turns out that you have to edit the .csproj file for the WebForms app and find the section that reads:

<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

The to that add the following GUID:

{603c0e0b-db56-11dc-be95-000d561079b0};

Such that it now reads as follows:

<ProjectTypeGuids>{603c0e0b-db56-11dc-be95-000d561079b0};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

Wednesday, March 25, 2009

Improving my JavaScript

I've been listening to Douglas Crockford's The JavaScript Programming Language at the YUI Theater and have learned a number of interesting things that I wanted to note before I forget them.

JavaScript Values: Numbers (64-bit floating point), Strings, Booleans, Objects, null, undefined

False values: false, null, undefined, "" (empty string), 0, NaN
True values: everything else, e.g. "0", "false"

== and != do coercion before comparing (e.g. different types can be considered the same)

=== and !== do not do coercion and the type as well as value must be equal

&& returns the second operand if the first is true otherwise it returns the first operand, e.g.
if(a) { return a.member; } else { return a; }
can be written as
return a && a.member;

|| returns the first operand if it is true otherwise the second as such it can be used to fill in default values, e.g.
var last = input || nr_items;

labelled breaks, a for() loop can be labelled and then a break statement can refer to that label.

Wednesday, March 11, 2009

Disable UAC on Server 2008 and Vista

I'm running Windows Server 2008 as a workstation. I ran into the usual problems with UAC and eventually disabled it.

My logic is this: On XP we didn't have UAC and I never got into trouble. The reason that I didn't get into trouble is because I'm a highly sophisticated user (software developer). I don't surf dubious web sites or follow suspicious links, and I don't install software from sources that I haven't researched or aren't linked to from multiple reputable places.

I believe that UAC shows it's true value to the mother-in-law (unsophisticated user) and protects them against valid dangers. I have seen my parents clicking on all sorts of links that I wouldn't go anywhere near. They need UAC and it should be switched on for them.

For us developers my belief is that leaving UAC switched on will cost us more in lost productivity than it will gain us in protection.

Disable UAC on Windows Server 2008

 

  1. Open the Control Panel.
  2. Click User Accounts.
  3. Click Turn User Account Control on or off.
  4. (If you receive a User Account Control message click Continue.)
  5. Clear the "Use User Account Control (UAC) to help protect your computer" check box, and then click OK.
  6. Click Restart Now to apply the change right away, or click Restart Later and close the User Accounts tasks window.

Disable UAC on Vista

  1. Similar to the above except when you open the Control Panel just type UAC into the search box (top right).
  2. You will then see the "Turn User Account Control (UAC) on or off. Follow this link.
  3. Clear the check box and then click okay.

 

Friday, March 6, 2009

Streaming a zip file from an ASP.NET web site

I was recently having a really tough time trying to debug the streaming of a zip file from an ASP.NET web app to a browser. The code was fairly simple and is repeated all over the web which gave me confidence in how robust it is:

FileInfo toDownload = new FileInfo(fullFileName);
if (toDownload.Exists)
{
   Response.Clear();
   Response.ContentType = "application/zip";
   Response.AppendHeader("Content-Disposition", "attachment;filename=" +
          toDownload.Name);
   Response.AppendHeader("Content-Length", toDownload.Length.ToString());
   Response.TransmitFile(fullFileName);
   Response.End();
}

The client side error that I was getting was:

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled. Details: Error parsing near 'PK...'.

The good thing about seeing the "PK" in the error is that it told me that the server was indeed sending the zip file. The first two characters in a zip file are PK which is one way to identify a zip file by opening it and reading the first two characters.

The control on the web page that kicked off the download action shown above was inside an UpdatePanel and it was this that was causing the problem. Eilon Lipton wrote the error message above and he explains it in this blog post

The solution it turns out is to put a PostBackTrigger in the UpdatePanel:

<Triggers>
   <asp:PostBackTrigger ControlID="ibDownload" />
</Triggers>

This will force the click to do a regular postback instead of an asyncronous postback and solved the problem.

Wednesday, March 4, 2009

Skewed results

Most web sites collect stats on usage. One of these figures is browser type and version.

I've just been using H&R Block for my tax returns this year and find that their site won't work well with anything other than Internet Explorer (IE). Whenever I get an email from them saying that there's a message I fire up IE to go and check the message.

Now the problem with this is that their stats will show that most of their users are using IE. This is because anybody using them will be forced to use IE. So they will never know which browser their users usually use and thereby creating skewed results for their site usage.