Upgrade to MVC 2 causes Unable to cast object of type ‘System.Web.UI.Triplet’ to type ‘System.Object[]’ relating to AntiForgeryToken

This has something to do with the way that MVC 1 and MVC 2 generate anti forgery tokens. It seems they might do things differently.

The solution is to clear your browser cookies.

James Crowley has a bit of information on it (first link in resources below!)

Resources

http://weblogs.asp.net/james_crowley/archive/2010/03/18/beware-upgrade-to-asp-net-mvc-2-0-with-care-if-you-use-antiforgerytoken.aspx

http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=199385

Getting the ResourceManager from a strongly typed resource file

I had a little bit of difficulty messing around getting the ResourceManager the class generated when making a resource file (resx). I wanted to get the value of something using a string and do it by accessing the ResourceManager property and calling the GetString() method myself. This is what i used to get the resource manager

Note you will need to make the resource file public if referencing as resource file in another assembly.

// Get the ResourceManager on the type
var resourceManager = (ResourceManager)ResourceType.GetProperty(
"ResourceManager",
    System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Static).GetValue(ResourceType, null);

// Get information on the getstring method
return resourceManager.GetString(_resourceKey, CultureInfo.CurrentCulture);

MVC 2 Strongly Typed Helper Method

Some quick information about generating a strongly types helper method in MVC 2: Covers:

  • An Expression as a method argument
  • Getting a valid name for the form field
  • Getting type information about the property specified on the view.

An Expression as a method argument

The Below gives a basic example of a strongly types helper method definition

public static MvcHtmlString MyHelperFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression)

{
}

Getting a valid name for the form field

Say we put this into the view

<%= Html.EnumDropDownFor(Model => Model.ContactDetails.Phone.Type) %>

We can generate a form field name like this:

var fullPropertyPath =
    htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(
        ExpressionHelper.GetExpressionText(expression)); 

This would result in fullPropertyPath being “ContactDetails.Phone.Type”. We can then use this as the name attribute on the form field we render.

Getting type information about the property specified on the view.

We can also get meta data about the type that the …Phone.Type property get’s/sets using ModelMetadata class’s FromLambdaExpression method like this:

var modelMetadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(
    expression, htmlHelper.ViewData);

var propertyType = modelMetadata.ModelType;

Custom Server and Client Side Required Validator in MVC 2 using jQuery.validate

This post has been moved here.

jQuery.validate – Setting default ignore rules

This post has been moved here.

jQuery.validate Custom Methods

We’ve been looking at validating a client side Url using the jQuery.validate (doc) plugin… and our rules were:

  • The field is required. You have to put the Url in.
  • Url must be an absolute path
  • Url must accept “http://localhost” style uri
  • Url must accept ip addresses (E.g. “http://10.0.0.12”)
  • We wanted to use a custom class called requiredUrl without adding custom rules to the validate method.
  • We want the code seperate from everything else, meaning we wanted to put the code in a different file, in other words, we didn’t want to polute the View (ASP.NET MVC) with rules nor alter the jquery.validate.js file directly.

The validate plugin allows you to add custom methods which allows the addition of a method that can be executed to validate a fields value… The method takes 3 parameters:

  1. The name of the method; in our case it is “requiredUrl”
  2. The function to do the validation… Returns true or false and takes 3 parameters: the value of the field, the element itself, and a params argument (not really sure why on this last one… haven’t looked it up as I’ve not had any need for it yet.)
  3. The third parameter is the message to show if the value is invalid.

Here is the requiredUrl method added to the validate plugin:

jQuery.validator.addMethod("requiredUrl", function(value, element, param) {
    var expression = /^(http:\/\/|https:\/\/)?((([\w-]+\.)+[\w-]+)|localhost)(\/[\w- .\/?%&=]*)?/i;
    return expression.test(value);
}, jQuery.validator.messages.url);

Notice the following:

  • The validation Regex requires something to be entered. Otherwise you would normally go as follows to also validate whether the field was required.

     return this.optional(element) || expression.test(value);

  • The last parameter is using the default Url validation message (jQuery.validator.messages.url)

With the following form field…

<input type=”text” class=”requiredUrl” />

…you could use the code as follows in your view:

$(document).ready(function() {
    $("#ServerForm").validate({
    rules: {
       webService: {
           requiredUrl: true
       }
    }

    });
});
  

The rule being added is for the form field with the Name of “webService” and the “requiredUrl” method is activated for that field, or in other words, this is the name of the method to execute when validation occurs for this field.

As already stated, I didn’t want to add this to the View so I wanted to just do the validation like this…

$(document).ready(function() {
    $("#ServerForm").validate(
);
});
  

To do that we need to register the css class “requiredUrl” with the validate plugin and tell it to use the “requiredUrl” method we registered earlier. I figure out you could do it like this:

jQuery.validator.classRuleSettings.requiredUrl = {requiredUrl: true};

The first “requiredUrl” refers to the css class to look for, and the second one refers to the name of the method that we added earlier.

Summary:

So the code would be:

jQuery.validator.addMethod("requiredUrl", function(value, element, param) {
    var expression = /^(http:\/\/|https:\/\/)?((([\w-]+\.)+[\w-]+)|localhost)(\/[\w- .\/?%&=]*)?/i;
    return expression.test(value);
}, jQuery.validator.messages.url);

jQuery.validator.classRuleSettings.requiredUrl = {requiredUrl: true};

Our form field would be:

<input type=”text” class=”requiredUrl” />

And our wireup to validate would be something like this:

$(document).ready(function() {
    $("#ServerForm").validate(
);
});