Posts
114
Comments
127
Trackbacks
10
June 2010 Entries
Dots.do.not.matter@gmail.com

I wish I had known about this before I went to TechEd two years ago - I'm still getting email from vendors who scanned my badge there…

Gmail ignores periods in user names and doesn't care about capitalization. (This is not true of Google Apps - It does care about dots.)

If your email address is homerjsimpson@gmail.com, all of these variations will be delivered to your Inbox:

You can create a filter to perform actions (forward, trash, apply a label, etc.) based on the "To" address. In this example, I'm applying a "might be spam" label to messages addressed to "homer.j.simpson":

Capture

If you're filling out a form for a site where you don't trust that they won't
"share your email address with trusted partners who will send you special offers and useful information":

 (spam5)

…you might want to give them a "dotty" email address so can have more control over the messages you receive.

Posted On Tuesday, June 29, 2010 7:38 PM | Comments (2)
Thursday "Virtual Brown Bag" Meetings

One of the best ways for developers to learn from each other is "brown bag meetings", where they bring their lunch to a conference room and share tips & tricks.

That's something I've always wanted to do, but there aren't a lot of others at my organization who are interested in doing that.

I've been lurking at "Virtual Brown Bag" meetings organized by Claudio Lassala the last couple of months, and have enjoyed them a lot.

They're held every Thursday from noon until 1PM U.S Central time via LiveMeeting.

Claudio's suggestions for the sort of thing that people could share at the meetings:

  • A shortcut in Visual Studio, Windows, whatever, that you’ve learned or have been using for a while;
  • A tool (free or commercial) that you can’t live without it;
  • A tool that you may have run across, find it to be interesting, but are not sure about it yet. Maybe somebody else already uses the tool and can jump in;
  • An article, book, or blog posts you’ve read and want to talk about. It may be something you’ve read and couldn’t quite understand; maybe somebody else can shed a light on it for you;
  • Some command, language feature, workaround, design pattern, etc., anything you’ve learned or run across and could share with the others;
  • Something that you’ve found a way to implement but still think that there’s got to be a better way to do it; maybe somebody else can tell you what the other way is;

It's usually Claudio & JB who take turns presenting, but they genuinely encourage everyone to share. I think others probably feel intimidated by "the wizards of smart", though :) I've contributed a few links and comments via the Q&A interface, but hope that sometime soon I'll have something cool enough to get on the mic and share my desktop.

You can join the weekly meetings via this link: https://www323.livemeeting.com/cc/usergroups/join?id=van&role=attend

If you can't wait 'til Thursday and want to see a recording of a previous meeting, see http://virtualaltnet.com/Recordings.

There's also a wiki with links to topics discussed during the meetings: http://sites.google.com/site/vbbwiki/

If anyone knows of other "virtual brown bags" held midday in the U.S., please let me know. I have four other free weekday lunch hours :)

EDIT: 10/9/2010 - There's a shiny new Virtual Brown Bag web site: http://www.virtualbrownbag.com/

Posted On Monday, June 28, 2010 10:16 PM | Comments (0)
St. Louis Day of .NET - August 20-21 2010
Technorati Tags: ,

 

That's right - The St. Louis Day of .NET is a two-day event!

That's how we do things in "the Lou".

Over 500 developers attended last year's event, and we're expecting to break that record this year.

I've been to DevLink and the Heartland Developer's Conference, and I thought that the 2009 St. Louis Day of .NET was at least as good as those events.

Nearly 100 national and regional speakers have submitted sessions, and the organizers are currently posting announced sessions to the site, with many more to come. You can check out the currently announced sessions here: http://www.stlouisdayofdotnet.com/Sessions.aspx.

This year's event will also include many informal "Open Space" sessions where all attendees with similar interests can discuss current trends or issues they are facing in today's real-world development environments.

Admission is $125 if you register before July 10th - $200 after that, so be sure to register early.

