views:

164

answers:

2

Here is the JS:

$('#createReview').click(function () {
    CKEDITOR.instances['ReviewText'].updateElement();
    $.ajax({
        type: 'POST',
        cache: false,
        url: '/Review/Create',
        data: $('#reviewForm').serialize(),
        dataType: 'html',
        success: function (response) {
            $('#bookReview').html(response);
        }
    });
    return false;
});

'createReview' is

The action:

    [HttpPost, ExportModelState]
    public ActionResult Create(Review review)
    {
        if (ModelState.IsValid)
        {
            if (review.Create())
                return PartialView("EditReview", review);
        }

        return RedirectToAction("Edit");
    }

When the form is posted, the review is created, but only the string property is binding--in this case the ReviewText. None of the integer properties are binding at all.

The strangest part is, when I run it in debug mode, none of the properties successfully bind, not even the ReviewText. When I inspect the Review object everything is either null or default.

I went back and forth between regular mode and debug, and it does the same thing every time.

I'm at a loss.

Edit:

Here is the full output of the Serialize() call, that won't fit in a comment:

score=0&score=0&score=0&score=0&score=0&score=0&score=0&score=0&score=0&score=0&Book.Review.Rating=0&Rating=0&ReviewID=0&ParentBookID=1&reviewText=%3Cp%3E%0A%09I%26%2339%3Bm+an+idiot%3C%2Fp%3E%0A%3Cbr+%2F%3E%0A%3Cdiv+firebugversion%3D%221.5.4%22+id%3D%22_firebugConsole%22+style%3D%22display%3A+none%3B%22%3E%0A%09%26nbsp%3B%3C%2Fdiv%3E%0A%3Cbr+%2F%3E%0A&DateCreated=1%2F1%2F0001+12%3A00%3A00+AM

Note that "score" is nowhere to be found in my entire database, and all that junk about Firebug mixed in there.

Edit #2:

OK, so all those "score" inputs are coming from the jQuery Raty plugin, which was promptly un-plugin-ed.

Firebug is lousing up the text coming from the CKEditor instance, which is not even getting updated prior to form submission.

This client-side stuff sure is a blast!

Grrr...

+2  A: 

You haven't shown how your model classes look like neither what input elements does your form consists of. Trying to reproduce the problem here's a working example I've created. It should be pretty close to your scenario:

Model:

public class Review
{
    public int ReviewID { get; set; }
    public int ParentBookID { get; set; }
    public int Rating { get; set; }
    public string ReviewText { get; set; }
    public int[] Scores { get; set; }
}

Controller:

public class ReviewController : Controller
{
    public ActionResult Edit()
    {
        var model = new Review
        {
            ReviewID = 1,
            Rating = 5,
            Scores = new[] { 1, 2, 3 }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Create(Review review)
    {
        if (ModelState.IsValid)
        {
            if (review.Create())
            {
                return PartialView("EditReview", review);
            }
        }

        // Notice that redirecting in an AJAX invoked action will simply
        // send an HTTP redirect to the Edit action and redisplay the whole page
        // which is probably not what you are looking for. Maybe it would be better
        // to return a partial here.
        return RedirectToAction("Edit");        
    }
}

View:

<% using (Html.BeginForm("Create", "Review", FormMethod.Post, new { id = "reviewForm" })) { %>
    <div>
        <%: Html.LabelFor(x => x.ReviewID)%>
        <%: Html.TextBoxFor(x => x.ReviewID)%>  
    </div>
    <div>
        <%: Html.HiddenFor(x => x.ParentBookID)%>  
    </div>
    <div>
        <%: Html.LabelFor(x => x.Rating)%>
        <%: Html.TextBoxFor(x => x.Rating)%>  
    </div>
    <div>
        <%: Html.LabelFor(x => x.ReviewText)%>
        <%: Html.TextAreaFor(x => x.ReviewText)%>  
    </div>
    <%: Html.EditorFor(x => x.Scores)%>

    <input type="submit" value="Review" />
<% } %>

<div id="bookReview"></div>

Script:

<script type="text/javascript" src="<%: Url.Content("~/scripts/jquery-1.4.1.min.js") %>"></script>
<script type="text/javascript">
$(function () {
    $('#reviewForm').submit(function () {
        $.ajax({
            type: this.method,
            url: this.action,
            data: $(this).serialize(),
            dataType: 'html',
            success: function (response) {
                $('#bookReview').html(response);
            }
        });
        return false;
    });
});
</script>

You could also take a look at the excellent jquery form plugin so that your script simplifies to this:

$(function () {
    $('#reviewForm').ajaxForm(function(response) {
        $('#bookReview').html(response);
    });
});
Darin Dimitrov
Thanks Darin. I wish there *were* an array named Score--the truth is, I'm sending back a whole bunch of garbage with that Serialize() call, and I don't know where it's coming from. I see some trash about Firebug in there, too. I'm wondering if it has to do with the combination of CKEditor, Firebug, and jQuery. The RedirectToAction comes from me trying to implement the P-R-G pattern. That form plugin is GTG then? I was wondering about that.
PolishedTurd
A: 

I'm going to go ahead and chalk this one up to a bad combination of plugins: Firebug, CKEditor and Raty.

PolishedTurd