2

I have a partialview that has a viewmodel containing a form with only email and name input. I post this data with jquery ajax to my controller to do some validation. My controller is a PartialViewResult method, see:

    [HttpPost]
    public PartialViewResult InviteUser(InviteEmailViewModel item)
    {
        return PartialView("_InvitedUsers", item);
    }

My jquery adds the result of this method to the DOM, since ive uses hiddenfor i get inputs like:

<input data-val="true" data-val-required="Name is required." id="Name" name="Name" type="hidden" value="test">
<input data-val="true" data-val-regex="Invalid Email Address" data-val-regex-pattern="^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$" data-val-required="Email Address is required." id="Email" name="Email" type="hidden" value="test@test.test">

The problem with this is that my ViewModel contains a List but after posting the form with the added partialviews the List is Null. Ive tested with hardcoded input fields like:

<input data-val="true" data-val-required="Name is required." id="Name" name="InviteEmailViewModel[0].Name" type="hidden" value="test">

and that does seem to work. How do i make MVC generate hidden fields like in my hardcoded example?

blaataap
  • 219
  • 2
  • 12

1 Answers1

3

To answer your Q:

To include hidden fields in the post, these need to 'survive' the create-in-controller-survive-the-post, if the field isn't in the form, then it won't be posted back to the controller, regardless if it's been created before in the controller.

Add the hidden field anywhere within the form so that it's posted back. So when it's created it'll have a container and will therefor be present on post.

IE:

@Html.HiddenFor(m => m.myHiddenField)
@Html.TextBoxFor(m => m.displayedField, new { @class = "NotHidden" })

What it could be:

If I'm understanding correctly you've got a ViewModel with a List, which is the model of the partial, which you want to add dynamically to your VM and bind on post.

To add items to a list dynamically, without them going null, you'll need to use BeginCollectionItem, which handles the hidden GUID issue for you.

I had similar issues and asked two questions which have solutions here and here, the latter is a problem with accessing a property two models down, but shows more complete code.

The issues that you've got are with the GUID. It doesn't go back through the post without help.

What you need is a prefix in the name/id so that the object can be properly assigned to its model when you post.

BeginCollectionItem will sort this out for you - which you can get 'stock' via typing Install-Package BeginCollectionItem in Package Manager Console in Visual Studio, check out this guide - here or you can download the file/whole thing and add it to your project manually by going to GitHub here

name="viewmodel[f7d8d024-5bb6-451d-87e3-fd3e3b8c1bba].listOfObjects[d5c08a43-f65e-46d1-b224-148225599edc].objectProperty" is what you need on the dynamically created model properties so that they all bind on post back.

Good luck. =)

Community
  • 1
  • 1
PurpleSmurph
  • 2,055
  • 3
  • 32
  • 52
  • Thank you, BeginCollectionItem was the trick. I installed it and actually didnt have to modify anything except adding the "@using (Html.BeginCollectionItem("InviteEmailAddresses"))" to my partial view. – blaataap Sep 21 '15 at 07:16
  • Excellent, glad it helped. – PurpleSmurph Sep 21 '15 at 07:34