Showing posts with label ASP.NET MVC. Show all posts
Showing posts with label ASP.NET MVC. Show all posts

Tuesday, December 6, 2011

Validating a single field using MVC 3 unobtrusive validation

I recently ran into a problem using the jQuery autocomplete control with ASP.NET MVC3 unobtrusive validation. Everything worked correctly except for the scenario where the user clicked an option in the drop-down using the mouse. When this happened, the validation event was not fired against the item the user clicked because no keyboard action had taken place. The solution was to fire the validation event in the select event of the autocomplete control.

To validate the single field using MVC 3 programatically, I used the following JavaScript:
$("form").validate().element($(elementToValidate)); 

Thursday, November 24, 2011

Protecting against CSRF in MVC 3

It is important to protect your customers and other users of your website against CSRF attacks. To do this in ASP.NET MVC 3, you would normally use the ValidateAntiForgeryTokenAttribute. The test below will ensure that all appropriate actions on all controllers have this protection.
[TestMethod]
public void All_post_actions_validate_anti_forgery_tokens()
{
    var modelController = typeof(MyController);  //this can be any one of your controllers in this particular area
    var allControllers = modelController.Assembly.GetTypes().Where(t => t.Namespace == modelController.Namespace && t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase));
    foreach (var controller in allControllers)
    {
        AssertControllerValidatesAntiForgeryToken(controller);
    }
}

static void AssertControllerValidatesAntiForgeryToken(Type controller)
{
    Console.WriteLine("Checking " + controller.Name);
    var violations = (
        from method in controller.GetMethods()
        let attributes = method.GetCustomAttributes(true)
        let parameters = method.GetParameters()
        let isProperty = !method.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase) && !method.Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase)
        let isPostMethod = parameters.Length != 0 && (!attributes.Any(a => a is ActionMethodSelectorAttribute) || attributes.Any(a => a is HttpPostAttribute))
        let noAntiForgeryToken = !attributes.Any(a => a is ValidateAntiForgeryTokenAttribute)
        let excludedMethods = typeof(ControllerBase).GetMethods().Select(m => m.Name)
        let isExcludedMethod = excludedMethods.Contains(method.Name)
        where isProperty && isPostMethod && noAntiForgeryToken && !isExcludedMethod
        select method.Name).ToArray();

    foreach (var violation in violations)
        Console.WriteLine("Failed: {0}/{1}", controller.Name, violation);

    Assert.AreEqual(0, violations.Count());
}