Reputation: 10400
I have a model, Sample
which contains a List<QCItem>
, which is populated in the constructor.
In my Sample.Create.cshtml
form, I have the following section, for populating the Mass
values of each item in a List<QCItem>
in the model:
@for (var itemCnt = 0; itemCnt < Model.Defects.Count(); itemCnt++)
{
@Html.LabelFor(m => Model.Defects[itemCnt], Model.Defects[itemCnt].Criteria)
@Html.HiddenFor(m => Model.Defects[itemCnt].Criteria,
new { @value = Model.Defects[itemCnt].Criteria })
@Html.TextBoxFor(m => Model.Defects[itemCnt].Mass)
@Html.HiddenFor(m => Model.Defects[itemCnt].Mass)
}
While debugging, I can see that each item in Model.Defects
in the controller for Model
contains the Mass
value I entered in the TextBoxFor
, and also that each of these textboxes have the correct label next to them.
However, I also need each of these QCItem
s to have Criteria
assigned, which is why I added the HiddenFor
field above, but when the debugger hits the controller, each of the QCItem
s has a Criteria
value of null
.
How can I pass this value to the controller action in the same way that Mass
is being passed? (It should automatically be assigned to the correct QCItem
) The value definitely exists, as it is displayed in the LabelFor
.
This is the method in SampleController:
public ActionResult Insert(HttpPostedFileBase file, Sample sample)
{
SelectedPallet = (Pallet)Session["pallet"];
sample.Pallet = SelectedPallet;
var access = new Access();
access.InsertNewQCSample(sample);
var files = Request.Files;
// Insert into database
return View("Details");
}
Here is the Sample
model with all of its properties:
public class Sample : IGriddable
{
private DataRow dataRow;
private DataRow row;
public string[] ColumnHeaders { get; } = new string[] { "SampleNumber", "Date", "ClerkStatus", "SupervisorStatus" };
public string RowLinkPrefix { get { return $"/receiving/{Pallet.Grv.GrvNumber}/{Pallet.PalletSequence}/"; } }
public bool Selectable { get; } = true;
public Pallet Pallet { get; set; }
public string Clerk { get; set; }
public string MassOff { get; set; }
public string ProductionComment { get; set; }
public string Quantity { get; set; }
public string Supervisor { get; set; }
public string TechnicalComment { get; set; }
public string SampleNumber { get; set; }
public string ClerkStatus { get; set; }
public DateTime Date { get; set; }
public string SupervisorStatus { get; set; }
public string ProductSpec { get; set; }
// Each defect status needs to be saved as a (DB)subQCItems item
public List<QCItem> Defects { get; set; } = new List<QCItem>();
public List<string> ImagePaths { get; set; } = new List<string>();
}
Here is the QCItem
model:
public class QCItem : IGriddable
{
public string[] ColumnHeaders { get; } = new string[] { "Criteria", "Major", "Mass" };
public string RowLinkPrefix { get; } = string.Empty;
public bool Selectable { get; } = false;
public string Criteria { get; internal set; }
public bool Major { get; set; }
public int Mass { get; set; }
public Sample Sample;
}
Upvotes: 2
Views: 80
Reputation:
You have given your Criteria
property and internal
setter and the DefaultModelBinder
cannot set it (it needs to be public
)
public string Criteria { get; set; }
Side notes:
Your LabelFor()
method is not associating a the label with the textbox (clicking on it will not set focus. It needs to be
@Html.LabelFor(m => Model.Defects[itemCnt].Mass, Model.Defects[itemCnt].Criteria)
Your hidden input for Criteria
should be just
@Html.HiddenFor(m => Model.Defects[itemCnt].Criteria)
The hidden input for Mass
is pointless and its value will be ignored by the DefaultModelBinder
because your have a TextBoxFor()
for the same property before the hidden input
Upvotes: 1
Reputation: 10400
Thanks to the help of Stephen Muecke's comment (which gave a suggestion which I had already tried), I noticed that the Criteria
property had an internal
setter, which cannot be accessed from the view.
After changing this to
public string Criteria { get; set; }
and in the form:
@for (var itemCnt = 0; itemCnt < Model.Defects.Count(); itemCnt++)
{
@Html.LabelFor(m => Model.Defects[itemCnt], Model.Defects[itemCnt].Criteria)
@Html.HiddenFor(m => Model.Defects[itemCnt].Criteria)
@Html.TextBoxFor(m => Model.Defects[itemCnt].Mass)
}
It now works fine
Upvotes: 0