Reputation: 3064
I’d like to know if someone could point me to a tutorial or give me an idea on how I should validate a model and display it's error messages by parsing a json response on the client. I am sure this must have been asked already but couldn't find the question.
0) User leaves empty required fields.
1) Hits submit button.
2) The post is handled and an ajax request is made instead.
3) The action method handles the post, tries to bind the model to the form collection. Detects errors as the required fields are empty.
4) Returns a json response, passing the object model it tried to bind.
5) I’d like to know how I could parse the json response so if I detect any errors, like a required field, I could make use of the generated data tags and display it's corresponding error message.
Action method:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult ValidateTrade(FormCollection data) {
Trade addedGroup = new Trade ();
try {
UpdateModel(addedGroup);
}
catch (Exception ex) {
} return json(addedGroup);
}
Javascript:
$.ajax({
url: link,
type: "POST",
data: form.serialize(),
success: function (data) {
//Parse response so if I detect errors, like required field, make use of the data tags already generated by MVC, show the corresponding error message.
},
error: function (jqXhr, textStatus, errorThrown) {
},
complete: function () {
}
});
Here’s my .cshtml:
@Html.LabelFor(model => model.Trade.Name)
@Html.TextBoxFor(model => model.Trade.Name)
@Html.ValidationMessageFor(model => model.Trade.Name)
Generated html:
<label for="Trade_Name">Name:</label>
<input class="input-validation-error" data-val="true" data-val-required="Name requiered." id="Trade_Name" name="Trade.Name" type="text" value="" />
<span class="field-validation-error" data-valmsg-for="Trade.Name" data-valmsg-replace="true">Name requiered.</span>
Upvotes: 1
Views: 1348
Reputation: 4841
MVC has a RemoteValidator markup that you can add additional properties to send along to the server to do your validation but this only produces a single validation message.
At one point in time I tried to do what you are suggesting, that being sending data to the server via AJAX, doing some validation, returning a list of errors, display some error messages. How I did it was to create a custom object that I would use for all of my JSON responses. You could extend the object to include an array or List of name/value pairs that would allow you to identify which fields has errors.
public class JSONResponseObject
{
private bool m_Success;
private string m_Redirect;
private string m_Message;
private object m_Data;
public bool Success
{
get { return m_Success; }
set { m_Success = value; }
}
public string Redirect
{
get { return m_Redirect; }
set { m_Redirect = value; }
}
public string Message
{
get { return m_Message; }
set { m_Message = value; }
}
public object Data
{
get { return m_Data; }
set { m_Data = value; }
}
public JSONResponseObject(bool Success)
{
m_Success = Success;
m_Redirect = null;
m_Message = null;
m_Data = null;
}
public JSONResponseObject(bool Success, object Data)
{
m_Success = Success;
m_Data = Data;
m_Redirect = null;
m_Message = null;
}
public JSONResponseObject(string Redirect)
{
m_Success = true;
m_Redirect = Redirect;
m_Message = null;
m_Data = null;
}
public JSONResponseObject(bool Success, string Message)
{
m_Success = Success;
m_Message = Message;
m_Redirect = null;
m_Data = null;
}
public JSONResponseObject(bool Success, string Message, object Data)
{
m_Success = Success;
m_Message = Message;
m_Data = Data;
m_Redirect = null;
}
}
This allows you to pass back a response to the client and check properties:
$.ajax({
type: "POST",
dataType: 'json',
url: "/woconnect/searchclients",
data: "q=" + escape($('#searchTerm').val()) + "&clienttypeid=" + escape($('input[name="clienttypeid"]:checked').val()),
success: function(response) {
if (response.Success) {
//do something with response.Data or response.Redirect
}
else
alert(response.Message);
$.unblockUI();
},
error: function() { $.unblockUI(); alert('An error occured and we were unable to load the clients'); }
});
The biggest issue is that you would have to write the validation inside of the controllers creating a dependency between the Controllers and the Views. I didn't like that. My next project used the built in client validation for MVC that used jQuery.Validate as rauland suggested. If setup propertly you could use one action to either return a full or partial view or even a JSON response by checking Request.IsAjaxRequest(). There is much work to be done and I found that the build in validation was the easiest thing to use.
Upvotes: 1
Reputation: 14219
Check out the jQuery Validate plugin. It allows you to set custom rules. You can assign the MVC-generated classes to work with the plugin's validation methods.
Upvotes: 1