# Monday, May 04, 2009

A few mornings ago I went into work, and per my usual routine, opened Outlook, opened IE 7 (we are developing an app that has to run against that sorry excuse for a browser), open Visual Studio, etc.

Once my laptop decided it was done with these seemingly simple tasks, I gave focus to VS, went to the File menu, down to Recent Projects and selected that VS solution which is the current source of my income. As soon as the previously-opened files were displayed, Visual Studio simply shutdown - rather quickly, too. There were no messages, warnings, requests for sending an error report to headquarters, etc. it simply shutdown.

Hmm, okay.

So, I tried it again and the same thing happens. So, I did something I rarely do, and rebooted Windows (XP Pro, of course), hoping that would "fix" the problem. Nope, no dice. Meanwhile, a coworker needed some help with something, so I go to his desk and in the process of that discussion, I mention PowerCommands for Visual Studio 2008 to him and he installs it because he really liked my description of the "Collapse Projects" feature, as we have quite a large number of projects in this solution (more than I think we should have, but whatever) and after a few of them are open, solution explorer becomes a bit unwieldy and useless.

No sooner than he installs PowerCommands and starts Visual Studio back up does it close up exactly as it had been doing for me. How serendipituous! Because I had been running PowerCommands for a week or two with no problems though, I was reluctant to think it was the cause of the problem; yet I couldn't deny what my eyes had just seen.

So, I searched around and after seeing this as being a problem for quite a few people, a lot of whom use XAML for WPF, and their various attempts at fixing the problem (my least favorite being to simply uninstall PowerCommands and cease using it), decided to try the following, which I found on Stack Overflow and has worked for all 3 of the people on my team which have had the problem - here is the solution:

You are going to modify the devenv.exe.config file, which can be found, typically, in this folder location:

32-bit Windows
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE

64-bit Windows
C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE

Open the file in Notepad or some other suitable text editor, and add the following (assemblyBinding node shown for context):

      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         ...
         <dependentAssembly>
            <assemblyIdentity name="Microsoft.PowerCommands" publicKeyToken="null" culture="neutral"/>
            
            <!-- For 32-bit systems, uncomment this one
            <codeBase version="1.1.0.0" href="href="C:\Program Files\PowerCommands\Microsoft.PowerCommands.dll"/>
            -->
            
            <!-- For 64-bit systems, uncomment and use this one  
            <codeBase version="1.1.0.0" href="C:\Program Files (x86)\PowerCommands\Microsoft.PowerCommands.dll"/>
            -->
            
         </dependentAssembly>
         ...
      </assemblyBinding>

Hopefully this helps someone, it's a sneaky bug.

Kick It on DotNetKicks.com

posted on Monday, May 04, 2009 5:22:50 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Saturday, April 04, 2009

I want you to look at the following code and try not to think too hard. There is really only one basic assumption even worth mentioning, which is that > 99.999% of the time, you look at source code in Visual Studio (specifically, Visual Studio 2008, not that it matters).

Here is the code we will be discussing for the moment - pretend you are one of my coworkers reading it for the first time, and you need to understand what is going on:

   1: // ...a handful of lines into a method...
   2: webGrid.Columns = WebGridDefinitions.QuarterlyReportColumns(linkUrl);

Now, of what type is the variable webGrid?
How about linkUrl?
I would be willing to bet you may be able to guess, even at this point.


Now, let's say you are still not 100% sure, so you scroll up the method definition a bit to find out, and you find this code:

   1: var linkUrl = htmlHelper.GetVirtualPath("MyAction", "MyController");
   2: var webGrid = new WebGrid(someObject, someData);

Now, of what type is the variable webGrid?
How about linkUrl?
If you don't know at this point, there is little hope for you.


Let's say that instead of the previous bit of code, you find this:

   1: string linkUrl = htmlHelper.GetVirtualPath("MyAction", "MyController");
   2: WebGrid webGrid = new WebGrid(someObject, someData);

