Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Knockoutjs And Server Side Validation in .NET MVC2

I'm using MVC2.

Whats the recommended way of server side validation of forms when using knockout?

Currently, most of my forms are in partial views, which have a C# ViewModel with Validation Attributes. Something like this:

public class SomeThingViewModel
{
    [Required]
    public string Name { get; set; }

    [Required]
    public int Number{ get; set; }
}

So when the form gets submitted to the server, I get all the model errors and I can return the form with errors, which are displayed with something like: <%: Html.ValidationMessageFor(m => m.Name)%>. This is then reloaded into the element that holds the form on the main page so that the user can see the errors. This would kill any bindings I had with the form in knockout I would assume.

I'm not really sure how to go about this using knockout.

like image 241
Jason Avatar asked Jan 31 '12 20:01

Jason


1 Answers

This can be tricky, but done right works like a breeze.

First, synchronize your viewmodels. What you have client-side in knockout you pass exactly to the server. Second, don't do server-side HTML with knockout. Create fields that are set server-side and read client-side that indicate the validity of each data field in your ViewModel.

So if your Model has a field Name, your ViewModel has Name and Name_ValidationResult, which is an enum that indicates whether or not the Name field is valid and why it's not. If your server-side validation fails, set your validation result fields and pass the whole server-side ViewModel back to the client to be re-set as the client-side ViewModel after the request completes. Basically, you a re-creating the ViewState portion of ASP.NET, but doing so in a format that will work with Knockout.js

On the client-side, you have error messages that only show based on values of the ValidationResult fields. So you might have a canned error message that states "The Name field must be set" that is only displayed if Name_ValidationResult has the value "Empty" (for example).

Basically, you actually use the MVVM pattern with a minor tweak to account for having to round-trip to the server.

So you are suggesting that I add ValidationResult fields in my C# ViewModel for each property. Then set the ValidationResult Properties in my controller when I check for the Model's validity. Then pass back the viewmodel as JSON? so that I can update my knockout viewmodel. This will require me to manually validate to some extent right? Or can I leverage the ModelState errors that I will end up with? – Blankasaurus

Bottom line is yes to all your questions.

In truth, I missed the fact that you were using DataAnnotations for your validation, or I'd have mentioned it. You should be able to leverage ModelState errors to set your validation results that you pass back to your knockout page.

The problem is that you're using two fundamentally incompatible technologies and hoping they'll play nice together, and I don't think that's going to work out the way you hope. Something is going to have to give, and I suggest that the best point for that is server-side. Drink the knockout cool-aid and fix what you have to server-side.

like image 80
Randolpho Avatar answered Nov 13 '22 04:11

Randolpho