aspnet, javascript, gists comments edit

I had to parse a culture-sensitive currency value from a string and couldn’t figure out how to do it. I’m using ASP.NET AJAX to do String.localeFormat("{0:c}", value) for writing a currency value to a textbox, but getting it back out… not so easy. The Number.parseLocale extension provided with ASP.NET AJAX is cool for parsing out numbers in a culture-sensitive fashion… if they don’t have a currency symbol.

So, time to hook that up. Here’s what I came out with:

Number.parseCurrency = function Number$parseCurrency(str) {
  /// <summary>
  /// Parses a string containing a culture-sensitive currency value into a number.
  /// </summary>
  /// <param name="str" type="String">
  /// The numeric string with optional currency symbol to convert into a number.
  /// </param>
  /// <returns type="Number" />
  var currencySymbol = Sys.CultureInfo.CurrentCulture.numberFormat.CurrencySymbol;
  var numberOnly = str.replace(/\s+/g, '').replace(eval("/\\" + currencySymbol + "/g"), '');
  var parsed = Number.parseLocale(numberOnly);
  if (isNaN(parsed)) {
    // Try all 5 possible negative number formats.
    var customCi = Sys.CultureInfo.InvariantCulture;
    for (var i = 0; i < 5; i++) {
      customCi.numberFormat.NumberNegativePattern = i;
      parsed = Number._parse(numberOnly, customCi);
      if (!isNaN(parsed)) {
        break;
      }
    }
  }
  return parsed;
}

What it’s doing:

  1. Get the currency symbol for the current culture.
  2. Take the currency-formatted string and remove all whitespace and that currency symbol. Now you have a number that is either positive or ostensibly adheres to one of the known negative number formats.
  3. Parse that string in a culture-sensitive fashion into a number. Usually this will work straight-off. Unfortunately, the negative currency format can sometimes differ from the negative number format. For example, a negative number might be -1.23, but a negative currency format might be like ($1.23). So if the parsing comes back as not-a-number, chances are that’s what you’re hitting.
  4. If the parsed value comes back as not-a-number, we know there are five pre-defined negative number formats that are possible in ASP.NET AJAX: ["(n)","-n","- n","n-","n -"] For each of those possible formats…
    1. Create a temporary culture, based on the Invariant culture, that uses the selected negative number pattern. (When you ask for the Invariant culture it actually creates a brand new instance every time, so doing this won’t change the built-in Invariant culture.)
    2. Try to manually parse the number given your custom culture.
    3. If it succeeded, return that value.

At the end of all that if you still come out with NaN, it’s not a currency value.

If someone knows a better way to do this, I’m all ears.

If you want it, go for it. YMMV, no warranty expressed nor implied. If you find a defect, post to the comments and I’ll update.

downloads, vs, coderush comments edit

This is sort of a niche thing, so if you don’t know what I’m talking about, don’t worry. However, people who write DXCore plugins (CodeRush/Refactor) sometimes need to do some action based on what context the user is currently in. For example, you may need to enable a function or hide a button or something if the user is in a designer screen. The problem is, it’s hard to debug that sort of thing - there’s nothing that says “here’s the context(s) you’re currently in” so when you’re writing your plugin you can do the right thing.

That’s what I made - a plugin that [optionally] polls for the list of contexts the user is currently in so you can debug the plugin you’re writing.

DX_ContextLab
Window

If you want it (or any of the other awesome FREE community plugins), head over to the DXCore Community Plugins site.

aspnet, javascript, gists comments edit

I’m working on a site where we’re using both ASP.NET AJAX and jQuery to get things done. This includes jQuery Validation for client-side validation functionality.

One of the things that comes with jQuery Validation is a $.validator.format method that replaces the {n} style parameters in a string with arguments - basically, a very lightweight String.format.