Now of what type is the variable webGrid?
How about linkUrl
How is this code any more clear than the code which uses the implicitly-typed variable declaration? Is the redundancy really that useful? Really?!

The only argument I am even willing to consider here is that, somehow, you are not sure what type htmlHelper.GetVirtualPath() returns, and thus the variable linkUrl is a bit ambiguous. But, remember the assumption we began with? You have no excuse now, unless you just started using Visual Studio 5 minutes ago and are not yet familiar with the power of Intellisense.

I posit that using implicitly-typed variable declarations via the var keyword is generally easier to read and maintain than being explicit (and redundant) in declaring variables.

Now, one's personal taste can make this argument somewhat moot, since you can still get the job done either way, but I would argue that it isn't worth pushing your personal tastes on others if they are comfortable with either method. If you want to stay behind the times and turn into a dinosaur, that's fine by me, but don't force me into the same fate because you want to push your subjective tastes on others for your comfort.

smile_tongue

By the way, the WebGrid type here is not a standard type, but that isn't the point. Whatever a "WebGrid" is in this code, it's only as far away as "Go To Definition."

Kick It on DotNetKicks.com

posted on Saturday, April 04, 2009 12:24:50 AM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Tuesday, February 03, 2009

Over the last 4 years, JavaScript has been critical to the majority of the web applications that I have worked on; dealing with the logical organization of said files has always been a less-than-satisfactory experience until about 2 years ago when I began using the following techniques for a easier design-time experience.

Page-Specific JavaScript Files

Let's say I have a page named foo.aspx and I have JavaScript specific to it contained in a file - I name the .js file foo.aspx.js. Then, in a base class for the pages of the application, I have the following code:

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     base.OnLoad(e);
   4:     AttachPageSpecificJavaScriptFile();
   5: }
   6:  
   7: private void AttachPageSpecificJavaScriptFile()
   8: {
   9:     var appRelativeVirtualPath = string.Format("{0}.js", TemplateControl.AppRelativeVirtualPath);
  10:     RegisterJavaScriptFile(appRelativeVirtualPath);
  11: }
  12:  
  13: protected void RegisterJavaScriptFile(string appRelativeVirtualPath)
  14: {
  15:     if (JavaScriptFileExists(appRelativeVirtualPath))
  16:     {
  17:         string url = ResolveClientUrl(appRelativeVirtualPath);
  18:         ClientScript.RegisterClientScriptInclude(url, url);
  19:     }
  20: }

Essentially, for each page in my application, the app will look for a *.aspx.js file that matches the name of the page (in our example, foo.aspx.js) and place, within the rendered page, a script tag referencing it.

Since every request to a given page would need to check to see whether or not an associated .js file existed, and considering the fact that checking with the file system each time would be somewhat costly, I have the following code take care of checking and then caching the results at the application level:

   1: private Dictionary<string, bool> JavaScriptFileRegistry
   2: {
   3:   get
   4:   {
   5:     var javaScriptFileRegistry = Application["JavaScriptFileRegistry"] as Dictionary<string, bool>;
   6:     if (javaScriptFileRegistry == null)
   7:     {
   8:       javaScriptFileRegistry = new Dictionary<string, bool>();
   9:       Application["JavaScriptFileRegistry"] = javaScriptFileRegistry;
  10:     }
  11:     return javaScriptFileRegistry;
  12:   }
  13: }
  14:  
  15: protected bool JavaScriptFileExists(string appRelativeVirtualPath)
  16: {
  17:   var registry = JavaScriptFileRegistry;
  18:   if (registry.ContainsKey(appRelativeVirtualPath) == false)
  19:   {
  20:     registry.Add(appRelativeVirtualPath, File.Exists(Server.MapPath(appRelativeVirtualPath)));
  21:   }
  22:   return registry[appRelativeVirtualPath];
  23: }

