user547995
user547995

Reputation: 2085

Model properties are null after submit

I have this model:

 public partial class Group
    {
        public Group()
        {
            this.ParameterGroup = new HashSet<ParameterGroup>();
        }

        public string GroupId { get; set; }
        public string Responsibility { get; set; }

        public virtual Text GroupDescText { get; set; }
        public virtual Text GroupNameText { get; set; }
        public virtual ICollection<ParameterGroup> ParameterGroup { get; set; }
    }

public partial class Text
    {
        public Text()
        {
            this.ParamName = new HashSet<Parameter>();
            this.ParamDesc = new HashSet<Parameter>();
            this.EnumElemName = new HashSet<EnumElem>();
            this.IoDeviceInfoText = new HashSet<IoDeviceInfo>();
            this.IoCatText = new HashSet<IoDeviceInfo>();
            this.GroupDesc = new HashSet<Group>();
            this.GroupName = new HashSet<Group>();
            this.Type = new HashSet<Type>();
            this.ParamDispPath = new HashSet<Parameter>();
            this.EnumElemText = new HashSet<EnumElem>();
            this.TextValue = new HashSet<TextValue>();
        }

        public string TextId { get; set; }
        public string XmlId { get; set; }

        public virtual ICollection<Parameter> ParamName { get; set; }
        public virtual ICollection<Parameter> ParamDesc { get; set; }
        public virtual ICollection<EnumElem> EnumElemName { get; set; }
        public virtual ICollection<IoDeviceInfo> IoDeviceInfoText { get; set; }
        public virtual ICollection<IoDeviceInfo> IoCatText { get; set; }
        public virtual ICollection<Group> GroupDesc { get; set; }
        public virtual ICollection<Group> GroupName { get; set; }
        public virtual ICollection<Type> Type { get; set; }
        public virtual ICollection<Parameter> ParamDispPath { get; set; }
        public virtual ICollection<EnumElem> EnumElemText { get; set; }
        public virtual ICollection<TextValue> TextValue { get; set; }
    }

This is my Controller:

 public class GroupController : Controller
    {
        // GET: Group
        public ActionResult Index()
        {
            return PartialView("Index", GroupModel.Instance.getGroups());
        }

        public ActionResult Edit(string id)
        {
            Group group = KebaContext.SessionBasedContext().GroupSet.Where(g => g.GroupId == id).FirstOrDefault();
            List<Language> langs = KebaContext.SessionBasedContext().LanguageSet.ToList();
            foreach(Language l in langs)
            {
                if(group.GroupDescText == null)
                {
                    group.GroupDescText = new Text();
                    TextValue value = new TextValue();
                    value.TextId = Guid.NewGuid().ToString("N");
                    value.LangId = l.LangId;
                    value.Value = "";
                    group.GroupDescText.TextValue.Add(value);
                }
                if (group.GroupNameText == null)
                {
                    group.GroupNameText = new Text();
                    TextValue value = new TextValue();
                    value.TextId = Guid.NewGuid().ToString("N");
                    value.LangId = l.LangId;
                    value.Value = "";
                    group.GroupNameText.TextValue.Add(value);
                }
                if (group.GroupDescText != null && group.GroupDescText.TextValue.Where(x => x.LangId == l.LangId).FirstOrDefault() == null) //just one lang is available
                {
                    TextValue value = new TextValue();
                    value.TextId = group.GroupDescText.TextValue.First().TextId;
                    value.LangId = l.LangId;
                    value.Value = "";
                    group.GroupDescText.TextValue.Add(value);
                }
                if (group.GroupNameText != null && group.GroupNameText.TextValue.Where(x => x.LangId == l.LangId).FirstOrDefault() == null) //just one lang is available
                {
                    TextValue value = new TextValue();
                    value.TextId = group.GroupNameText.TextValue.First().TextId;
                    value.LangId = l.LangId;
                    value.Value = "";
                    group.GroupNameText.TextValue.Add(value);
                }
            }
            return View(group);
        }

        [HttpPost]
        public ActionResult Edit(Group xyz)
        {

            return RedirectToAction("Index", "Types");
        }
    }

This is my View:

@using System.Web.Mvc.Html;
@model Keba.Data.EF.Group
@{
    ViewBag.Title = "Group Editing";
}
<h2>Edit Group</h2>
<div id="groupEdit">
    @using (Html.BeginForm("Edit", "Group", FormMethod.Post))
    {
        @Html.HiddenFor(model => model.GroupId);
        <table class="userEditAddTable">
            <tr><th>Responsibility</th><td>@Html.EditorFor(model => model.Responsibility)</td></tr>
            @foreach (var name in Model.GroupNameText.TextValue)
            {
                @Html.HiddenFor(model => name.LangId)
                @Html.HiddenFor(model => name.Value)
                <tr><th>GroupNameText(@Html.DisplayFor(model => name.LangId))</th><td> @Html.TextBoxFor(model => name.Value)</td></tr>;
            }
            @foreach (var desc in Model.GroupDescText.TextValue)
            {
                @Html.HiddenFor(model => desc.LangId)
                @Html.HiddenFor(model => desc.Value)
                <tr><th>GroupDescText(@Html.DisplayFor(model => desc.LangId))</th><td> @Html.TextBoxFor(model => desc.Value)</td></tr>;
            }
        </table>
        <br />
        <div id="buttons">
            <input name="Save" type="submit" value="Save" class="button" />
            <input name="Cancel" type="submit" value="Cancel" class="button" />
        </div>
    }
</div>

Problem:

If I try to change the value of a Text in the group model e.g. GroupNameText.TextValue.Value send it to the controller (submit). The properties GroupNameText and GroupDescText are null. I have also tried the solution with propertybinding ([Bind(Include = "GroupDescText,GroupNameText")] Group xyz) which also doesn't work

Upvotes: 1

Views: 1170

Answers (2)

Mahmoud Hboubati
Mahmoud Hboubati

Reputation: 1107

Have a look at this similar to your approach is to have a list in the view, you might need to have partials.

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239270

First, remember that only properties that are posted (i.e. have a form input element representing them) will be populated.

Second, the names of the input elements must match up to what the model binder expects on post, or it will discard the values, as it won't know what to do with them. In particular, with enumerables, this means you need to use for loops rather than foreach, so that Razor can create the right name binding:

@for (var i = 0; i < Model.GroupNameText.TextValue; i++)
{
    @Html.HiddenFor(m => m.GroupNameText.TextValue[i].LangId)
    @Html.HiddenFor(m => m.GroupNameText.TextValue[i].Value)
    ...
}

That will result in a name attribute like GroupNameText.TextValue[0].LangId, which the model binder should be able to bind appropriately, whereas your field names are currently just LangId, which is meaningless on post.

Upvotes: 3

Related Questions