ASP.NET AJAX provides a really nice implementation of String.format that is pretty full-featured and understands format strings. For example, you can do String.format("{0:d}", mydate) to format a date in short date format. Snazzy stuff. Unfortunately, the jQuery Validation one isn't that robust... so I figured I'd marry the two worlds. Allow you to still use the$.validator.format` method, just like you always do, but under the covers it’ll pass through to ASP.NET AJAX to do the replacement/formatting.

Make sure you’ve got the ASP.NET AJAX, jQuery, and jQuery Validation script libraries registered in your page, then do this:

(function($) {
  if ($.validator) {
    $.validator.format = function(source, params) {
      if (arguments.length == 1)
        return function() {
          var args = $.makeArray(arguments);
          args.unshift(source);
          return $.validator.format.apply(this, args);
        };
      if (arguments.length > 2 && params.constructor != Array) {
        params = $.makeArray(arguments).slice(1);
      }
      if (params.constructor != Array) {
        params = [params];
      }
      var toEval = "String.localeFormat(source, __);";
      var paramEval = new Array();
      for (var i = 0; i < params.length; i++) {
        Array.add(paramEval, "params[" + i + "]");
      }
      toEval = toEval.replace(/__/, paramEval.join(","));
      return eval(toEval);
    };
  }
})(jQuery);

Basically we keep the currying bit that comes out of the box with $.validator.format but replace the bit that does the replacement work with the ASP.NET AJAX String.format. That should replace the existing $.validator.format method with a syntactically-and-functionally-equivalent, but slightly more robust, implementation.

UPDATE 9/30/09: The original version didn’t work if there was more than one parameter value you were validating against, like in a range where there’s a min and a max value. The new version takes that into account. The crazy eval junk at the end is because you can’t do String.localeFormat("...", Array) - the string formatting in ASP.NET AJAX doesn’t like it if you pass an array rather than an explicit list of arguments. The eval thing dynamically builds a valid statement like String.localeFormat(source, params[0], params[1]..., params[n]) and evaluates that so it works.

General Ramblings comments edit

The Killers - Day & Age

Jenn and I went to see The Killers last night at the Memorial Coliseum. It was awesome.

Now, the opening bands - there were two - not so great. First up was The Nervous Wreckords, which we were a little late for, and Jenn fairly accurately described as “15 minutes of pain.” After that came Mariachi El Bronx, which was sort of modern-ish mariachi music. I didn’t think they were horrible (Jenn did), but it wasn’t great, either.

The Killers, on the other hand, put on an awesome show. They sang all the hits from their albums as well as a few lesser known songs. Jenn and I did our little “stand up by your seat and bob your head” dances for part of it. The thing I noticed was howinto it their drummer gets. The guy’s a wildman - great on the drums and really fun to watch.

The crowd was great, really into the whole thing, and all-in-all it was a fantastic show. Totally worth the price of admission.

Jenn got her very first concert shirt ever at this show, too, so a groundbreaking experience was had by all.

aspnet, books, dotnet comments edit

Professional ASP.NET MVC 1.0 Professional ASP.NET MVC 1.0 is definitely one of those books you should have on your shelf if you work with ASP.NET MVC or are considering the move. It covers a good range of topics at a nice level of detail, which is surprising considering it’s not one of those four-inch-wide mammoths you’re probably familiar with.

The topics covered are:

  1. NerdDinner - A walkthrough of making a fully-functioning MVC app from start to finish
  2. Model-View-Controller and ASP.NET
  3. ASP.NET > ASP.NET MVC
  4. Routes and URLs
  5. Controllers
  6. Views
  7. AJAX
  8. Filters
  9. Securing Your Application
  10. Test Driven Development with ASP.NET MVC
  11. Testable Design Patterns
  12. Best of Both Worlds - Web Forms and MVC Together

Nearly half of the book is the first chapter, which is a really nice walkthrough of creating an MVC site from File -> New Project all the way to AJAX integration with maps. It covers more than just MVC including database creation and a few design pattern intros. While it stands alone (and is available for free online), it whets your appetite to see a little more detail on each aspect of the framework.

After the first chapter, the rest of the book is kind of like one of those movies you see that’s told through flashbacks - you’ve already seen some high-level end-to-end stuff and now it’s time to get the back story.

Chapters 2 and 3 are primarily about comparing and contrasting ASP.NET MVC with other things: other MVC frameworks (both .NET and non-.NET based) and ASP.NET web forms. They explain why you might (or might not) want to choose to use the ASP.NET MVC framework and talks a bit about why the MVC pattern is good. While interesting, some of these chapters came across a bit like a sales pitch, which got in the way of the message.

Chapter 4 covered a good deal on routing including how it works, how to extend it, and how it compares to URL rewriting. It helps when reading about routing if you have at least an entry-level understanding of regular expressions since they’re used a lot in routing and that experience is assumed. (If you don’t, I recommend Mastering Regular Expressions - it’s one of those mainstay books you should have on hand at all times.)

Chapter 5 on controllers walks you through the simplest case of creating a controller all the way through some fairly complex cases. The authors also touch a bit more on the “model” part of “Model-View-Controller” here with explanations of model binders (how you get data in and out of your model) as well as input validation (which they acknowledge is currently “a very simple, but limited” mechanism).

Chapter 6 discusses the role of the view in “Model-View-Controller” and explains ways to work with views, how to change the engine that renders the views, and when your controller should directly return data vs. use a view. They talk a little about what views should NOT do, but there was no discussion on what views SHOULD do. Folks new to MVC can find all sorts of gray areas where something might be able to happen in the view or the controller and in a somewhat opinionated framework it would have been nice to see what the authors (and/or the product team) thought were good candidates for logic that belongs in the view.

Chapter 7 talked about the pros and cons of using AJAX in an application and how to recognize and handle AJAX requests to your controller. It showed how to deal with a browser that has script disabled, which isn’t normally covered by these sorts of books and was nice to see. A lot of the chapter was HTML and script, as you’d expect in a discussion of AJAX, but isn’t really what you paid your admission to see. Regardless, it has a place in the book and was worth addressing.

Chapter 8, on filters, was a great explanation of what I think is one of the more deep topics in ASP.NET MVC. This chapter is a great reference on exactly how filters work and includes a great explanation of the order of execution for filters. Plus, there’s a whole subsection on filter naming conventions, which made me happy since naming conventions are usually entirely ignored in books like this.

Chapter 9 was more about the different types of attacks that someone can use on your site than anything. It seems like it was meant to put some level of fear into you, to scare you into wanting to secure your app. It’s a good discussion, but it felt a little misplaced and goes on for quite a while. If you’re not at all familiar with web site vulnerabilities, you’ll find this interesting; if you’ve been doing web work for a while, this will be old hat. Of course, they do end up explaining how to address some of these attacks and how MVC helps you, which is the part you’ll want to read.

One thing that they don’t mention when discussing cross-site request forgery is that the prevention MVC comes with makes the assumption that the user is browsing with a trusted, secure browser. With browser vulnerabilities constantly being discovered and patched, this isn’t always a safe assumption. Most CSRF prevention measures that come with web frameworks make that assumption and it feels like a huge miss when it’s not mentioned in the middle of a security chapter.

Chapters 10 and 11 talk about how to test an ASP.NET MVC app and how to use certain design patterns to make your app more testable. These are chapters that are missing from almost every book out there and seeing them included is like a breath of fresh air. Many of the patterns discussed here are applicable outside ASP.NET MVC as well, making the discussion doubly valuable.

The final chapter talks about all the ways you can work with both ASP.NET web forms and MVC together. Whether you have an existing web forms project you want to add MVC into or an MVC project you want to add some web forms into, this chapter walks you through step-by-step with screen shots and everything. It even talks about how to migrate an ASP.NET web forms app into an MVC app. Good stuff.

Through it all, the tone of the book is nice and light, fairly informal. It makes reading the book easy and keeps you interested. It would be nice if more books were written like this. There are also interesting asides from the product team, filling you in on their reasoning on why certain features behave the way they do and why certain design choices were made.

Also, any time a new design pattern is introduced or discussed, the authors take the time to explain some of the background on the pattern and why it’s good. You don’t see that in many books - usually the pattern is just used with no explanation as to why.

I’ve seen a couple of other reviews that mention how it’s not technical enough or doesn’t go into enough detail. I don’t think the goal of this book was to cover every edge case or offer solutions to every possible problem. I also don’t think it’s meant to be a reference that covers every method on every class available in the framework. It does a good job introducing the concepts of MVC and taking you down to a good intermediate level of development - more than “beginner” but less than “guru” - and (surprise!) it’s readable. I think that goes a long way.

This is a great book and I’d recommend it to anyone who has considered using ASP.NET MVC or is even just interested in learning more.