To complete this, I have a registry hack that will cause any *.aspx.js files to collapse underneath the *.aspx page in the solution explorer of Visual Studio (i.e. it will hide underneath the page, just like the *.aspx.cs file does). Depending on the version of Visual Studio you are using, the registry hack is different. Here are a couple that I use with Windows XP (I don't know if they differ for Vista because I don't use Vista) - copy each one into a text file and rename it with a .reg extension, then execute the file.

Visual Studio 2005
   1: Windows Registry Editor Version 5.00 
   2: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js] 
   3: @=""
Visual Studio 2008
   1: Windows Registry Editor Version 5.00 
   2: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\{E24C65DC-7377-472b-9ABA-BC803B73C61A}\RelatedFiles\.aspx\.js] 
   3: @=""

You will probably need to reboot your machine before these take effect. Also, the nesting will only take place for newly-added .js files, any that you have which are already named *.aspx.js can be nested by either re-adding them to the project or manually modifying the .csproj file's XML.

Anyway, that is how I do things and it really helps to keep things organized. I also do all of this for user controls (ascx files) - with the above, it should be simple enough to figure out how to do this for the user controls and ascx file extension.

Hope this helps someone!

Kick It on DotNetKicks.com

posted on Tuesday, February 03, 2009 2:21:51 PM (Mountain Standard Time, UTC-07:00)  #    Comments [6]
# Wednesday, October 31, 2007

Since learning about the SubSonic project last week, I have spent a bit of time reading up on it, watching screencasts about it, playing with it, and reading the blog of its creator, Rob Conery. In his post "How MVC, jQuery, and SubSonic Will Make You Smile," Rob talks about the use of .NET 3.5's extension methods, in particular extending a Dictionary<string, string> to return HTML for a drop down list (HTML select); here is what his version of the extension method looks like:

 

 1: public static string ToHtmlSelect(this Dictionary<string, string> listItems, string name,
object selectedValue, object attributes)
 2: {
 3:  // input formats
 4:  string selectFormat = "<select name='{0}' id='{0}' {1}>\r\n{2}\r\n </select>";
 5:  string optionFormat = "\t<option value='{0}' {1}>{2}</option>\r\n";
 6:  
 7:  // output
 8:  StringBuilder sb = new StringBuilder();
 9:  
 10:  foreach (string s in listItems.Keys)
 11:  {
 12:  string selectedFlag = "";
 13:  string text = listItems[s];
 14:  string value = s;
 15:  if (value.ToLower().Equals(selectedValue.ToString().ToLower()))
 16:  selectedFlag = "selected=true";
 17:  sb.AppendFormat(optionFormat, s.ToString(), selectedFlag, text);
 18:  }
 19:  string result = string.Format(selectFormat, name, attributes.ToAttributeList(), sb.ToString());
 20:  return result;
 21: }



 

He also mentions that (on line 19) there is another extension method that "hangs off the object class" which basically enumerates all of the properties of an object, creating a name/value pair attribute list. He doesn't give the code of that extension method, which he states "is ScottGu magic at work and something he shows in his MVC demos." I have yet to watch those demos myself, but the code is probably something akin to this:

 

 1: public static string ToAttributeList(this object attributes) 
 2: {
 3:  StringBuilder sb = new StringBuilder();
 4:  foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(attributes)) 
 5:  {
 6:  sb.AppendFormat("{0}='{1}' ", property.Name, property.GetValue(attributes).ToString());
 7:  }
 8:  return sb.ToString();
 9: }

 

This allows you to pass anonymous types, specifying what might normally be optional parameters, a la something I have been doing in JavaScript for a while using MochiKit (other JavaScript libs exploit the same literal JavaScript object notation in their function signatures). The idea is that you don't need to have a structured method signature that accepts all possible options - you can pass in what you want to specify as a part of an anonymous object. This will make more sense if you have spent any time doing this in JavaScript or want to wait a moment and read on.

