4
votes

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.

2

2 Answers

4
votes

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.

0
votes

Write the following references in the master file (layout.cshtml):

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

In web.config, set 'false' to 'true':

<appSettings>
<!--<add key="ClientValidationEnabled" value="true"/> (enable this when client-side validation is needed) -->
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

In the model:

public class ValidUserNameAttribue : ValidationAttribute
{
  public override bool IsValid(object value)
  {
    return (value != null && value.ToString() == "Bob");
  }
}

public class Customer
{
  [ValidUserNameAttribue(ErrorMessage = "please type user name as Bob")] /* for server side validation*/
  public string UserName { get; set; }
}

In the Controller:

public class HomeController : Controller
{
  [HttpGet]
  public ActionResult Index()
  {
    return View(new ValidationModel());
  }

  [HttpPost]
  public ActionResult Form(ValidationModel validationModel)
  {
    return PartialView(!ModelState.IsValid ? "Partial/_Form" : "Partial/_Success", validationModel);
  }
}

Index View:

@model MVC3_Ajax_Form_jQuery_Validation.Models.ValidationModel

@{
    ViewBag.Title = "ajax form submit and server side validation";
}


<div id="FormContainer">
    @Html.Partial("Partial/_Form")
</div>

Form View:

@model MVC3_Ajax_Form_jQuery_Validation.Models.ValidationModel

@using (Ajax.BeginForm("Form", new AjaxOptions() { UpdateTargetId = "FormContainer" , OnSuccess = "$.validator.unobtrusive.parse('form');" }))
{

    <p>
        @Html.ValidationMessageFor(m => m.UserName) // (Error Message)
    </p>

    <p>
        @Html.LabelFor(m => m.UserName):
        @Html.EditorFor(m => m.UserName)
    </p>

    <input type="submit" value="Submit" />
}

Success View:

@model MVC3_Ajax_Form_jQuery_Validation.Models.ValidationModel

User name '@Model.UserName' is valid :)

Check out this link for server-side validation in an AJAX form: http://www.codeproject.com/Articles/460893/Unobtrusive-AJAX-Form-Validation-in-ASP-NET-MVC