Опубликовать объект с многоуровневым свойством в контроллер - PullRequest
0 голосов
/ 01 января 2019

Мне нужно отправить объект из вида в контроллер, и модель содержит список объектов, у каждого из которых есть список других сложных объектов.Представьте, что у меня есть эти модели:

public class CourseVm {
    public IList<CousreAttendance> CourseAttendances { get; set;}
}

public class CourseAttendance {
    public int StudentId { get; set; }
    public List<SessionAttendance> SessionAttendances { get; set; }
}

public class SessionAttendance {
    public int SessionId { get; set; }
    public bool IsPresent { get; set; }
} 

Я могу отправить список объектов без свойств внутреннего списка, но отправка выше CourseVm в контроллер всегда завершается неудачей.Я хочу создать правильную форму ввода, как показано ниже:

// Before submit form to controller
form.append('<input type="hidden" name="CourseAttendances.Index" value="0" />'+
            '<input type="hidden" name="CourseAttendances[0].StudentId" value="5" />'+

            '<input type="hidden" name="CourseAttendances[0].SessionAttendances.Index" value="0" />' +
            '<input type="hidden" name="CourseAttendances[0].SessionAttendances[0].IsPresent" value="true" />' +
            '<input type="hidden" name="CourseAttendances[0].SessionAttendances[0].SessionId" value="555" />' 

    // Do same logic for SessionAttendances[1..n]
  );

Я не хочу использовать @Html.HiddenFor() по некоторым причинам и вынужден делать скрытые вводы с помощью jquery.Как я могу сделать правильный ввод ??Спасибо.

1 Ответ

0 голосов
/ 02 января 2019

Я нашел решение проблемы и выложил его для будущих читателей.Решение должно состоять из 2 шагов

  1. Все модели должны иметь конструктор без параметров .У одной из моих моделей не было.
  2. Скрытые входные данные должны быть сделаны методом ниже .

Я написал метод, чтобы сделать ввод для объекта отправкис несколькими уровнями списков.Код:

function hiddenInputForComplexListItemWithListProperty(index, inputName, objectProperties) 
{
    /// <summary>
    /// Used when user wants to create related html inputs for a list of a complex object
    /// </summary>
    /// <param name="index">Index of item in the list. it starts from 0</param>
    /// <param name="inputName">The name for the entry in the form.</param>
    /// <param name="objectProperties">The object's properties that hold the data and will carry the information for
    /// the input. The properties should be in the json format. If the property is object again, flatten the inner object.
    /// for example if the object has 2 properties like Id and Student which is complex object, make student object like below:
    /// { "Id": 5, "Student.Id" : 1000, "Student.Name": "Reza", "Student.LastName" : "Ghasemi" }
    /// </param>
    /// <returns>A string containing the hidden inputs for current list object</returns>    
    var inputs = `<input type="hidden" name="${inputName}.Index" value="${index}" />`;
    inputs += _makeInput(index, inputName, objectProperties);

    return inputs;
}

function isPrimitive(obj) {
    /// <summary>Checks the variable and if it is primitive variable returns true.</summary>
    return Object(obj) !== obj;
}

function _normalize(propertyName) {
    return propertyName.replace(/(\[|\]|\.)/g, '_');
}

function _makeInput(index, inputName, values) {
    function _inputForNonPrimitives(values) {
        var output = '';
        Object.keys(values).forEach(function(key) {
            var value = values[key];

            if (isPrimitive(value)) {
                var name = `${inputName}[${index}].${key}`;
                output += `<input type="hidden" name="${name}" id="${_normalize(name)}" value="${value}" Value="${value}" />`;
            } else {
                for (var i = 0; i < value.length; i++) {
                    output += _makeInput(i, `${inputName}[${index}].${key}`, value[i]);
                }
            }
        });
        return output;
    }

    if (isPrimitive(values))
        return `<input type="hidden" name="${inputName}[${index}]" id="${_normalize(name)}" value="${values}" Value="${values}" />`;

    var output = '';
    if (Array.isArray(values)) {
        values.forEach(function(item) {
            output += _inputForNonPrimitives(item);
        });
    } else {
        output += _inputForNonPrimitives(values);
    }

    return output;
}

Использование: считается, что вы хотите отправить список следующих моделей на контроллер:

{
    "Id" : 1,
    "CourseAttendances": [ 
                          {"StudentId" : 100, 
                           "SessionAttendances" : [{"SessionId":1, "IsPresent":true},
                                                   {"SessionId":2, "IsPresent":false}]
                          },
                          {"StudentId" : 101, 
                           "SessionAttendances" : [{"SessionId":1, "IsPresent":true},
                                                   {"SessionId":2, "IsPresent":true}]
                          }
                         ]
}

вы должны сделать объект следующим образом:

var form = $('#yourForm');

for (var i=0; i<list_of_objects; i++){
    form.append(
        hiddenInputForComplexListItemWithListProperty(
             i,  // i will be the index of object
             "CourseAttendances", // Name of property name in the model
             all_of_model_properties_with_their_values                                          
        ));
}

Правильная форма метода вызова для примера модели json (о котором я писал выше):

hiddenInputForComplexListItemWithListProperty(
    1,
    "CourseAttendances",
    [ 
     {"StudentId" : 100, 
      "SessionAttendances" : [{"SessionId":1, "IsPresent":true},
                              {"SessionId":2, "IsPresent":false}]
     },
     {"StudentId" : 101, 
      "SessionAttendances" : [{"SessionId":1, "IsPresent":true},
                              {"SessionId":2, "IsPresent":true}]
     }
    ]
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...