我试图序列化一个包含对象数组的表单并将其发送到我的应用程序服务,但我找不到任何方法让它工作......
这是我的保存方法
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; }
}
用于序列化的ABP的jquery插件
$.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(),但我收到此错误:您的请求无效!
所以没有显示错误......
这是日志文件 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(任务任务) at 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.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) at Abp.WebApi.Security.AntiForgery.AbpAntiForgeryApiFilter.d__10.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) at Abp.WebApi.Authorization.AbpApiAuthorizeFilter.d__7.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在System.Web.Http.Controllers.AuthenticationFilterResult.d__0.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.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)
Javscript控制台错误:
{code:0,message:&#34;您的请求无效!&#34;,详细信息:&#34;验证期间检测到以下错误。 ↵ - ↵&#34;,validationErrors:Array(1)} 码 : 0 细节 : &#34;验证期间检测到以下错误。 ↵ - ↵&#34; 信息 : &#34;您的请求无效!&#34; validationErrors : 阵列(1) 0 : 会员 : 阵列(1) 0 : &#34; brewerDto&#34; 长度 : 1 信息 : &#34;&#34;
EDIT1
获取控制台的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"
答案 0 :(得分:1)
您是否考虑过使用JSON并手动迭代表单输入?
有很多方法可以将表单序列化为JSON对象,它们依赖于实际的标记和表单名称,这个例子依赖于&#34; id&#34;要设置的参数(并且最佳做法是使它们等于到字段名称:
<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);
答案 1 :(得分:1)
试试这个:
$.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;
};
输出:
{Name: "123", Beers: [{Name: "123"}, {Name: "321"}]}