How to take multiple values for a strongly typed list of data models in ASP.NET-MVC-5 inside razor code
I have a strongly typed view model and I need to grab multiple entries for "List" from the user for a strongly typed list. I am struggling to achieve this in razor code. This is the [httpget] method.
View Model
public class AccommodationApplicationViewModel
{
public AccommodationApplicationViewModel()
{
_RentingApplicationModel = new PropertyRentingApplication();
_PropertyRentingPriceModel = new List<PropertyRentingPrice>();
_AdditionalTenantModel = new List<AdditionalTenant>();
_StudentLimitedInfoModel = new List<StudentLimitedInfo>();
}
public PropertyRentingApplication _RentingApplicationModel { get; set; }
public List<PropertyRentingPrice> _PropertyRentingPriceModel { get; set; }
public List<AdditionalTenant> _AdditionalTenantModel { get; set; }
public List<StudentLimitedInfo> _StudentLimitedInfoModel { get; set; }
}
Shaver code
<div>
<div class="form-group">
@Html.LabelFor(model => model._StudentLimitedInfoModel[0].StudentNumber_UWLID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
//@Html.EditorFor(model => model._StudentLimitedInfoModel[0].StudentNumber_UWLID, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
@Html.ValidationMessageFor(model => model._StudentLimitedInfoModel[0].StudentNumber_UWLID, "", new { @class = "text-danger" })*@
</div>
</div>
I am getting error on the following line
@Html.EditorFor(model => model._StudentLimitedInfoModel[0].StudentNumber_UWLID, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
Mistake:
The index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
source to share
You can take one of two approaches with you. If there is a fixed number of elements for the list, you can simply initialize it with the appropriate number of instances. For example:
_PropertyRentingPriceModel = new List<PropertyRentingPrice>
{
new PropertyRentingPrice(),
new PropertyRentingPrice(),
new PropertyRentingPrice()
};
This will give you three items. Then, in your opinion:
@for (var i = 0; i < Model._PropertyRentingPriceModel.Count(); i++)
{
@Html.EditorFor(m => m._PropertyRentingPriceModel[i].Foo)
}
If the elements are more fluid, or the user needs to be able to add or remove elements as they wish, you will need a JavaScript solution that would involve creating the inputs and manually naming them accordingly. For this, I would recommend using some template-enabled data binding library like Knockout or Angular. It will make your life so much easier. When creating your JavaScript template, you just need to keep in mind the collection input naming convention that will be expected from the module-module in your POST: request CollectionProperty[Index].Property
. For example, you will need to look something like this:
<input type="text" name="_PropertyRentingPriceModel[0].Foo" value="" />
source to share