3

I have tried to follow some good posts here to get this to work but every time i click the ajax postback the break point in my controller shows a model with null values. This page displays model values for viewing only, but I have tried putting them in their own form and also wrapping them in the ajax form and nothing seems to work.

@model VendorProfileIntranet.Models.VendorProfile

$(function () {
$("form").submit(function () {
    if ($(this).valid()) {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                $("#message").html(result);
            }
        });
    }
    return false;
});

});

    @using (Ajax.BeginForm("SelectVendor", "Home", new AjaxOptions { HttpMethod="post", InsertionMode=InsertionMode.Replace, UpdateTargetId="message" }))
{
    <div style="float:right; width:500px">
        <div id="message"></div>
        <input id="btnSubmit" type="submit" value="Select Vendor" />
    </div>

The view is really long (just displays model values for viewing) abbreviated here.

<div id="viewform">
    <div id="viewform-contact" style="float:left;">
    <fieldset>
        <legend>Contact Information</legend>
        @Html.HiddenFor(model => model.ProfileID)
        <div class="view-field">
            @Html.LabelFor(model => model.Name)
            @Html.DisplayFor(model => model.Name)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Email)
            @Html.DisplayFor(model => model.Email)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Phone)
            @Html.DisplayFor(model => model.Phone)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Website)
            @Html.DisplayFor(model => model.Website)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.CompanyName)
            @Html.DisplayFor(model => model.CompanyName)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Address1)
            @Html.DisplayFor(model => model.Address1)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Address2)&nbsp;
            @Html.DisplayFor(model => model.Address2)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.City)
            @Html.DisplayFor(model => model.City)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.State)
            @Html.DisplayFor(model => model.State)
        </div>
        <br />
        <div class="view-field">
            @Html.LabelFor(model => model.Zip)
            @Html.DisplayFor(model => model.Zip)
        </div>
        <br />
        <div class="view-fieldwide">
            @Html.LabelFor(model => model.VendorNotes)
        </div>
        <br />
        <div class="view-fieldwide">
            @Html.DisplayFor(model => model.VendorNotes)
        </div>
        <br /><br />
        </fieldset>
    </div>
}

Controller. I have tried the above in one or two forms. With the above code the model contains all empty values except the ProfileID which is stuffed in a hidden input field. I think passing the model should work without having to create a hidden field for every model value?

[HttpPost]
        public ActionResult SelectVendor(VendorProfile pageModel)
    {
        // handle selected vendor
            _DAL.SelectVendor(pageModel.ProfileID);
            return Content("This Vendor has been selected", "text/html");
    }

ANSWER

The model values are not binded due to the use of DisplayFor

Community
  • 1
  • 1
SQLGrinder
  • 373
  • 4
  • 6
  • 20
  • 1
    You seem to be lacking input elements in your form' – Forty-Two Mar 15 '13 at 18:52
  • @Forty-Two There is a button that when clicked should pass back the model that is the other form (not shown) and insert a record in db and update message in div tag that it was successful. I tried putting all the form elements in the ajax form and that didn't work either, so one form or two forms didn't work. I know I am missing something. – SQLGrinder Mar 15 '13 at 20:43
  • Can you post the rest of your view? – Mathew Thompson Mar 15 '13 at 20:50
  • @mattytommo See above. I suspect something wrong with the way I have the one or two forms setup. Like I said I have tried this a couple ways already. THx – SQLGrinder Mar 15 '13 at 21:03

1 Answers1

7

As noted in the comments, you're actually expecting to see items in your Model that you have put in your form using DisplayFor. DisplayFor fields will not post, they are simply for display. In order to post those values back, you'd need a HiddenFor for each of the field that you want to post, in order for model binding to work it's magic.

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
  • I have tried one form and two forms. I actually tried exactly what you suggested above (and tried it again) and my model is still null when the the controller breakpoint is hit. :( – SQLGrinder Mar 15 '13 at 21:18
  • @Vic What is in Request.Form when you debug? – Mathew Thompson Mar 15 '13 at 21:29
  • Interesting... It only contains 7 keys, it has the ProfileID (from hidden input) and of the remaining 2 dozen items on the page from the model it only contains 6 checkbox values that are all false (even though one on the page shows true. This is going with everything stuffed into one form and not modifying the jquery code. – SQLGrinder Mar 15 '13 at 21:41
  • @Vic Request.Form won't contain the other values that you have `DisplayFor` for, you'll have to have `HiddenFor`s for each of those in order to model bind. What happens if you submit the form without jquery? – Mathew Thompson Mar 15 '13 at 21:50
  • Ah, light bulb moment. Thx. It works the same even without the jquery. I am looking into a variation of using TextBoxFor with readonly that would display all the fields and allow model binding (instead of using both DisplayFor and HiddenFor) – SQLGrinder Mar 15 '13 at 22:17
  • @Vic No problems, glad I could help! You could create your own overload of the `DisplayFor` method that actually rendered the hidden field too. – Mathew Thompson Mar 15 '13 at 22:22