Holy Shitballs Batman! jQuery and Microsoft? Seriously??

Holy Shitballs Batman! jQuery and Microsoft? Seriously??

Wow.  This was only posted 6 hours ago and i feel like I'm the last to hear the news.

Partyin with Balsamiq Mockups

I'm havin alot of fun with Balsamiq Mockups today.  Here's my latest endeavor, I'm still learning so it's not great but it did help get over a hump with the project i'm working on.

Quick, Somebody Give Me A Credit Card Number

Sketchy Food Tracker

Via Tobin, i decided to check out Balsamiq Mockups.  Wow.  This tool is frickin awesome.

Food Tracker

As part of starting a cross fit program, I'm tracking(trying to anyway), I want to get better at tracking what I eat.  Since I suck at coming up sample project ideas, i figured that a food tracking app would be a good way to play around with ASP.NET MVC and MonoRail as a sample application.  I had come up with a sketch of the input form this weekend, but this morning the one I did with Balsamiq's online tool came out WAY better.  Check out the sketch:

The tools is surprisingly fun to use.  There are a ton of controls to pick from and anything you choose you can customize the text and data.

The grid in my sketch was a snap to set up, drag a grid, type in what you want for the header text, and a few rows beneath and you're done.

The designer also hasguidelines, so when you drag a control, similar to Visual Studio's WinForm designer, you get the vertical and horizontal guidelines that help you make stuff look good.

Anyway, if you have drawn diagrams of screen layouts before on paper, it's worth takin a look at.

 

 

 

 

 

 

 

More Html.ValidateTextBox

OK.  So I added some server side rule checking as a backup to the client side stuff.  In order to test this out, I had to turn off client side validation.  Right now it only returns a list of validation error messages, but I have some plans for that mechanism.  The controller method that handles the form post now looks like this:

 

[AcceptVerbs("POST")]
public ActionResult Edit(int id, Customer customer)
{
  customer.ID = id;
  if (!Model.IsValid(customer))
  {
    ViewData["errormessages"] = Model.GetErrorMessages(customer);
    return View(customer);
  }

  RepoFactory.Get().Save(customer);
  return this.RedirectToAction("index");
}
1
2
3
4
5
6
7
8
9
10
11
12
13

The only change i made to the Customer class so far was that I added a custom model binder attribute to the customer.  That attribute looks like this:

public class CustomerBinder : IModelBinder
{
  public object GetValue(ControllerContext controllerContext,
    string modelName,
    Type modelType,
    ModelStateDictionary modelState)
  {
    NameValueCollection form = controllerContext.HttpContext.Request.Form;
    return new Customer
    {
      FirstName = form["FirstName"],
      LastName = form["LastName"]
    };
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

And the customer class looks like this(i updated the validation attribute constructors to match the changes i made.

[ModelBinder(typeof(CustomerBinder))]
public class Customer : IModel
{
  public int ID { get; set; }

  [ValidateLength(3, 30,
    "First name must be between 3 and 30 characters in length.", true)]
  public string FirstName { get; set; }

  [ValidateMaxLength(30,
    "Last name is required and cannot exceed 30 characters.", true)]
  public string LastName { get; set; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

And the server side validation ends up rendering the following view(reminiscent of lammo validation summary in webforms):

Validation Exceptions

This one bugs me.  Scott Guthrie has a huge post on some new form stuff that comes with preview 5.  Great info there.  However, looking at the validation examples, you can see that the validation depends on on checking business rules and throwing exceptions if any of the rules fail; then in the controller you catch a general System.Exception, update some stuff for the view, and return the same view.  Why is this bad?

Well, an exception didn't really occur, it was made up because of failing a known business rule.  So basically, now you're using the throwing of exceptions to guide your workflow which makes your code hard to test and hard to follow.  I wouldn't  normally comment on something like this, but I saw another example of this by Stephen Walther here

People, please don't throw exceptions in non-exceptional situations.

Html.ValidateTextBox

OK.  So why is it, that most of the validation examples I see for ASP.NET MVC always include allowing the user to submit potentially invalid form fields to the server?? 

If your validation "framework" requires you to submit a form to the server prior to being validated, then your framework sucks.  Period.  Definitely have the server side validation.  Server side validation exists to double check that you didn't fuck up and miss something on the front end with client side validation.

I implemented a VERY lame outline of something that I would expect from a framework.  Simple attributes are applied to properties that are bound in the view.  My example expects that you are using jQuery.  This is not good. 

A validation framework that works on the client, should not care about it's implementation but should have a default implementation. So it shouldn't care if you're a jQuery fan, or prototype fan, or not a fan of javascript at all;it should establish some common methods that you are free to implement yourself.

If Microsoft were to implement a good validation framework, here's what I would require from them.  Zero installation.  Requiring that you install the Enterprise Library to get any sort of validation bennies is absurd, please stop doing this.

The framework would default to Microsoft's home grown javascript library, but with VERY little effort, could be switched out with prototype, jQuery, or any javascript framework you want.

Here's my scratch project trying to come up with a better validation framework.  It's tied to jQuery, which I don't like.  It looks for any element(i've only concentrated on an input element of type="text", so it doesn't do much) that contains a 'validate' attribute.  then inspects other css classes that have been tacked on that indicate some sort of validation to perform on the element.  I'm thinking of also sticking other attributes on the element when it's generated, not XHtml-ish, but oh well.

It's based on attributes that implement my IModelValidator interface which looks like this:

public interface IModelValidator
{
  bool Validate(object value);
}
1
2
3
4

The ValidateRequiredAttribute tests to make sure a value exists and looks like this:

public class ValidateRequiredAttribute : System.Attribute, IModelValidator
{
  public bool Validate(object value)
  {
    if (value == null) return false;
    if (System.Convert.ToString(value).Length == 0) return false;
    return true;
  }
}
1
2
3
4
5
6
7
8
9

ValidateMaxlengthAttribute checks to make sure the length of a value does not exceed a max value:

public class ValidateMaxLengthAttribute : System.Attribute, IModelValidator
{
  private int _maxLength = 0;
  public int MaxLength
  {
    get
    {
      return _maxLength;
    }
  }
  public ValidateMaxLengthAttribute(int maxLength)
  {
    _maxLength = maxLength;
  }
  public bool Validate(object value)
  {
    if (value == null) return false;
    return System.Convert.ToString(value).Length
 
Author: , 0000-00-00