Question

I have a form which I like to be submitted with jQuery Ajax. My Ajax function is something like following code :

   $('#submitForm').click(function (e) {
        e.preventDefault();

        $.ajax({
            url: '/Letter/Create',
            type: 'post',
            data: {
                letterViewModel: $('#letterForm').serialize(),
                relatedLetters: JSON.stringify(relatedLetterList)
            },
            success: function (result) {
                alert('success ' + result);
            },
            error: function () {
                alert('error');
            }
        });
    });

And my Action is :

    [HttpPost]
    public virtual ActionResult Create(LetterViewModel letterViewModel, string relatedLetters)
    {
        .
        .
        .
    }

Here is the problem, first parameter of Action method is always null. I don't know what is the problem, any advice will be helpful.

Update: Data after serialization:

__RequestVerificationToken=goQJDz5BCMx9NCJAZ3yuMA2E-WRgL9pJvavkLhF27epxkz3bRO_t-ADNhGHslHjXifLuxmFQcJBuOkMBSqMlFjkfKjVK-hGgY-nvRmp_2i81&CategoryId=1&LetterTitle=456&Exporter=465&ArchivePlace=456&OrgLetterNumber=456&OrgLetterDate_fa=1392%2F02%2F02&IndicatorNumber=456456&IndicatorDate_fa=1392%2F02%2F09&RelatedLetterId=3

And My LetterViewModel:

public class LetterViewModel
{
    public Int32 LetterId { get; set; }

    public Int32 RelatedLetterId { get; set; }

    public Int32 ServiceUserId { get; set; }

    public Int32 CategoryId { get; set; }

    public String LetterTitle { get; set; }

    public DateTime OrgLetterDate { get; set; }

    public String OrgLetterNumber { get; set; }

    public DateTime IndicatorDate { get; set; }

    public String IndicatorNumber { get; set; }

    public String ArchivePlace { get; set; }

    public Boolean HasAppendix { get; set; }

    public Int32 PageCount { get; set; }

    public String Exporter { get; set; }

    public String OrgLetterDate_fa { get; set; }

    public String IndicatorDate_fa { get; set; }

    public List<CategoryViewModel> CategoryViewModels { get; set; }

    public List<VwLetterViewModel> RelatedLetters { get; set; }
}
Was it helpful?

Solution

The problem is here:

data: {
    letterViewModel: $('#letterForm').serialize(),
    relatedLetters: JSON.stringify(relatedLetterList)
},

The .serialize() method already performs an application/x-www-form-urlencoded serialization of the data and jQuery data does another one so you end up with invalid request.

You could include a hidden field in your #letterForm and set its value immediately before posting the form:

$('#letterForm').submit(function (e) {
    e.preventDefault();

    // set the value of the hidden field to the corresponding JSON
    $('#relatedLetters').val(JSON.stringify(relatedLetterList));

    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(),
        success: function (result) {
            alert('success ' + result);
        },
        error: function () {
            alert('error');
        }
    });
});

Also notice that I have used the .submit event of the form instead of the .click event of a submit button. The reason for this is that a form can be submitted in other ways, not only by clicking on the submit button with a mouse. Think for example the user pressing the Enter key while inside some iof the form fields. This will submit the form and if you subscribe to the click event of your submit button your AJAX request will never fire.

OTHER TIPS

I've had this problem before with Controllers and POST data as it differs from GET when sending variables, you need to send your data in JSON format, such as:

$('#submitForm').click(function (e) {
    e.preventDefault();

    var data = {
        letterViewModel: $('#letterForm').serialize(),
        relatedLetters: relatedLetterList // don't need to stringify this as it's done in JSON.stringify below
    }

    var obj = JSON.stringify(data);

    $.ajax({
        url: '/Letter/Create',
        type: 'post',
        data: obj,
        success: function (result) {
            alert('success ' + result);
        },
        error: function () {
            alert('error');
        }
    });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top