ASP MVC HTML-форма POST List <Entity> - PullRequest
4 голосов
/ 12 декабря 2010

Сегодня я весь день боролся с одной и той же проблемой. Я все еще начинающий ASP MVC, пришедший из мира Flex. Но сейчас я работаю над проектом ASP MVC.

Я думаю, что это довольно сложная проблема, поэтому я пытаюсь описать проблему очень подробно. Так что заранее спасибо, что вы обсуждаете время, чтобы пройти через это!

Описание системы:

Я пытаюсь создать "ProjectManagementSystem". Вы можете иметь несколько проектов, где у каждого проекта есть имя и описание. Проект также имеет список дополнительных деталей. Нормальная форма позволит мне ввести имя и описание для нового проекта, верно?

Теперь требуется, чтобы можно было добавить дополнительные элементы формы. Например, я хочу добавить новый ввод, который позволит мне ввести доступный бюджет для всех существующих и новых проектов.

Бюджет является дополнительной деталью проекта. IE. при добавлении элемента a для бюджета новая деталь проекта добавляется ко всем проектам.

Классы:

Я получил класс «Project», который имеет список «ProjectDetails», а также предоставляет некоторый интерфейс для получения, добавления и удаления «ProjectDetail» из «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;
    }
}

Класс "ProjectDetail" выглядит следующим образом:

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")
    { 

    }
}

Обратите внимание, что ProjectDetail наследует Name и Value от базового класса ProjectItem.

Я пытаюсь создать представление, которое позволит мне редактировать единственное свойство Value всех «ProjectDetails» в списке «Подробности» определенного «Проекта». Теперь каждый «ProjectDetail» связан с «FormElement», и им соответствует их свойство Name.

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)
    {

    }

}

И класс "Форма":

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 
}

Таким образом, представление должно будет визуализировать «форму» и заполнить элементы значением соответствующего «ProjectDetail».

Итак, представление передается в "ProjectEditModel":

public class ProjectEditModel
{
    public Form Form;

    public Project Project;

    public ProjectViewModel() {}
}

Следующее представление строго типизировано как "ProjectEditModel":

<% 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>

<% } %>

Это будет правильно отображаться и отображать элемент формы для каждой дополнительной детали. Но когда я верну модель POST, будет вызван конструктор, и таким образом я потеряю все свои ссылки. PENG!

Я читал, что MVC "просто работает", как это, и я готов принять это, но как мне решить мою проблему тогда? Вам нужна дополнительная информация?

Большое спасибо, очень признателен за помощь!

1 Ответ

2 голосов
/ 06 апреля 2011

MVC не будет автоматически обрабатывать способ, которым вы пытаетесь динамически создать форму. Он не будет связывать вашу коллекцию элементов формы с коллекцией, так как не может различить их.

Попробуйте методологию, описанную в этого сообщения в блоге , для обработки динамического рендеринга коллекции и привязки модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...