Как сериализовать форму с массивом ввода

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

Вот мой метод сохранения

var brewer = _$form.serializeFormToObject();

abp.services.app.brewer.create(brewer).done(() => {
    ...
});

// brewerService
serviceNamespace.create = function(brewerDto, ajaxParams) {
    return abp.ajax($.extend({
        url: abp.appPath + 'api/services/app/brewer/Create',
        type: 'POST',
        data: JSON.stringify(brewerDto)
    }, ajaxParams));
};

Вот моя форма

<form name="AddBrewerForm" role="form" novalidate class="form-validation">
    <ul class="nav nav-tabs tab-nav-right" role="tablist">
        <li role="presentation" class="active">
            <a href="#brewer-detail" data-toggle="tab">@L("BrewerDetails")</a>
        </li>

        <li role="presentation">
            <a href="#beers-list" data-toggle="tab">@L("Beers")</a>
        </li>
    </ul>

    <div class="tab-content">
        <div role="tabpanel" class="tab-pane animated fadeIn active" id="brewer-detail">
            <div class="row clearfix" style="margin-top:10px;">
                <div class="col-sm-12">
                    <div class="form-group form-float">
                        <div class="form-line">
                            <input id="name" type="text" name="Name" required class="validate form-control" />
                            <label for="name" class="form-label">Name</label>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div role="tabpanel" class="tab-pane animated fadeIn" id="beers-list">
            <div id="beer-list-content">
                <div class="brewer-beer-card row form-group form-float" style="border: 1px solid black;">
                    <div class="col-md-10">
                        <div class="form-line">
                            <input id="beer-0" type="text" name="Beers[0].Name" required class="validate form-control" />
                            <label for="beer-0" class="dynamic-beer-label form-label">@L("Name")</label>
                       </div>
                    </div>
                </div>

                <div class="brewer-beer-card row form-group form-float" style="border: 1px solid black;">
                    <div class="col-md-10">
                        <div class="form-line">
                            <input id="beer-1" type="text" name="Beers[1].Name" required class="validate form-control" />
                            <label for="beer-1" class="dynamic-beer-label form-label">@L("Name")</label>
                       </div>
                    </div>
                </div>
            </div>

            <div class="row" style="margin-top: 10px;">
                <div class="col-sm-12 ">
                    <button type="button" id="add-beer-button" class="btn btn-primary waves-effect">
                        @L("Add")
                    </button>
                </div>
            </div>
        </div>
    </div>
</form>

ApplicationServiceDto

public class InsertBrewerDto
{
    [Required]
    [StringLength(128)]
    public string Name { get; set; }

    public List<NewBrewerBeerDto> Beers { get; set; }
}

public class NewBrewerBeerDto
{
    [Required]
    public string Name { get; set; }
}

jquery-плагин ABP для сериализации

$.fn.serializeFormToObject = function () {
    //serialize to array
    var data = $(this).serializeArray();

    //add also disabled items
    $(':disabled[name]', this).each(function () {
        data.push({ name: this.name, value: $(this).val() });
    });

    //map to object
    var obj = {};
    data.map(function (x) { obj[x.name] = x.value; });

    return obj;
};

Я продолжаю получать нуль для своих массивов пива...

Итак, я попытался использовать $(form).serialize(), но получаю эту ошибку: Ваш запрос недействителен!

Попробуй это:

Так что ошибки не видно...

Ошибка консоли JavaScript:

{код: 0, сообщение: "Ваш запрос недействителен!", сведения: "Во время проверки были обнаружены следующие ошибки. ↵ - ↵", validationErrors: Array(1)} код: 0 сведения: "Обнаружены следующие ошибки во время проверки. ↵ - ↵" сообщение: "Ваш запрос недействителен!" validationErrors: Массив(1) 0: Члены: Массив(1) 0: "brewerDto" длина: 1 сообщение: ""

ИЗМЕНИТЬ1

JS для получения консоли

Во время проверки были обнаружены следующие ошибки.

    var b1 = _$form.serialize();
    var b2 = _$form.serializeArray();
    var b3 = _$form.serializeFormToObject();

    console.log(b1);
    console.log(b2);
    console.log(b3);

b1

Name=123&Beers%5B0%5D.Name=123&Beers%5B1%5D.Name=321

b2

(3) [{…}, {…}, {…}]
0:{name: "Name", value: "123"}
1:{name: "Beers[0].Name", value: "123"}
2:{name: "Beers[1].Name", value: "321"}
length:3

b3

{Name: "123", Beers[0].Name: "123", Beers[1].Name: "321"}
Beers[0].Name :"123"
Beers[1].Name : "321"
Name : "123"

person Vince    schedule 30.09.2017    source источник
comment
Такая же ошибка происходит   -  person adiga    schedule 30.09.2017
comment
см. мой Edit1 для вывода консоли   -  person Vince    schedule 30.09.2017
comment
Это сработало для меня, я думаю, что это может быть особенностью структуры abp. Может быть стоит отметить   -  person Vince    schedule 30.09.2017
comment
Я думаю, это должен быть очень хороший ответ! но ABP все еще терпит неудачу.... без какого-либо сообщения проверки, ожидающего на их странице github, чтобы увидеть, что не так   -  person PowerMan2015    schedule 29.09.2019


Ответы (2)


Выход:

$.fn.serializeFormToObjectWithArraysOfObjects = function () {
    var obj = $(this).serializeFormToObject();
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        var result = key.match(/(.*)\[(\d)\].(.*)/);
        if (result) {
          var outer = result[1];
          var index = result[2];
          var inner = result[3];
          obj[outer] = obj[outer] || [];
          obj[outer][index] = obj[outer][index] || {};
          obj[outer][index][inner] = obj[key];
          delete obj[key];
        }
      }
    }
    return obj;
};

