Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I edit an IEnumerable<T> with ASP.NET MVC 3?

Given the following types

public class SomeValue
{
    public int Id { get; set; }
    public int Value { get; set; }
}

public class SomeModel
{
    public string SomeProp1 { get; set; }
    public string SomeProp2 { get; set; }
    public IEnumerable<SomeValue> MyData { get; set; }
}

I want to create an edit form for the type SomeModel which would contain the usual text fields for SomeProp1 and SomeProp2 and then a table containing a text field for each SomeValue in the SomeModel.MyData collection.

How is this done? How do the values get bound back to the model?

I currently have a form displaying a text field for each value but they all have the same name and same Id. This is obviously not valid HTML and will prevent MVC from mapping the values back.

like image 512
Greg B Avatar asked Nov 20 '10 16:11

Greg B


1 Answers

You would do it using Editor Templates. This way the framework will take care of everything (from properly naming the input fields to properly binding the values back in the post action).

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // In the GET action populate your model somehow
        // and render the form so that the user can edit it
        var model = new SomeModel
        {
            SomeProp1 = "prop1",
            SomeProp2 = "prop1",
            MyData = new[] 
            {
                new SomeValue { Id = 1, Value = 123 },
                new SomeValue { Id = 2, Value = 456 },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(SomeModel model)
    {
        // Here the model will be properly bound
        // with the values that the user modified
        // in the form so you could perform some action
        return View(model);
    }
}

View (~/Views/Home/Index.aspx):

<% using (Html.BeginForm()) { %>

    Prop1: <%= Html.TextBoxFor(x => x.SomeProp1) %><br/>
    Prop2: <%= Html.TextBoxFor(x => x.SomeProp2) %><br/>
    <%= Html.EditorFor(x => x.MyData) %><br/>
    <input type="submit" value="OK" />
<% } %>

And finally the Editor Template (~/Views/Home/EditorTemplates/SomeValue.ascx) which will be automatically invoked for each element of the MyData collection:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyApp.Models.SomeValue>" %>
<div>
    <%= Html.TextBoxFor(x => x.Id) %>
    <%= Html.TextBoxFor(x => x.Value) %>
</div>
like image 135
Darin Dimitrov Avatar answered Oct 20 '22 05:10

Darin Dimitrov