1

I'm trying to dynamically create a form with different types of fields. Then simply pass the user inputted data back to the controller and bind back to my model. I'm using a custom editor template for each control and was hoping it would bind properly in the controller. However, the property is NULL each time so I cannot retrieve the input values.

Model

public class ReceiptModel : ClassBase
{
    public int ReceiptId { get; set; }
    public List<CustomControlModel> CustomControlList { get; set; }
}

public class CustomControlModel 
{
    public string CustomControlName { get; set; }
    public CustomControlType CustomControlType { get; set; }
}

View

@foreach (CustomControlModel ccm in @Model.CustomControlList)
{
    if (!string.IsNullOrEmpty(ccm.PropertyName))
    {
        @Html.EditorFor(model => ccm, "CustomControlModel")
    }
}

Custom Template

@Html.HiddenFor(model => model.CustomControlId)


<label>@Model.LabelCaption</label>

@switch (@Model.CustomControlType)
{

case CustomControlType.TEXTBOX:
                    if (@Model.ReadOnly)
                    {

                        @Html.TextBoxFor(model => model.CustomControlId, new { @readonly = "readonly", @Value = @Model.Value })
                    }
                    else
                    {

        <input id="@Model.CustomControlName" name="@Model.CustomControlName" type="text" value="@Model.Value" />
}

Any help would be much appreciated. Thanks in advance.

8
  • It simply needs to be @Html.EditorFor(m => m.CustomControlList) - no foreach loop assuming you have located the EditorTemplate in the /Views/Shared/EditorTemplates folder (or the /Views/yourControllerName/EditorTemplates folder). But its a bit unclear what if (!string.IsNullOrEmpty(ccm.PropertyName)) is for - you model does not have a property named PropertyName Commented Jan 8, 2016 at 23:17
  • Take a look at this simple project: github.com/SirwanAfifi/SimpleFormGenerator Commented Jan 9, 2016 at 8:23
  • Thanks for the quick response. This works well to get my controls on the page, but the inputted values are not being set with the model binder. When the user submits the form, can't I simply reference the values in the model or is there a trick to get the new values? Commented Jan 9, 2016 at 15:14
  • If your POST method has a parameter ReceiptModel model then it will be correctly bound (including the collection) when you submit. If your having problems, then you need to post more code. Commented Jan 10, 2016 at 9:14
  • @StephenMuecke I assume the problem is in my custom editor template. Code added above. Commented Jan 10, 2016 at 15:36

1 Answer 1

1

Don't use foreach. It does not result in the correct property names in the rendered html and so the properties will not be picked up by the model binder. Use a for loop instead:

@for (int i = p; I < @Model.CustomControlList.Count; i++)
{
    if (!string.IsNullOrEmpty(Model.CustomControlList[i].PropertyName))
    {
        @Html.EditorFor(model => model.CustomControlList[i], "CustomControlModel")
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I believe you made two typos: int i = 0; and i < Model.CustomControlList.Count;
Correct. Gold star. I left the @ by accident. For some reason 'i' is always replaced with 'I' when writing on here. Most annoying.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.