tags:

views:

636

answers:

3

This same question was asked here and an answer was given which is workable, but with the finalization of the ASP.Net MVC framework, I wondered if there was a better solution.

If I have the following class structure how do create the view page and more importantly return the data back to the controller.

public class Person {


public int Id {get;set;}
  public string Name {get;set;}
  public IList<TelNos> TelNos {get;set;}
}

public class TelNos{
  public string Type {get;set;}
  public string Number {get;set;}
}

My understanding is that within the page I would could include the following (assuming strongly typed view):

<% foreach (var telNo in Model.Product.TelNos)
               {%>
            <p><label for="telNo.Type">Type of Number</label>

                <%= Html.TextBox("telNo.Type")%>
                <%= Html.ValidationMessage("telNo.Type", "*")%>
            </p>
<p><label for="telNo.Number">Type of Number</label>

                <%= Html.TextBox("telNo.Number")%>
                <%= Html.ValidationMessage("telNo.Number", "*")%>
            </p>
            <%} %>

Assuming that I initiated 2 TelNos objects I would then see 2 sets of text boxes within the view.

When that form is posted back, the suggestion on the previous post was to iterate through the FormCollection within the post method:

[AcceptVerbs( HttpVerb.POST )]
public ActionResult Whatever( FormCollection form )
{
 ....
}

However is that now the best approach, or have the further updates to MVC provided a better solution?

Thanks, Richard

+2  A: 

There have not been any updates or best practices (as far as I'm aware of) to handling dynamic forms on post. The still tried and true ways are to either databind your information, or iterate through it in the FormCollection. If you take a look here it might help you with the databinding. OR in the latter case, you could iterate through the forms collection calling up the various values with their string name. Although this could possibly have some conflicts since they are all going to have the same id of

 "telNo.Type"
 "telNo.Number"

You might have to do some manipulation to have it be something like

 "telNo.Type[i]"
 "telNo.Number[i]"

where i is a number in sequence for that object in the list. You could also have it be something other string combination that generates a unique id for that object so that you can get the type and the number.

 "object[i].telNo.Type" 
 "object[i].telNo.Number"

It really depends on how you think you can best implement it. Sometimes getting databinding to work for dynamic forms can be a pain and it's easier to just iterate through the collection, then using something like LINQ to get the ones you want/group them/etc.

MunkiPhD
A: 

Thanks for your answer. Your answer did give me an idea, which I think is different to what you are suggesting.

If I include in the view an index to the object, then the Default Model builder takes the values and assigns them to the associated objects. The view code is as follows:

    <% int i=0;
foreach (var telNo in Model.Product.TelNos)
                   {%>
                <p><label for="telNo.Type">Type of Number</label>

                    <%= Html.TextBox("telNo"+i.ToString()+".Type")%>
                    <%= Html.ValidationMessage("telNo"+i.ToString()+".Type", "*")%>
                </p>
    <p><label for="telNo.Number">Type of Number</label>

                    <%= Html.TextBox("telNo"+i.ToString()+".Number")%>
                    <%= Html.ValidationMessage("telNo"+i.ToString()+".Number", "*")%>
                </p>
                <%i++;
} %>

Richard

Richbits
A: 

I like the idea at http://stackoverflow.com/questions/1033635/asp-net-mvc-partial-view-with-form which in turn links to Model Binding To A List

I think it's better for two reason:

  1. Going through FormCollection violates the idea of separating view form controller. Controller will have too much knowledge on how the data is displayed.
  2. Writing a unit test will be painful. you'll need to stick all the values into the form controller manually
Vitalik