Сложный тип привязки модели MVC, который имеет свойство коллекции сложных типов с Angular JS

Я разрабатываю веб-приложение, используя Angular JS и ASP.NET MVC. Но у меня проблема с привязкой модели сложного типа. Я загружаю список файлов, в основном список строк. В базе данных они (список строк и список файлов) являются одними и теми же столбцами и таблицами, потому что я сохраняю путь после загрузки файла. Для строки я сохраняю тот же столбец с путем к файлу. Например, таблица базы данных имеет столбцы Id(int) и Data(string).

Затем я сохраняю строковые данные, опубликованные AngularJS, в столбце данных для пути к файлу, а также в столбце данных. Но дело в том, что мне нужно помнить порядок. Например, пользователь добавляет текстовое поле, а затем вводит значение, затем динамически добавляет поле файла, затем выбирает файл, затем добавляет текстовое поле и снова вводит значение. Таким образом, порядок должен быть ["значение текста 1", "Файл", "значение текста 2"]. Но проблема в том, что мы не можем связать список данных, смешанный как с HttpPostedFileBase для файла, так и со строкой для текстового значения. Итак, что я сделал, так это создал модели просмотра, как показано ниже.

    public class CreateBlogVM
    {
        [Required]
        [MaxLength(250)]
        public string Title { get; set; }
        [Required]
        public ContentModel[] TextContents { get; set; }
        [Required]
        public ContentFileModel[] Files { get; set; }
    }

    public class ContentModel
    {
        public int OrderNo { get; set; }
        public string Content { get; set; }
    }

    public class ContentFileModel
    {
        public int OrderNo { get; set; }
        public HttpPostedFileBase File { get; set; }
    }

Как вы можете видеть выше, CreateBlogVM будет ViewModel, которую я сейчас привязываю. Этот класс будет иметь два свойства сложного типа — TextContents и Files, которые я объяснил выше, что я делал. Итак, чтобы запомнить порядок, я создал сложный тип с полем OrderNo (Клиент будет передавать это значение), как вы можете видеть выше, поскольку мы не можем связать список данных примерно так.

[HttpPostedFileBase, String, String, HttpPostedFileBase]

Но проблема в том, что когда я публикую данные из Angular js, все значения равны нулю и не привязывают данные. Обязательным является только значение «Заголовок».

    var textContents = new Array();
    var photoContents = new Array();

    for(var i=0; i<$scope.rows.length; i++)
    {
        if($scope.rows[i].type=="text")
        {
            var value = $scope.rows[i].value;
            if (value == "" || value == null) {
                showAlert("Text field should not be empty", "danger");
                return;
            }
            else {
                var content = { OrderNo: i, Content: value }
                textContents.push(content)
            }
        }
        else if($scope.rows[i].type=="photo")
        {
            var file = $scope.rows[i].file;
            if(file==null)
            {
                showAlert("Photo file is required", "danger");
                return;
            }
            else {
                var content = { OrderNo: i, File: file };
                photoContents.push(file);
            }
        }
    }

    var fd = new FormData();
    fd.append('Title', $scope.title);
    fd.append("TextContents", textContents);
    fd.append("Files", photoContents);

    $http.post("/Admin/Blog/Create", fd, {
        transformRequest: angular.identity,
        headers: { 'Content-Type': undefined }
    })

    .success(function () {
    })

    .error(function () {
    });

Вышеприведенный код - это то, как я отправляю данные на сервер. Когда я публикую данные, все значения равны нулю, а mvc не связывает данные. Но когда я привязываю значения без использования сложного типа, подобного этому

public JsonResult Create(HttpPostedFileBase files, String contents, String title)

Но если я привяжусь, как указано выше, я не смогу упорядочить файлы и содержимое строк. Так что не так с моим кодом? Как я могу связать сложные данные, которые имеют список свойств объекта сложного типа?


person Wai Yan Hein    schedule 12.11.2016    source источник
comment
Вы не можете привязать массив объектов (textContents) к string. Но почему не просто модель с string content и HttpPostedFileBase, а затем основная модель содержит коллекцию этой модели, чтобы контент и файл были связаны вместе?   -  person    schedule 12.11.2016
comment
И вы можете добавлять только простые пары name/value для формирования данных, а не наборов объектов.   -  person    schedule 12.11.2016
comment
Вы имеете в виду массив строк и массив HttpPostedFileBase?   -  person Wai Yan Hein    schedule 12.11.2016
comment
Я могу связать коллекцию строк с данными формы, если я использую старый способ, которым я пользуюсь.   -  person Wai Yan Hein    schedule 12.11.2016
comment
Просто массив HttpPostedFileBase и массив строк не подходят, потому что мне нужно передать вместе с ними OrderNo.   -  person Wai Yan Hein    schedule 12.11.2016
comment
Давайте продолжим обсуждение в чате.   -  person    schedule 12.11.2016
comment
что если вы получите как public JsonResult Create(CreateBlogVM model) ?   -  person Mahbubur Rahman    schedule 12.11.2016


Ответы (1)


Измените модели так, чтобы получить прямую связь между Content и связанным File (свойство Order необязательно)

public class CreateBlogVM
{
    [Required]
    [MaxLength(250)]
    public string Title { get; set; }
    public List<FileVM> Files { get; set; }
}
public class FileVM
{
    [Required]
    public string Content { get; set; }
    [Required]
    public HttpPostedFileBase Image { get; set; }
}

Вы можете добавлять к FormData только простые пары name/value (не массивы объектов). В своем цикле добавьте данные, используя

var fd = new FormData();
fd.append('Title', $scope.title);
for (var i=0; i<$scope.rows.length; i++)
{
    ....
    var content = $scope.rows[i].value;
    fd.append('Files[' + i + '].Content', content);
    ....
    var file = $scope.rows[i].file;
    fd.append('Files[' + i + '].Image', file);
}
....

так что вы генерируете имена с помощью индексаторов, которые относятся к вашему свойству коллекции (Files[0].Content, Files[0].Image, Files[1].Content и т. д.)

Тогда ваша подпись метода POST будет

public JsonResult Create(CreateBlogVM model)
person Community    schedule 12.11.2016
comment
Большое спасибо. Это все, что мне нужно. Очень идеальный ответ. - person Wai Yan Hein; 12.11.2016