views:

38

answers:

1

On my site I have simple form (by the way I'm using razor view engine):

<form method="post" action="Mail/SendMailMessage" id="mailForm">
   @Html.LabelFor(m => m.UserFirstAndSecondName)<br />
   @Html.TextBoxFor(m => m.UserFirstAndSecondName)<br />
   @Html.LabelFor(m => m.Email)<br />
   @Html.TextBoxFor(m => m.Email)<br />
   @Html.LabelFor(m => m.Content)<br />
   @Html.TextAreaFor(m => m.Content, new { cols = "40%", rows = "5%" })<br />
   <input type="submit" value="Send">
</form>

For this form to work, I'm using jquery.form.js plugin:

$(document).ready(function () {
    var options = {
        beforeSubmit: showRequest,  // pre-submit callback 
        success: showResponse  // post-submit callback 
    };
    $('#mailForm').ajaxForm(options);
});

When every field in the form is filled and I submit the form, everything is fine. Action on controller is invoked:

  [HttpPost]
  public JsonResult SendMailMessage(MailModel model)
  {
     //...
     return Json(new MailModel());
  }

and response is returned.

But if any field on the form is not filled, controller action is not invoked and I'm getting returned object which is undefined:

function showResponse(responseData, statusText, xhr, $form) {
    setUpMailForm(responseData); // undefined responseData
}

I suppose that this jQuery plugin is not sending empty form fields, and this is the problem when it comes to desetialization. How to make it to properly deserialize form fields to MailModel object, and invoke controller action, even when some of fields in the form are empty ?

How to make this work ?

PS. I want to do it using this jquery.form.js plugin, and not by explicit usage of $.post, and preparing data to send manually.

UPDATE

I was wrong. I have debugged jquery.plugin.js and every field name with its value (empty or not) is passed in the query string.

Below I put the model class:

public class MailModel
   {
      [Required(ErrorMessageResourceName = "FirstAndSecondNamesRequired")]
      [StringLength(150, MinimumLength = 1, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "UserFirstAndSecondNameLenghtError")]
      [Display(ResourceType = typeof(Resources), Name = "UserFirstAndSecondName")]
      public string UserFirstAndSecondName { get; set; }

      [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "EmailRequired")]
      [StringLength(100, MinimumLength = 1, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "EmailLenghtError")]
      [RegularExpression(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "EmailRegexError")]
      [Display(ResourceType = typeof(Resources), Name = "Email")]
      public string Email { get; set; }

      [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "ContentRequired")]
      [StringLength(1000, MinimumLength = 1, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "ContentLenghtError")]
      [Display(ResourceType = typeof(Resources), Name = "Content")]
      public string Content { get; set; }    
   }
A: 

The source of my problem is totally different than I expected. The problem is in attribute declaration in the model. Instead of:

[Required(ErrorMessageResourceName = "FirstAndSecondNamesRequired")]

I should put also the type of my resource:

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "FirstAndSecondNamesRequired")]

After fixing all attributes, everything has started to work as expected.

Jarek Waliszko