2

I want to pass validation result from server to client and show the message.

Without KnockOut.js it is very simple:

  1. Call the validation logic.
  2. Add validation result to ModelState.
  3. Every thing is hooked automatically. (Html.ValidationMessageFor)

What should I do when using KnockOut? What is the best practice here?

Do I need to return my ModelState with my ViewModel? If yes, how should i bind that to my ValidationMessage placeholder? Is there any plugin to use?

update 1:

  1. I know how to use client side validation libraries (Ko validation, jQuery validation) this is not my problem.

  2. I know how to return model state to client using Ajax.

  3. The problem is: What is the standard way of binding my errors list, to UI elements? Do I need to iterate my collection and bind them one by one? Is there any plugin that can bind my model state object to ui?

(just like when you are not using knockout and mvc takes care of it and binds them to your validation message place holders.)

Afshin Gh
  • 7,918
  • 2
  • 26
  • 43
  • yes we do have ko validation plugin for doing client side validation . you can check here if you are new to this http://jsfiddle.net/Kohan/JL26Z/17/ . cheers – super cool Mar 29 '15 at 00:43
  • 2
    This seems to apply to ASP.NET MVC + AJAX in general, not to Knockout specifically. You should see if the answers here apply: http://stackoverflow.com/questions/14005773/use-asp-net-mvc-validation-with-jquery-ajax – wrschneider Mar 29 '15 at 01:31
  • Thanks for the comments. Check my update. @wrschneider99 the link you provided was really helpful. – Afshin Gh Mar 29 '15 at 11:49

1 Answers1

0

I was facing the same problem. First I tried to implement this solution (https://datatellblog.wordpress.com/2015/06/26/client-and-server-validation-with-web-api-and-knockout/) but it didn't work.

My final solution is something like this:

  1. Convert the ModelState to a JS array:

    var modelState = null;
    modelState = @Html.Raw(Json.Encode(ViewData.ModelState.Where(k => k.Value.Errors.Any()).Select(t => new { Key = t.Key, Value = t.Value.Errors.Select(e => e.ErrorMessage) })));
    
    function getModelState() {
        return modelState;
    }
    
  2. After creating your view model, add the errors to it:

     self.addErrors = function (data, modelState) {
        $(data).each(function (dataIndex, dataItem) {
            var itemModelState = $(modelState).filter(function (filterIndex) { return stringStartsWith(modelState[filterIndex].Key, "Addresses[" + dataIndex + "]") });
    
            $(itemModelState).each(function (index, item) {
                var field = item.Key.split(".")[1];
                if (field === "NumberOfPositions") {
                    $(item.Value).each(function (valueIndex, valueItem) {
                        var name = item.Key.replace("[", "\\[").replace("]", "\\]").replace(".", "\\.") + "_Error";
                        $("#" + name).text(valueItem);
                        $("#" + name).removeClass("field-validation-valid").addClass("field-validation-error").show();
                    });
                }
            });
    
        });
    };
    

This works at least in my case. Hope it helps.

vgaltes
  • 1,150
  • 11
  • 18