ASP.NET MVC 3 Binding to a Collection inside an Ob

2019-07-29 07:31发布

问题:

I have a model with an object that contains a collection like this:

namespace API.Example.Models
{
    public class OrderTest
    {
        public string UserName { get; set; }

        public string Token { get; set; }

        public POCO.Order Order { get; set; }

    }
}

namespace Supertext.API.POCO
{
    public class Order
    {
        public List<TranslationGroup> Groups = new List<TranslationGroup>();
    }


    public class TranslationGroup
    {
        public string GroupId { get; set; }
    }
}

The Order object contains a collection called Groups.
In the view I display the collection like this (with the index like explained in several examples)

@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)

@for (int i = 0; i < Model.Order.Groups.Count; i++)
{ 
    @Html.LabelFor(m => Model.Order.Groups[i].GroupId)
    @Html.TextBoxFor(m => Model.Order.Groups[i].GroupId)
}

And this is the Controller method that gets called:

[HttpPost]
public ActionResult Index(Models.OrderTest model)

The HTML of the UserName element:

<input id="UserName" name="UserName" style="width:300px;" type="text" value="">

and the GroupId element:

<input id="Order_Groups_0__GroupId" name="Order.Groups[0].GroupId" type="text" value="1">

I can access the UserName, but there is nothing in the collection.
What am I missing? And whats the difference between using m.UserName and Model.Order.Groups (I mean m and Model). Is that my issue?

回答1:

Each property of POCO entity use like a property managed by the CLR. Let the CLR manage the create of instance and etc.. or you can generate conflicts that can throw issues like you have.

Change your Order code to this:

public class Order     
{         
    public List<TranslationGroup> Groups { get; set; }    
}  

--EDIT

I create a new project and add the following class:

public class TranslationGroup
{
    public string GroupId { get; set; } 
}

public class Order
{
    public List<TranslationGroup> Groups { get; set; }
}

public class OrderTest 
{ 
    public string UserName { get; set; } 
    public string Token { get; set; } 
    public Order Order { get; set; } 
} 

Here my code behind of the OrderTestController:

public ActionResult Index()
{
    var orderTest = new Models.OrderTest()
    {
        UserName = "Vinicius",
        Token = "12as1da58sd558",
        Order = new Models.Order()
        {
            Groups = new List<Models.TranslationGroup>()
            {
                new Models.TranslationGroup() { GroupId = "a54s"},
                new Models.TranslationGroup() { GroupId = "a87d"},
                new Models.TranslationGroup() { GroupId = "2gf4"}
            }
        }
    };


    return View(orderTest);
}

[HttpPost]
public ActionResult Index(Models.OrderTest model)
{
    return View();
}

And Index View:

@model TestCollection.Models.OrderTest
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>OrderTest</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.UserName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.UserName)
            @Html.ValidationMessageFor(model => model.UserName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Token)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Token)
            @Html.ValidationMessageFor(model => model.Token)
        </div>
        @for (int i = 0; i < Model.Order.Groups.Count; i++)
        {     
            <div class="editor-label">
                @Html.LabelFor(m => Model.Order.Groups[i].GroupId)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => Model.Order.Groups[i].GroupId)
            </div>
        }
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

So, if you run, and go to OrderTest view, you 'll see all attributes filled, and when you click in create, all things will be binded (the collection as well).