Jquery – mvc3 – ajax form submit and server side validation

ajaxasp.net-ajaxasp.net-mvc-3jquery

I am sure this has been asked already, but I have been trying all the solutions given, but none of the given solution is solving my problem. Probably, I am not implementing it right.

I am using MVC3, razor, jQuery.

I have a new user registration form. Once registration is successful, I want to display the successful message (different on type of registration) in a dialog box.

If there is any error with ModelState, means ModelState.IsValid == false, I want to display errors in ValidationSummary.

View

function OnBegin () { alert('begin'); return $('form').validate().form(); }
function OnSuccess () { alert('success'); DisplaySucess()}
function OnFailure () { alert('failure'); }
function DisplaySuccess() {
    var typeOfRegistration = $('input:radio[name=RegistrationType]:checked').val();
    var msg;
    if (typeOfRegistration == 0) {
        msg = "You are successfully enrolled for Algebra classes.";
    }
    if (typeOfRegistration == 1) {
        msg = "You are registered with your email address. Someone would contact you with an email.";
    }
    if (typeOfRegistration == 2) {
        msg = "Thank you for filling up this form. One welcome packet would be delivered with in next 15 days";
    }

    msg = msg.replace(/\n/g, '<br />');
    $('#dialog').html(msg);
    $('#dialog').dialog('open');
}
@model Models.RegistrationModel
@using (Ajax.BeginForm("NewRegistration", "Account", new AjaxOptions() { OnBegin="OnBegin", OnSuccess = "OnSuccess", OnFailure = "OnFailure" }))
{ 
  @Html.ValidationSummary()
    <div>
    Register<br />
    @Html.RadioButton("RegistrationType ", "0", true) New Algebra class<br />
    @Html.RadioButton("RegistrationType ", "1") New user registration by email<br />
    @Html.RadioButton("RegistrationType ", "2") New user registration by mailing address<br/>
   ..some more types
</div>
<div>
    …here I display/hide controls based on Registration type selected.
        <div>
    @Html.LabelFor("UserName")
    @Html.TextBox("UserName")</div>
}

Controller

public ActionResult NewRegistration(RegistrationModel model)
{

         if (Request.IsAjaxRequest())
         {
             if (!ModelState.IsValid) { 
        //Ques: How do I display this in ValidationSummary. 
        return Json(new object[] { false, "Contains Email Address", ModelState.GetAllErrors() }); 
        }
             else { 
        if (UserNameIsTaken){ 
            //Ques: This does not show in ValidationSummary
            ModelState.AddModelError("_FORM", "This username is already taken. Please pick a different username.");
        }
       }
    }
         else if (!ModelState.IsValid) { return View(model); }

}

Model

public class RegistrationModel: IValidatableObject
{
[Required] //this gets displayed in ValidationSummary as Client-side validation
    public string UserName { get; set; }
    .. and all fields here
}
public IEnumerable<ValidationResult> Validate(ValidationContext context)
{
        if (!string.IsNullOrEmpty(UserName) && UserName.Contains(EmailAddress)) {
            yield return new ValidationResult("Username cannot contain email address", new[] { "UserName" });
        }
    }

Web.config has

UnobtrusiveJavaScriptEnabled="true" and ClientValidationEnabled="true"

.js files included are

script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript">

script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript">

script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript">

script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript">

What am I missing here? Any alternative?
Thanks in advance.

Best Answer

I Think that posting a form vía ajax you only get client side errors.

Server side errors, need to be returned via Json and then "inserted" in the markup vía jQuery or plain javascript.

Here you can see and download a fully working example.