MVC validation lost in Knockoutjs post

2020-07-22 17:32发布

I'm using MVC4 and knockout. I have a form on a page that is strongly typed to a viewmodel. In that viewmodel I have some validation defined, for instance:

[Required(ErrorMessage = "Title is required")]
public string Title { get; set; }

If I do a standard post to the form without the required field filled, my action sees that the model is not valid and returns to the view, and a main validation message is displayed because I have @Html.ValidationSummary in my form. The individual field is also marked as invalid (with a message) because I have @Html.ValidationMessageFor associated with the field

So then I added knockout and instead of just posting the form I now call ko.utils.postJson($("form")[0], self);. Now most everything works, if I post the form with the required field not populated, my action detects that the model is invalid and returns to the view, except now the individual validation messages don't show up.

The filled in fields before the post are also lost. I tried to remedy this by reading in the mvc viewmodel and setting the variables to those values like so.

var model = @Html.Raw(Json.Encode(Model));

And then in my knockout viewmodel setting that value

self.Title = ko.observable(model.Title);

But then when I entered '1', it would fill in the field with '"1"' when the failed post returned.

This is not too complex of a form, so I do not want to introduce some new validation layer if it can be avoided. I don't mind there being a post for the validation.

Thanks, Dan

2条回答
我只想做你的唯一
2楼-- · 2020-07-22 17:39

What I question. I was exploring this topic for the last 2 weeks. (Look up my questions from last few days if you want to). I came to conclusion that data annotations and fluent validation doesn't work on client side that is using knockout unfortunately. Hence you have to introduce another layer of validation.

Good news is that its well tested and as standard as knockout is.

You have mainly three options:

I was expecting community to tend to suggest using jQuery one, but apparently mainstream validation for knockout is the first choice there. It behaves very similarly to data annotations, but is obviously done on knockout view model fields.

Hope this helps (don't shoot the messenger :) )

查看更多
虎瘦雄心在
3楼-- · 2020-07-22 18:00

Im looking into a similar situation at the moment, doing a hybrid web api / MVC project. Where only the details pages recieve any data from the controller. Rest handled by knockout. Options i can see sofar(some tested, some qualified guess):

  1. Duplicate your validationlogic through the ViewModel and the Knockout Clientside ViewModel(using preferrably Knockout-Validation as suggested above). Instinctively feels funky to me.
  2. Set up your form as a regular mvc strongly typed form using jquery unobtrusive validation.

1,2: Handle events(when form is deemed valid) using knockout / jquery. If async post contains errors return and present them (some css / less / sass frameworks like bootstrap have ready alertbox classes for example to put the error in).

  1. Check out MVC Control Toolkits clientblock. I plan to test this option myself, looks promising.
  2. Try KnockoutMvc, that also seems to be able to help with this.
查看更多
登录 后发表回答