The event will again be held at the beautiful Ameristar Casino Resort & Conference Center, and all attendees are invited to a social networking event at Ameristar's HOME Nightclub on Friday evening. If you're coming from out of town (or if you're a St. Louisan who wants to live like a high roller for a night), Ameristar is offering special room rates.

All attendees will receive:

  • A brainful of .NET knowledge
  • Breakfast and lunch on both days
  • A chance to make new friendships and professional connections
  • A handsome St. Louis Day of .NET polo shirt that you can wear proudly at work
  • Other great Day of .NET swag

Check the St. Louis Day of .NET web site (http://www.stlouisdayofdotnet.com/) for details.

Posted On Monday, June 28, 2010 9:24 PM | Comments (0)
Happy 10th Birthday, CODE magazine
Technorati Tags: ,

 

I really enjoyed listening to the June 18th episode of the "CodeCast" podcast: http://www.code-magazine.com/CodeCast/Index.aspx?messageid=99ad6813-73c7-429c-9370-812b4058f145.

Ken Levy, Markus Egger and Rod Paddock reminisced about the 10 years that have passed since Markus and Rick Strahl came up with the wild idea of branching out from the software business to magazine publishing.

CODE has by far been the most useful magazine for me during the past 10 years (and one of the few survivors). MSDN is also good, but it frequently feels like reading a transmission beamed back from the future from a highly intelligent alien civilization :)

I love that CODE lets authors take as much space as needed to cover a topic. The July/August 2010 issue includes an 18-page article about SSIS, and 17 pages about getting started with Git.

Humorous highlights from the podcast include:

  • the story about how there was another "Code magazine" owned by Larry Flynt, and for a while if people went to http://www.code-magazine.com without the hyphen they were redirected to the site for Flynt's more famous magazine.
  • reminiscing about how some of the others used to have Markus-esque hair (I remember seeing Rod Paddock's mullet in the editor's notes every month.)
  • stories about memorable covers, including the "warrior princess" that Markus whipped up overnight in an emergency, and the painted hand showing Visual Studio languages (that didn't include C++)! I think that's the first issue I came across, and I'm ashamed to say i never noticed that the hand had six fingers.:

WarriorPrincess 6Fingers

(Please don't sue me for "leveraging" the artwork from the CODE site :)

 

The podcast reminded me of the days before the internet took off, when books and magazines were the main way that developers learned their craft.

I used to find something useful in every issue of Visual Basic Programmer's Journal, especially the articles by Francesco Balena.

The Art of Programming with Visual Basic

The resource that was most influential in my early days of PC development was Mark Warhol's book "The Art of Programming With Visual Basic". (It looks like you can get a used copy on Amazon for a penny! http://www.amazon.com/Art-Programming-Visual-Basic/dp/0471128538)

Mark's book was full of great advice and was hilarious. It's the most entertaining book about software that I've ever read.

I Binged and Googled and couldn't find anything about Mark, but I hope he's still in the software business and somehow does a search for himself and comes across this article and finds out that he made a difference in my career.

Thanks to all of the authors (and later bloggers and podcasters) who've inspired me over the years.

Good luck to CODE in the next 10 years. I can't imagine what the software world will look like in 2020.

Posted On Saturday, June 26, 2010 6:12 PM | Comments (0)
"Cloning" divs with jQuery
Technorati Tags: ,

 

I'm sure I've "invented" a technique that's been done by many others (and I don't doubt that there's a slicker way to do it), but…

Sometimes I'll want to have an identical chunk of HTML repeated more than once on a web page, for example: a search page with "Search" and "Clear Fields" buttons both above and below the search field inputs. I'd like to just render that HTML once on the server, than "clone" it on the client.

For my site, I established a convention where the "clone source" div has a class name with the prefix "jsCloneSource_", and the "clone target" div(s) include a class name with the prefix "jsCloneTarget_" (and both class names have the same suffix).

Here's what my search page looks like. Lines 3-5 describe a div with the class name "jsCloneSource_SearchButtons" where the buttons child view is rendered. Line 11 contains an empty div with the class name "jsCloneTarget_SearchButtons":

   1:      <% Html.BeginForm(MVC.Widget.Search()); %>
   2:      
   3:      <div class="jsCloneSource_SearchButtons buttonsAboveForm">
   4:          <% Html.RenderAction(MVC.Search.SearchFormButtons());%>
   5:      </div>
   6:   
   7:      <fieldset class="searchFormFieldset">
   8:          <!-- (search Labels and TextBoxes) -->
   9:      </fieldset>
  10:   
  11:      <div class="jsCloneTarget_SearchButtons buttonsBelowForm"></div>
  12:   
  13:      <% Html.EndForm(); %>

The JavaScript file referenced in my site's master page looks for divs with a "jsCloneSource_" prefix. For each one it finds, it finds divs with the "jsCloneTarget_" prefix and the same suffix (in this example, "_SearchButtons") and replaces the target div HTML with a copy of the source div HTML:

   1:  $(document).ready(function () {
   2:      $("div[class*='jsCloneSource_']").each(function () {
   3:          var html = $(this).html();
   4:          var targetCssClass = getCloneTargetClass($(this).attr("class"));
   5:          if (targetCssClass) {
   6:              $("div." + targetCssClass).html(html);
   7:          }
   8:      });
   9:  });
  10:   
  11:  function getCloneTargetClass(sourceClasses) {
  12:      var classNames = sourceClasses.split(" ");
  13:   
  14:      for (var i = 0; i < classNames.length; i++) {
  15:          var className = classNames[i];
  16:          if (className.substr(0, 14) === "jsCloneSource_") {
  17:              return className.replace("jsCloneSource_", "jsCloneTarget_");
  18:          }
  19:      }
  20:      
  21:      return null;   
  22:  }

It doesn't save a lot of server processing in this example, but I think it could greatly simplify things in scenarios like a grid where the same dropdown list is displayed in each row.

If I've reinvented the wheel, please let me know. I love to write code, but I also love to delete it when there's an existing tested alternative.

Posted On Saturday, June 26, 2010 9:42 AM | Comments (2)
The Big Boy MVC Series
Technorati Tags: ,

 

I wish I had discovered this before part 19. I've got some catching up to do…

Evan Nagle's working / blogging / joking / cartooning his way through building an ASP.NET MVC 2 web site in what looks like the .NET world's answer to Why's (Poignant) Guide to Ruby:

http://www.weirdlover.com/2010/05/29/the-big-boy-mvc-series-building-an-asp-net-mvc-web-application-all-by-yourself-part-1/ 

Looks like a bit more entertaining ride than NerdDinner or the Music Store.

Posted On Tuesday, June 22, 2010 8:34 PM | Comments (0)
Norweigan Developers Conference Videos

Videos of presentations from NDC 2010 are now available at: http://streaming.ndc2010.no/tcs/

It looks like there are about 48 available. I'm particularly looking forward to:

  • Mads Torgersen: "C# Quo Vadis?" (followed by a discussion on the future of C# with Mads, Eric Lippert, Gafter and Jon Skeet)
  • Roy Osherove: "Beautiful Teams & Leaders"
  • Greg Young: "5 reasons why projects using DDD fail"
  • Jon Skeet: "If I Ruled the World - C# 5.0 According to Jon"
  • Eric Evans: "What I've learned About DDD Since the Book"
  • K. Scott Allen: "Advanced Tips & Tricks for ASP.NET MVC 2"
  • Jon Skeet: "Noda time: An Alternative Date & Time Framework"
  • Kevin McNeish: ".NET Design Patterns for Agile Software Processes"
  • Jon Skeet: "Reactive Extensions (Rx)" (I'm a big Skeet fan - How does he know so much about C# working at a company that doesn't allow Windows :)
  • ...and the already legendary Rob Conery session: "The Next Big Thing Or Cool-Kid Koolaid? Slicing Through The Rhetoric of MVC vs. WebForms"

Skål!

Posted On Tuesday, June 22, 2010 7:35 PM | Comments (0)
Kansas City Developer Conference Recap

Technorati Tags: ,

 

Thanks to the KC development community for a great free event. The Johnson County Community College provided very nice facilities.

I’m the sort of guy who would willingly drive 4+ hours each way for a free XL (or “developer medium”, as Richard Campbell calls it) T-shirt, but got a lot more than that out of the event. Here's a recap of the sessions I attended:

Why Kanban?

speaker: Troy Tuttle

Troy is a “pragmatic agilist” at AdventureTech (not AdventureWorks – I was distracted for a while by my mistaken impression that Troy worked for a fictional Microsoft demo company – By the way, please don’t check the part of my resume that includes my work history at Contoso and Northwinds ;).

I vaguely knew that Kanban was based on Japanese lean manufacturing and involved Post-it notes on whiteboards, but that was about it. Troy did a nice job of giving me a better picture of Kanban. It looked like his slides were pretty similar to the deck from his Topeka DNUG presentation, so I’ll take a look at those to try to keep what I learned in my brain for more than a few days.

The Zen of ASP.NET and MVC

speaker: Javier Lozano

I had listened to Javier being interview on Hanselminutes during the drive from St. Louis, so it was fun to meet him in person a few hours later. He presented a nice overview of why MVC is such an improvement over WebForms (even without his MVC Turbine plug-in, which he refrained from pimping :)

TDD with SpecFlow, a Cucumber-like Tool for .NET

speaker: Darren Cauthon

A friend of mine has been blogging about how much he likes Cucumber, but he’s much more a Ruby wannabe than I am, so I hadn’t looked into it much. I was impressed Darren’s demonstration of how SpecFlow works with NUnit to make it easy to turn English language (or English-esque “Gherkin” language, anyway) into testable specs and produces results that customers and developers alike can understand. Darren says this was his first presentation, which is hard to believe – he did a great job. I hope he’ll consider applying for a speaker slot at the St. Louis Day of .NET.

Design by Compartment

speaker: George Westwater

George presented a very thought-provoking talk about Design by Compartment, a pragmatic alternative to DDD.

jQuery and JSSpec

speaker: Phil Japikse

Phil’s presentation was subtitled “Making the Web Developer Friendly” (which can be pronounced as either:
“Making the Web Developer-Friendly” or:
“Making the Web Developer Friendly”).

I heart jQuery. I think John Resig should be awarded a Nobel Prize and the Presidential Medal of Freedom.

I wasn’t familiar with JSSpec, though. It’s a BDD framework for testing JavaScript. I’ve been putting off the question of how to test my JavaScript code. Thanks to Phil for letting me know one way to tackle that task.


The only suggestion I can make for an improvement to the KCDC (I assume there will be more – it sure looked like a success to me) is to say on the web site exactly where the conference is located. I circled the campus for a while before finding a collection of cars that looked sufficiently geeky enough to tell me that which building to report to ;)

Thanks again, KC, and I hope some of you will make the trip to the St. Louis Day(s) of .NET in August.

Posted On Saturday, June 19, 2010 3:26 PM | Comments (0)
Which ASP.NET MVC Grid?
Technorati Tags: ,,

 

I started looking at the MvcContrib grid earlier this week, and it looks promising.

At the Kansas City Developer’s Conference today, Javier Lozano showed a demo using JqGrid.

When I asked Javier about JqGrid, he said I might want to look at Telerik’s ASP.NET MVC Extensions Grid.

Any recommendations would be welcome. (If you can give me a grid comparing the capabilities of each, that would be great ;)

Posted On Saturday, June 19, 2010 12:39 PM | Comments (2)
An Alphabet of Eponymous Aphorisms, Programming Paradigms, Software Sayings, Annoying Alliteration

Malcolm Anderson blogged about “Einstein’s Razor” yesterday, which reminded me of my favorite software development “law”, the name of which I can never remember. It took much Wikipedia-ing to find it (Hofstadter’s Law – see below), but along the way I compiled the following list:

  • Amara’s Law: We tend to overestimate the effect of a technology in the short run and underestimate the effect in the long run.
  • Brook’s Law: Adding manpower to a late software project makes it later.
  • Law of Demeter: Each unit should only talk to its friends; don't talk to strangers.
  • Einstein’s Razor: “Make things as simple as possible, but not simpler” is the popular paraphrase, but what he actually said was “It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience”, an overly complicated quote which is an obvious violation of Einstein’s Razor. (You can tell by looking at a picture of Einstein that the dude was hardly an expert on razors or other grooming apparati.)
  • Finagle's Law of Dynamic Negatives: Anything that can go wrong, will—at the worst possible moment. - O'Toole's Corollary: The perversity of the Universe tends towards a maximum.
  • Greenspun's Tenth Rule: Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. (Morris’s Corollary: “…including Common Lisp”)
  • Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
  • Issawi’s Omelet Analogy: One cannot make an omelet without breaking eggs - but it is amazing how many eggs one can break without making a decent omelet.
  • Kaner’s Caveat: A program which perfectly meets a lousy specification is a lousy program.
  • Liskov Substitution Principle (paraphrased): Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
  • Mason’s Maxim: Since human beings themselves are not fully debugged yet, there will be bugs in your code no matter what you do.
  • Occam's Razor: The simplest explanation is usually the correct one.
  • Parkinson’s Law: Work expands so as to fill the time available for its completion.
  • Quentin Tarantino’s Pie Principle: “…you want to go home have a drink and go and eat pie and talk about it.” (OK, he was talking about movies, not software, but I couldn’t find a “Q” quote about software. And wouldn’t it be cool to write a program so great that the users want to eat pie and talk about it?)
  • Raymond’s Rule: Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter. 
  • Sowa's Law of Standards: Whenever a major organization develops a new system as an official standard for X, the primary result is the widespread adoption of some simpler system as a de facto standard for X.
  • Turing’s Tenet: We shall do a much better programming job, provided we approach the task with a full appreciation of its tremendous difficulty, provided that we respect the intrinsic limitations of the human mind and approach the task as very humble programmers. 
  • Udi Dahan’s Race Condition Rule: If you think you have a race condition, you don’t understand the domain well enough. These rules didn’t exist in the age of paper, there is no reason for them to exist in the age of computers. When you have race conditions, go back to the business and find out actual rules.
  • Van Vleck’s Kvetching: We know about as much about software quality problems as they knew about the Black Plague in the 1600s. We've seen the victims' agonies and helped burn the corpses. We don't know what causes it; we don't really know if there is only one disease. We just suffer -- and keep pouring our sewage into our water supply.
  • Wheeler’s Law: All problems in computer science can be solved by another level of indirection... Except for the problem of too many layers of indirection. Wheeler also said “Compatibility means deliberately repeating other people's mistakes.”.
  • Yourdon’s Rule of Two Feet: If you think your management doesn't know what it's doing or that your organisation turns out low-quality software crap that embarrasses you, then leave.
  • Zawinski's Law of Software Envelopment: Every program attempts to expand until it can read mail. Zawinski is also responsible for “Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems.” He once commented about X Windows widget toolkits: “Using these toolkits is like trying to make a bookshelf out of mashed potatoes.”
Posted On Friday, June 18, 2010 9:50 AM | Comments (1)
Kansas City Developer's Conference
Technorati Tags: ,

 

I just found about about / registered for Saturday’s Kansas City Developer’s Conference, and am going to make the drive over from the right side of the state (Hey, no offense, KC – I’m just looking at a map, and St. Louis is on the right side, Kansas City’s on the left).

(I’m sure the event’s been mentioned on geekswithblogs several times, but I’m on a “staycation” this week, getting cabin fever, and noticed @leebrandt’s tweet today.)

I’m looking forward to some of the presentations in the Agile and Patterns tracks.

I’m going to have to get up pretty early Saturday morning to descend from St. Louis to Kansas City (Again, no offense – St. Louis is just at a higher elevation*, that’s all), so if you see a tired-looking guy wandering around wearing a St. Louis Day of .NET shirt, please be nice.

I’m not sure how much longer registration will be open, but here’s the link: http://kcdc.eventbrite.com/


*Not true – St. Louis is closer to sea level than Kansas City, but I’ll start my drive from the top of the Arch, OK?

Posted On Thursday, June 17, 2010 11:09 AM | Comments (1)
Devs For Wendy

If you’re a developer in the New York City area, please check out Devs For Wendy, benefitting Wendy Friedlander and her family…

Wendy is a 30 year old software agilista from Long Island. She's a strong WPF developer and a firm believer in the agile method of development including pair programming and TDD. Wendy is wife and mother of a beautiful girl named Kaylee who will be 2 in August.

In August of 2009 Wendy learned that she had a rare and agressive pediatric cancer called aveolar rhabdomyosarcoma. Her treatment consists of high dose chemotherapy and radiation. She has had to leave her job, and her husband has been forced into part time work in order to care for their daughter.

Please join us at 7pm on July 7th 2010 for a dinner benefiting Wendy brought to you by the NYC development community.

You can also donate via PayPal.

Posted On Thursday, June 17, 2010 7:36 AM | Comments (0)
Microsoft Tag Tagged Me

I got EXTREMELY lucky last week and won an HP Mini 311 notebook from a Microsoft Tag Twitter contest.

I did my required tweet to enter last Tuesday, and one hour later received notification that I had won the weekly drawing.

Apparently you can tweet up to 500 times (I pity the followers of those who do that), so it was really lucky that I won, and I sympathize with those who had been really trying.

If you would like to try your luck, there are seven weekly prizes left, and you can find out about the contest here: http://tag.microsoft.com/ttcontest.aspx

twitterTag

For a free PC, I thought it was the least I could do to find out what Microsoft Tag is. I was vaguely aware of those pastel-y triangle-y square things that look like someone put one of Don Johnson’s Miami Vice outfits through a shredder, and knew that the company I work for (one of the world’s largest consumer products companies) was looking into putting them on our products, packaging and advertising, but didn’t know much more about the technology.

I thought they were just an improvement over bar codes, and would be used in retail store scanners, but I was mistaken. These tags are meant to be scanned by consumers using their mobile phones, to get instant access to information, websites, reviews, etc. Scanning a tag can open a web page, import a contact card, or dial a phone number, play a video…

Tag reader software can be installed on Windows Mobile, iPhone, Symbian, Blackberry, Android, J2ME, and other phones (and I suspect that it will be available for Windows Phone 7 also :).

There are built-in tracking, metrics and analysis tools, to help companies using Tag make decisions about their marketing expenditures.

(And they don’t have to look Miami Vice-y – They can be customized to reflect the personality of the person or a brand.)

Looks like interesting stuff. You can find out more at http://tag.microsoft.com.

Posted On Wednesday, June 16, 2010 9:54 AM | Comments (0)
I’m offended by your antisemantic views
Technorati Tags:

 

CSS class names should usually be “semantic” (describing the meaning of the styled areas, e.g. “article-title”, “author-info”, “errror-message”, not “structural” (e.g. “left-side-navbar”, “small-title”).

…and they definitely shouldn’t explicitly describe the styling. I’ve seen a class names like “bold-red-12pt”. If you’re going to do that, you might as well just use inline font tags.

This article explains it much better than I can…

Posted On Tuesday, June 15, 2010 9:09 PM | Comments (1)
ASP.NET MVC localization DisplayNameAttribute alternatives: a better way

 

In my last post, I talked bout creating a custom class inheriting from System.ComponentModel.DisplayNameAttribute to retrieve display names from resource files:

        [LocalizedDisplayName("RememberMe")]
        public bool RememberMe { get; set; }
 

That’s a lot of work to put an attribute on all of my model properties though. It would be nice if I could intercept the ASP.NET MVC code that analyzes the model metadata to retrieve display names to make it automatically get localized text from my resource files. That way, I could just set up resource file entries where the keys are the property names, and not have to put attributes on all of my properties.

That’s done by creating a custom class inheriting from System.Web.Mvc.DataAnnotationsModelMetadataProvider:

   1:      public class LocalizedDataAnnotationsModelMetadataProvider :
   2:          DataAnnotationsModelMetadataProvider
   3:      {
   4:          protected override ModelMetadata CreateMetadata(
   5:              IEnumerable<Attribute> attributes, 
   6:              Type containerType, 
   7:              Func<object> modelAccessor, 
   8:              Type modelType, 
   9:              string propertyName)
  10:          {
  11:              var meta = base.CreateMetadata
  12:                  (attributes, containerType, modelAccessor, modelType, propertyName);
  13:   
  14:              if (string.IsNullOrEmpty(propertyName)) 
  15:                  return meta;
  16:   
  17:              if (meta.DisplayName == null)
  18:                  GetLocalizedDisplayName(meta, propertyName);
  19:   
  20:              if (string.IsNullOrEmpty(meta.DisplayName))
  21:                  meta.DisplayName = string.Format("[[{0}]]", propertyName);
  22:   
  23:              return meta;
  24:          }
  25:   
  26:          private static void GetLocalizedDisplayName(ModelMetadata meta, string propertyName)
  27:          {
  28:              ResourceManager resourceManager = MyResource.ResourceManager;
  29:              CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
  30:   
  31:              meta.DisplayName = resourceManager.GetString(propertyName, culture);
  32:          }
  33:      }

Line 11 calls the base CreateMetadata method.

Line 17 checks whether the metadata DisplayName property has already been populated by a DisplayNameAttribute (or my LocalizedDisplayNameAttribute). If so, it respects that and doesn’t use my custom localized text lookup.

The GetLocalizedDisplayName method checks for the property name as a resource file key. If found, it uses the localized text from the resource files.

If the key is not found in the resource file, as with my LocalizedDisplayNameAttribute, I return a formatted string containing the property name (e.g. “[[RememberMe]]”) so I can tell by looking at my web pages which resource keys I haven’t defined yet.

It’s hooked up with this code in the Application_Start method of Global.asax:

    ModelMetadataProviders.Current = new LocalizedDataAnnotationsModelMetadataProvider();
Posted On Monday, June 14, 2010 6:04 PM | Comments (6)
ASP.NET MVC localization DisplayNameAttribute alternatives: a good way

 

The ASP.NET MVC HTML helper methods like .LabelFor and .EditorFor use model metadata to autogenerate labels for model properties.

By default it uses the property name for the label text, but if that’s not appropriate, you can use a DisplayName attribute to specify the desired label text:

        [DisplayName("Remember me?")]
        public bool RememberMe { get; set; }

I’m working on a multi-language web site, so the labels need to be localized. I tried pointing the DisplayName attribute to a resource string:

        [DisplayName(MyResource.RememberMe)]
        public bool RememberMe { get; set; }

…but that results in the compiler error "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type”.

I got around this by creating a custom LocalizedDisplayNameAttribute class that inherits from DisplayNameAttribute:

   1:  public class LocalizedDisplayNameAttribute : DisplayNameAttribute 
   2:  {
   3:      public LocalizedDisplayNameAttribute(string resourceKey)
   4:      {
   5:          ResourceKey = resourceKey;
   6:      }
   7:   
   8:      public override string DisplayName
   9:      {
  10:          get
  11:          {
  12:              string displayName = MyResource.ResourceManager.GetString(ResourceKey);
  13:   
  14:              return string.IsNullOrEmpty(displayName)
  15:                  ? string.Format("[[{0}]]", ResourceKey)
  16:                  : displayName;
  17:          }
  18:      }
  19:   
  20:      private string ResourceKey { get; set; }
  21:  }

Instead of a display string, it takes a constructor argument of a resource key. The DisplayName method is overridden to get the display string from the resource file (line 12).

If the key is not found, I return a formatted string containing the key (e.g. “[[RememberMe]]”) so I can tell by looking at my web pages which resource keys I haven’t defined yet (line 15).

The usage of my custom attribute in the model looks like this:

        [LocalizedDisplayName("RememberMe")]
        public bool RememberMe { get; set; }

That was my first attempt at localized display names, and it’s a technique that I still use in some cases, but in my next post I’ll talk about the method that I now prefer, a custom DataAnnotationsModelMetadataProvider class…

Posted On Monday, June 14, 2010 5:26 PM | Comments (1)
45% off Apple and Microsoft dev books from Manning through June 17

I’m really enjoying “ASP.NET MVC 2 In Action” – Think I’ll pop for “JQuery in Action” now:

http://campaign.constantcontact.com/render?v=001cQcN0FSUz163y8UN8daOKl273F1ld9De4lyrZZkZD2vOrQCOrZ21vmO0hNEKL8hP1eVm0aHcF4PEd5OUEWwg7qkJhUrJ-yrnzXtWKhq2XvhouzWyZAmHQa2ctUauOXhV

Posted On Wednesday, June 9, 2010 7:06 PM | Comments (0)
Hello, T4MVC – Goodbye, ASP.NET MVC “magic strings”
Technorati Tags: ,,

 

I’m working on my first ASP.NET MVC project, and I really, really like MVC.

I hate all of the “magic strings”, though:

    <div id="logindisplay">
        <% Html.RenderPartial("LogOnUserControl"); %>
    </div>
    <div id="menucontainer">
        <ul id="menu">
            <li><%=Html.ActionLink("Find Dinner", "Index", "Dinners")%></li>
            <li><%=Html.ActionLink("Host Dinner", "Create", "Dinners")%></li>
            <li><%=Html.ActionLink("About", "About", "Home")%></li>
        </ul>
    </div>

They’re prone to misspelling (causing errors that won’t be caught until runtime), there’s duplication, there’s no Intellisense, and they’re not friendly to refactoring tools.

 

I had started down the path of creating static classes with constants for the strings, e.g.:

            <li><%=Html.ActionLink("Find Dinner", DinnerControllerActions.Index, Controllers.Dinner)%></li>

…but that was pretty tedious.

 

Then I discovered T4MVC (http://mvccontrib.codeplex.com/wikipage?title=T4MVC).

Just add its T4MVC.tt and T4MVC.settings.t4 files to the root of your MVC application, and it magically (and this time, it’s good magic) generates code that allows you to replace the first code sample above with this:

            <div id="logindisplay">
                <% Html.RenderPartial(MVC.Shared.Views.LogOnUserControl); %>
            </div>
            <div id="menucontainer">
                <ul id="menu">
                    <li><%=Html.ActionLink("Find Dinner", MVC.Dinners.Index())%></li>
                    <li><%=Html.ActionLink("Host Dinner", MVC.Dinners.Create())%></li>
                    <li><%=Html.ActionLink("About", MVC.Home.About())%></li>
                </ul>
            </div>

It gives you a strongly-typed alternative to magic strings for all of these scenarios:

  • Html.Action
  • Html.ActionLink
  • Html.RenderAction
  • Html.RenderPartial
  • Html.BeginForm
  • Url.Action
  • Ajax.ActionLink
  • view names inside controllers

But wait, there’s more!

It even gives you static helpers for image and script links, e.g.:

    <img src="<%= Links.Content.nerd_jpg %>" />
 
    <script src="<%= Links.Scripts.Map_js %>" type="text/javascript"></script>

…instead of:

    <img src="/Content/nerd.jpg" />
 
    <script src="/Scripts/Map.js" type="text/javascript"></script>

 

Thanks to David Ebbo for creating this great tool.

You can watch an eight and a half minute video about T4MVC on Channel 9 via this link: http://channel9.msdn.com/posts/jongalloway/Jon-Takes-Five-with-David-Ebbo-on-T4MVC/.

You can download T4MVC from its CodePlex page: http://mvccontrib.codeplex.com/wikipage?title=T4MVC.

Posted On Sunday, June 6, 2010 7:47 AM | Comments (4)
ASP.NET Localization: Enabling resource expressions with an external resource assembly
Technorati Tags: ,,

 

I have several related projects that need the same localized text, so my global resources files are in a shared assembly that’s referenced by each of those projects.

It took an embarrassingly long time to figure out how to have my .resx files generate “public” properties instead of “internal” so I could have a shared resources assembly (apparently it was pretty tricky pre-VS2008, and my “googling” bogged me down some out-of-date instructions). It’s easy though – Just change the “Custom Tool” to “PublicResXFileCodeGenerator”:

resources2  

…which can be done via the “Access Modifier” dropdown of the resource file designer window:

resources1 (1)

 

A reference to my shared resources DLL gives me the ability to use the resources in code, but by default, the ASP.NET resource expression syntax:

<asp:Button ID="BeerButton" runat="server" Text="<%$ Resources:MyResources, Beer %>" />
 

…assumes that your resources are in your web site project.

 

To make resource expressions work with my shared resources assembly, I added two classes to the resources assembly:

1) a custom IResourceProvider implementation:

 
   1:  using System;
   2:  using System.Web.Compilation;
   3:  using System.Globalization;
   4:   
   5:  namespace DuffBeer
   6:  {
   7:      public class CustomResourceProvider : IResourceProvider
   8:      {
   9:          public object GetObject(string resourceKey, CultureInfo culture)
  10:          {
  11:              return MyResources.ResourceManager.GetObject(resourceKey, culture);
  12:          }
  13:   
  14:          public System.Resources.IResourceReader ResourceReader
  15:          {
  16:              get { throw new NotSupportedException(); }
  17:          }
  18:      }
  19:  }

 

2) and a custom factory class inheriting from the ResourceProviderFactory base class:

 

   1:  using System;
   2:  using System.Web.Compilation;
   3:   
   4:  namespace DuffBeer
   5:  {
   6:      public class CustomResourceProviderFactory : ResourceProviderFactory
   7:      {
   8:          public override IResourceProvider CreateGlobalResourceProvider(string classKey)
   9:          {
  10:               return new CustomResourceProvider();
  11:          }
  12:   
  13:          public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
  14:          {
  15:              throw new NotSupportedException(String.Format(
  16:                  "{0} does not support local resources.", 
  17:                  this.GetType().Name));
  18:          }
  19:      }
  20:  }

 

In the “system.web / globalization” section of my web.config file, I point the “resourceProviderFactoryType" property to my custom factory:

 
<system.web>
    <globalization culture="auto:en-US" uiCulture="auto:en-US"
    resourceProviderFactoryType="DuffBeer.CustomResourceProviderFactory, DuffBeer" />

 

This simple approach met my needs for these projects , but if you want to create reusable resource provider and factory classes that allow you to specify the assembly in the resource expression, the instructions are here.

Posted On Saturday, June 5, 2010 5:15 PM | Comments (3)
“ASP.NET MVC 2 in Action” Ebook is complete

I just got email notification that ASP.NET MVC2 in Action is complete.

I had signed up for the Manning Early Access Program (MEAP), which allowed me to reserve a hardcopy of the book, a PDF of the completed chapters, and the PDF of the entire version 1 (ASP.NET MVC in Action) book all for $49.99.

I’m working on my first MVC application, and it’s been a big help so far.

Congratulations to Jeffrey Palermo, Ben Scheirman, Jimmy Bogard, Eric Hexter, and Matthew Hinze for completing what looks like a great book!

Posted On Tuesday, June 1, 2010 6:32 PM | Comments (0)
Tag Cloud