ASP MVC HTML Form POST List <Entity>

Today I struggle with the same problem all day. I am still starting ASP MVC coming from the Flex world. But now I am working on some ASP MVC project.

I think this is a rather complicated problem, so I describe the problem in great detail. So thanks in advance for saying the time to go through this!

System Description:

I am trying to create a "ProjectManagementSystem". You can have several projects where each project has a name and description. The project also has a list of additional information. A normal form would allow me to enter a name and description for a new project, right?

Now the requirement is to add additional form elements. For example, I want to add a new input that will allow me to enter an affordable budget for all existing and new projects.

Budget - additional detail of the project. IE when element a is added from the budget, a new project detail is added for all projects.

Classes:

I got the Project class, which has a ProjectDetails list, and also provides some interface for getting, adding and removing ProjectDetail from Project:

public class Project : ProjectItem { public virtual IList<ProjectDetail> Details { get; set; } public Project(string name, string description) : base(name, description) { Details = new List<ProjectDetail>(); } public Project() : this("new project", "this is a new project") { } public virtual void AddDetail(string name) { var detail = GetDetail(name); if (detail == null) { detail = new ProjectDetail(name, "empty"); detail.Project = this; Details.Add(detail); } } public virtual void RemoveDetail(string name) { var detail = GetDetail(name); if (detail != null) { detail.Project = null; Details.Remove(detail); } } public virtual ProjectDetail GetDetail(string name) { ProjectDetail result = null; foreach (ProjectDetail detail in Details) { if (detail.Name.Equals(name)) { result = detail; } } return result; } } 

The "ProjectDetail" class is as follows:

 public class ProjectDetail : ProjectItemDetail { [NotNull] public virtual Project Project { get; set; } public ProjectDetail(string name, string value) : base(name, value) { } public ProjectDetail() : this("new project detail", "empty") { } } 

Note that "ProjectDetail" inherits the name and value from the ProjectItem base class.

I am trying to create a view that allows me to edit one Value for all ProjectDetails in the details list of a specific Project. Now each "ProjectDetail" is associated with a "FormElement", and they correspond to the Name property.

 public class FormElement { public static string TYPE_UNKNOWN = "typeUnknown"; public static string TYPE_NUMERIC = "typeNumeric"; public static string TYPE_CHAR = "typeChar"; public static string TYPE_DATE = "typeDate"; [NotNull] public virtual string Name { get; set; } [NotNull] public virtual int Position { get; set; } [NotNull] public virtual string Type { get; set; } [NotNull] public virtual Form Form { get; set; } public FormElement(string name, int position, string type) { Name = name; Position = position; Type = type; } public FormElement() : this("unknownFormElement", -1, TYPE_UNKNOWN) { } } 

And the class "Form":

 public class Form : Entity { [NotNull] public virtual string Name { get; set; } public virtual IList<FormElement> FormElements { get; set; } public Form(string name) { Name = name; FormElements = new List<FormElement>(); } public Form() : this("unknownWebform") { } //public interface for getting, adding, deleting FormElement } 

Thus, the view will have to display the “Form” and populate the elements with the value of the associated “ProjectDetail”.

So, the view is passed to "ProjectEditModel":

 public class ProjectEditModel { public Form Form; public Project Project; public ProjectViewModel() {} } 

In the "ProjectEditModel" the following view is strictly indicated:

 <% using (Html.BeginForm("Edit", "Project", FormMethod.Post)) {%> <div> <fieldset> <legend>Edit Project</legend> <div class="editor-label"> <%: Html.LabelFor(m => m.Project.Name) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Project.Name)%> </div> <div class="editor-label"> <%: Html.LabelFor(m => m.Project.Description)%> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Project.Description)%> </div> <% foreach (var formElement in Model.Form.FormElements) { if (formElement.Type.Equals(Domain.Model.FormElement.TYPE_CHAR)) { %> <div class="editor-label"> <%: Html.Label(Model.Project.GetDetail(formElement.Name).Name)%> </div> <div class="editor-field"> <%: Html.TextBoxFor(m => m.Project.GetDetail(formElement.Name).Value)%> </div> <% } if (formElement.Type.Equals(Domain.Model.FormElement.TYPE_NUMERIC)) { } } %> <p> <input type="hidden" name="Id" value="<%: Model.Project.Id %>" /> <input type="submit" value="Save" /> </p> </fieldset> </div> <% } %> 

This will display correctly and show the form element for each additional part. But when I return the POST model, the constructor will be called, and thus I will lose all my links. PENG!

I read that MVC "just works" like this, and I am ready to accept it, but how can I solve my problem? Do you need more information?

Thank you, I would love the help!

+4
source share
1 answer

MVC will not automatically process the way you try to dynamically create a form. He will not associate your collection of form elements with the collection, since it does not have the ability to distinguish between them.

Try the methodology described in this blog post to handle dynamic model collection and binding.

+2
source

All Articles