Search code examples
c#jqueryasp.net-corerazor

Post handler doesn't parse serialized form


I've read a lot of tutorials across the internet about handling form values which are passed to POST handler via AJAX call. All of them assume, that serialized form is parsed by Handler method without any problems. Unfortunately, in my case something went wrong, and I can't get correct values from my serialized form.

Following images present post handler, html for form and ajax call.

I would like to mention few additional things. First of all, according to tutorials I'd like to encapsulate form fields in separate class, in this case ResponseModel. Anyway, I was not able to retrieve any value from the serialized form passed as an ajax argument. It looks like form is serialized, cause I can see correct value when I log serializedForm variable.

When I change argument type for response argument from ResponseModel to simple string then string is passed to handler, and I can retrieve this value as a string, but not as an object (that's what I expect). Just can't understand why it works without any issues in all theses tutorials, and I can't implement this in my own project.

So my question - Why post handler can't parse serialized form into expected object?

Many thanks

ResponseModel class:

public class ResponseModel
{
    public string Status { get; set; }
    [Required]
    public string Description { get; set; }
}

Property for the input fields:

    [BindProperty]
    public ResponseModel EditedTicket { get; set; }

Post handler:

    public async Task<JsonResult> OnPostUpdateTicket(ResponseModel response, int ticketId)
    {
        if (!ModelState.IsValid)
        {
            Debug.WriteLine("Model invalid");
        }

        return new JsonResult(new { success = true, message = "Ticket has been assigned!", errormessage = "Something went wrong, try again later" });
    }

Form HTML:

            <form id="edit_ticket" method="post">
                <label asp-for="EditedTicket.Description">Description</label>
                <input asp-for="EditedTicket.Description" name="EditedTicket.Description" class="form-control" />
                <input id="update-ticket" type="submit" class="btn btn-success text-white" value="Update" />
            </form>

Ajax call:

    //Button submit
    updateTicketBtn.click(function (e) {
        e.preventDefault();
        var serializedForm = $('#edit_ticket').serialize();
        console.log('This is serialized form: ', serializedForm);

        $.ajax({
            type: "POST",
            url: "/QAView/ProjectDetails?handler=UpdateTicket",
            beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            dateType: 'application/json',
            contentType: 'application/x-www-form-urlencoded; charset=UTF-8',   
            data: { 'response': serializedForm, 'ticketId': ticketId }
        }).done(function (response) {
            console.log('Done!');
        })
    });

Solution

  • You can just append your extra info (not included in <form>) like this:

    var serializedForm = $('#edit_ticket').serialize();
    serializedForm += "&ticketId=" + ticketId;
    //...
    //the posted data is changed to something like this:
    data: serializedForm
    

    For the model ResponseModel, because you bind it via the property EditedTicket you don't need it in the handler, like this:

    public async Task<JsonResult> OnPostUpdateTicket(int ticketId){
         //access the property EditedTicket here
         //...
    }
    

    In case you want to bind it via an argument, you need a prefix setting like this:

    public async Task<JsonResult> OnPostUpdateTicket([Bind(Prefix=nameof(EditedTicket))] ResponseModel response,
                                                     int ticketId){
        //...
    }