0

Is there any way to pass list of models, each generated by HTML Partial View to a Controller Action in ASP.Net MVC 5?

So I have a View (with a model called WordModel) where I call a HTML partial View (with a model called MeaningModel) multiple times in a form like the following:

@using (Html.BeginForm("Create", "Entry", FormMethod.Post, new { id = "createForm" })) {
  @Html.AntiForgeryToken()

  <!--some other things here-->

  @Html.Partial("_Meaning", new MeaningModel() { Number = 1 })
  @Html.Partial("_Meaning", new MeaningModel() { Number = 2 })
  @Html.Partial("_Meaning", new MeaningModel() { Number = 3 })

  <!--some other things here-->

}

And the MeaningModel consists of multiple basic elements like the following:

public class MeaningModel {
    public string MeaningValue { get; set; }
    public int HomonimNumber { get; set; }
    public string Example1 { get; set; }
    public string Example2 { get; set; }
    //and so on
}

Now, in my Controller, I have an Action which handles the Create form submission:

// POST: Meaning/Create
[HttpPost]
public ActionResult Create(WordModel model, List<MeaningModel> meanings, FormCollection collection) {
    try {
        // TODO: Add insert logic here

        return RedirectToAction("Index");
    } catch {
        return View();
    }
}

I could get the values I put in the main View in the WordModel model, but not the values in the Partial Views which consists of elements forming the List<MeaningModel> meanings. Is there any way to access them?

I could give each element in the MeaningModel different name per meaning model (such as MeaningValue_1, MeaningValue_2, MeaningValue_3, HomonimNumber_1, HomonimNumber_2, HomonimNumber_3, and so on) so that they will be captured by the FormCollection. But, as much as possible, I want to take advantage of the MeaningModel I have created and get them by the model.

Any way to do that?

Ian
  • 30,182
  • 19
  • 69
  • 107
  • Short answer is no (unless you were to pass a value for the `HtmlFieldPrefix` - refer [this answer](http://stackoverflow.com/questions/29808573/getting-the-values-from-a-nested-complex-object-that-is-passed-to-a-partial-view/29809907#29809907) which in your case would need to be `[#]` where `#` is a zero based indexer). Its far better to use a `for` loop of custom `EditorTemplate` so that you form controls are correctly named (refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943)) –  Aug 19 '16 at 09:16
  • I look at your answer in the referred post. Thanks, that looks promising. I will test it out. – Ian Aug 19 '16 at 09:18
  • As a side note, does `WordModel` contain a property that is `List`? If so, then the 2nd parameter of the method would not be required - the 'prefix' could be `Meanings[#]` assuming that property is named `Meanings`. But using an `EditorTemplate` is really the correct approach –  Aug 19 '16 at 09:25
  • Also, this seems like it might be related to [your previous question](http://stackoverflow.com/questions/39023419/can-we-append-chunk-of-html-in-jquery-using-html-partial-helper-c-sharp-asp-n) in which case neither approach is likely to work if your also dynamically adding items. You would need something like [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Aug 19 '16 at 09:27
  • @StephenMuecke ah yes, the `WordModel` contain a property that is `List Meanings` I deleted the 2nd parameter and add the prefix `Meanings[#]` and it worked like charm. I also dynamically adding the item, but having `Number` to indicate them. So far it is OK. Thanks! I really owe you, pal! ;) – Ian Aug 19 '16 at 10:36
  • You just need to ensure that the indexer starts at zero and is consecutive (which will be an issue if you also dynamically delete any items in the collection - it would post back non-consecutive indexers and binding would fail) –  Aug 19 '16 at 10:38
  • The adding and deleting of the element is controlled by input number up and down. Thus, it is done one by one - always at the end of the collection. If this is not safe enough, I plan to change it to two buttons (+ and -). Not sure if they are good enough for the long run, but as of now, should be sufficient for my need - it is not the main problem now. The main problem is the collection passing which your answers greatly help to solve already. ;) – Ian Aug 19 '16 at 10:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121340/discussion-between-stephen-muecke-and-ian). –  Aug 19 '16 at 10:44
  • @StephenMuecke That being said, I have a quick question, let say the `MeaningModel` is another complex model which have a `List Examples` property. Will the form be able to pass the `Examples` elements if we give name to the inputs with the naming convention `Meanings[#].Examples[#].SomeProperty` too? – Ian Aug 19 '16 at 11:16
  • Yes, you can nest as many levels deep as you want. So long as the indexers start at zero and are consecutive, then the `DefaultModelBinder` will bind them correctly –  Aug 19 '16 at 11:19
  • @StephenMuecke great, thanks! ;) – Ian Aug 19 '16 at 11:20

0 Answers0