Рассматривали ли вы возможность использования JSON и повторения ввода формы вручную?

{Name: "123", Beers: [{Name: "123"}, {Name: "321"}]}
person aaron    schedule 02.10.2017
comment
вау... stackoverflow заставил меня проверить неправильный ответ. извините, ссылка на github github.com/aspnetboilerplate/aspnetboilerplate/issues/2553 - person Vince; 03.10.2017
comment
Объект сериализуется по умолчанию... их свойство сериализуемо. Для Json я пробовал Serialize и SerializeToArray, и оба не работают, и я получаю сообщение об ошибке - person Vince; 03.10.2017

Существует много способов сериализации форм в объект JSON, и они зависят от фактической разметки и имен форм, в этом примере используется параметр «id», который необходимо установить (и, как лучше всего, сделать их равными к имени поля:

Есть и другие стратегии, но мне нравится эта, потому что мы можем явно указать, что мы хотим отправить на сервер:

<input name="example" id="example" />

и мы можем применить здесь простые правила проверки перед их отправкой.

var list_of_fields = ["f1","f2","f3"];

Некоторый пример кода:

попробуйте использовать

<input name="example" id="example" />
и удалить
var list_of_fields = ["f1","f2","f3"];
. Вот так:
var list_of_fields = ["f1","f2","f3"];
var serialised_values = {}
for(var i=0;i<list_of_fields.length;i++){
    var dom_object = document.getElementById(list_of_fields[i]);
    if(dom_object.tagName == "INPUT" || dom_object.tagName == "TEXTAREA"){
        serialized_values[dom_object.name] = dom_object.value;
    }
    if(dom_object.tagName == "SELECT"){
        serialized_values[dom_object.name] = dom_object.options[dom_object.selectedIndex].value;
    }

    //other field types go here

    //validation can go here too...
}
console.log(serialized_values);

var list_of_fields = ["f1","f2","f3"];
var serialised_values = {}
for(var i=0;i<list_of_fields.length;i++){
    var dom_object = document.getElementById(list_of_fields[i]);
    if(dom_object.tagName == "INPUT" || dom_object.tagName == "TEXTAREA"){
        serialized_values[dom_object.name] = dom_object.value;
    }
    if(dom_object.tagName == "SELECT"){
        serialized_values[dom_object.name] = dom_object.options[dom_object.selectedIndex].value;
    }

    //other field types go here

    //validation can go here too...
}
console.log(serialized_values);
person Felipe Valdes    schedule 30.09.2017
comment
как насчет преобразования $(this) в ссылку на фактическую форму с использованием метода dom, может быть, это не то, что вы ожидаете?? - person Vince; 30.09.2017
comment
это определенно моя форма, я подтверждаю это - person Felipe Valdes; 30.09.2017
comment
Я отредактировал свой ответ, чтобы объяснить свою точку зрения, пожалуйста, просмотрите, Винс - person Vince; 30.09.2017
comment
Моя проблема в том, что у меня есть список одного и того же элемента Beer[0].Name Beer[1].Name, поэтому он будет одинаковым для всех, если я использую эту стратегию или с индексом. я хотел бы что-то более общее, что создаст объект json, потому что я не знаю, сколько у меня будет каждого объекта. - person Felipe Valdes; 01.10.2017
comment
тогда я думаю, просто используйте document.getElementById(form).querySelector(INPUT) чтобы получить список элементов, нет? - person Vince; 03.10.2017
comment
Вот файл журнала WARN 2017-09-30 10:53:13,458 [31] nHandling.AbpApiExceptionFilterAttribute — аргументы метода недействительны! Подробнее см. ValidationErrors. Abp.Runtime.Validation.AbpValidationException: аргументы метода недействительны! Подробнее см. ValidationErrors. at Abp.Runtime.Validation.Interception.MethodInvocationValidator.ThrowValidationError() at Abp.Runtime.Validation.Interception.MethodInvocationValidator.Validate() at Abp.WebApi.Validation.AbpApiValidationFilter.d__5.MoveNext() --- Конец трассировки стека из предыдущее расположение, где было выдано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(задача задачи) в Abp.WebApi.Auditing.AbpApiAuditFilter.d__4.MoveNext( ) --- Конец трассировки стека из предыдущего места, где было выдано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(задача задачи) в System.Web .Http.Controllers.ActionFilterResult.d__2.MoveNext() --- Конец трассировки стека из предыдущего места, где возникло исключение --- в System.Runtime.CompilerServices.TaskAw aiter.ThrowForNonSuccess(задача) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(задача) в Abp.WebApi.Security.AntiForgery.AbpAntiForgeryApiFilter.d__10.MoveNext() --- Конец трассировки стека из предыдущего места, где было исключение брошено --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(задача задачи) в Abp.WebApi.Authorization.AbpApiAuthorizeFilter.d__7.MoveNext() --- End трассировки стека из предыдущего места, где было создано исключение --- в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(задача задачи) в System.Web.Http.Controllers. AuthenticationFilterResult.d__0.MoveNext() --- Конец трассировки стека из предыдущего места, где было выдано исключение --- в System.Runtime.CompilerServices.TaskAwa iter.ThrowForNonSuccess (задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в System.Web.Http.Controllers.ExceptionFilterResult.d__0. MoveNext() WARN 2017-09-30 10:53:13,458 [31] nHandling.AbpApiExceptionFilterAttribute — 1 ошибка проверки: WARN 2017-09-30 10:53:13,458 [31] nHandling.AbpApiExceptionFilterAttribute — (brewerDto) - person Felipe Valdes; 03.10.2017