Anyway, the whole reason I was even posting on this subject is because of a comment made on Rob's post by one Joe Chung, wherein he states:

"Seeing StringBuilder-generated HTML makes me sad for the future of ASP.NET. Object-oriented ASP spaghetti code is still spaghetti code."

He is referring to the string hacking done in the ToHtmlSelect extension method. I too don't care for it, and simply wanted to show a nicer way of doing this, which leverages objects we already have access to in ASP.NET which do that grunt work for us.

Here is my version of Rob's method (which I still have issues with, but for now we will let those go for the sake of staying on topic) - note, there are no literal strings for those that despise them:

 1: public static string ToHtmlSelect(this Dictionary<string, string> listItems, object selectedValue,
object attributes)
 2: {
 3:  DropDownList htmlSelect = new DropDownList();
 4:  htmlSelect.Attributes.AddAttributes(attributes);
 5:  foreach (string key in listItems.Keys)
 6:  {
 7:  ListItem item = new ListItem(listItems[key], key);
 8:  item.Selected = (key.ToLower().Equals(selectedValue.ToString().ToLower()));
 9:  htmlSelect.Items.Add(item);
 10:  }
 11:  return htmlSelect.ToHtml();
 12: }

 

Now, my version does not use the ToAttributeList() extension method hanging off of  object - mine uses something a bit different, but an extension method nonetheless (although a bit naive, it will suffice for our purposes):

 

 1: public static void AddAttributes(this System.Web.UI.AttributeCollection attributeCollection,
object attributes)
 2: {
 3:  foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(attributes))
 4:  {
 5:  attributeCollection.Add(property.Name, property.GetValue(attributes).ToString());
 6:  }
 7: }

 

My extension method hangs instead off of System.Web.UI.AttributeCollection because my version of the ToHtmlSelect() method works with the System.Web.UI.DropDownList object, which uses that as the place to store its attributes.

The other key to mine is the following extension method which wraps a technique I have been using for over 2 years to create HTML (I didn't figure it out on my own, but can't remember where I saw this exactly - I think in the Google Group for the AjaxPro.NET component back when it was simply Ajax.NET):

 

 1: public static string ToHtml(this Control control)
 2: {
 3:  StringWriter sw = new StringWriter();
 4:  HtmlTextWriter htw = new HtmlTextWriter(sw);
 5:  control.RenderControl(htw);
 6:  return sw.ToString();
 7: }

 

Note - this can be used for all sorts of Control-derived ASP.NET HTML wrapper objects to get you some HTML without string hacking in your layers of code:

 

 1: Calendar c = new Calendar();
 2: string calendarHtml = c.ToHtml();

 

Notice Joe - no literal strings! That should make you happy (I know it makes me happy!).

Now, I love hacking JavaScript as much as the next guy (been doing it hardcore for the last 2.5 years even with ASP.NET because it is too much fun!), but hacking strings to create HTML is still not that fun. Even in JavaScript I don't do it if I don't have to, preferring to use functions that handle that for me (MochiKit has some simple DOM functions for handling HTML creation).

Anyway, hope this is of some use to someone out there!

 

Technorati Tags: , , , ,
Kick It on DotNetKicks.com

posted on Wednesday, October 31, 2007 12:38:37 PM (Mountain Standard Time, UTC-07:00)  #    Comments [11]
# Tuesday, February 27, 2007

 

The company I work for is hiring -  whether you are a project manager, senior-level Java developer, Microsoft application developer or a web design/usability expert, Software Technology Group has something for you.

I have worked for STG for over 2 years now and can tell you that, without a doubt, working for STG has been one of the highlights of my career.

Kick It on DotNetKicks.com

posted on Tuesday, February 27, 2007 9:28:28 AM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Friday, October 17, 2003
Just basic info on my 'new' job
Kick It on DotNetKicks.com

posted on Friday, October 17, 2003 12:06:36 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]