我正在尝试验证动态添加的字段并保存到DB中。表单验证正在工作,但当我将表单提交给控制器模型时。计数没有更改。(型号计数=1)
我相信问题很简单,但出于某种原因我看不出问题。我在等你的帮助。
您还可以看到工作示例和调试屏幕截图。
编辑
在这个屏幕截图中,你可以看到客户端页面,调试模式
型号
public int BudgetId { get; set; }
public int DistributionId { get; set; }
public int InvoiceId { get; set; }
public bool ExtraBudgetary { get; set; }
public string ExtraBudgetaryNo { get; set; }
public string Currency { get; set; }
[Required]
public decimal CurrencyRate { get; set; }
[Required]
public string Description { get; set; }
public bool DistributionTemp { get; set; }
[Required]
public decimal ActualAmount { get; set; }
[Required]
public decimal Percentage { get; set; }
public DateTime TransactionDate { get; set; }
public string DistributionName { get; set; }
public int ProcessedBy { get; set; }
public string Explanation { get; set; }
public bool Validity { get; set; }
查看
<div class="row">
<div class="col-sm-12">
<section class="panel panel-default">
<header class="panel-heading">
<i class="fa fa-bolt"></i>
Actions
<span class="tools pull-right">
<a href="javascript:;" class="fa fa-chevron-down"></a>
<a href="javascript:;" class="fa fa-cog"></a>
<a href="javascript:;" class="fa fa-times"></a>
</span>
</header>
<div class="panel-body">
<a href="/Budget/Home/Index" class="btn btn-white btn-danger btn-round btn-xs">
<i class="fa fa-times"></i>
Close
</a>
<button class="btn btn-white btn-success btn-round btn-xs" type="submit" tabindex="14" value="Create">
<i class="fa fa-floppy-o bigger-120 green"></i>
Save
</button>
</div>
</section>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<section class="panel panel-success">
<header class="panel-heading">
<i class="fa fa-credit-card"></i>
New Actual(s)
<span class="tools pull-right">
<a href="javascript:;" class="fa fa-chevron-down"></a>
<a href="javascript:;" class="fa fa-cog"></a>
<a href="javascript:;" class="fa fa-times"></a>
</span>
</header>
<div class="panel-body" style="overflow-x: scroll;">
<div class="pull-left">
<br />
<button type="button" class="btn btn-white btn-success btn-round btn-xs addButton"><i class="fa fa-plus"></i></button>
<div class="">
@if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var i in Model)
{
<div class="form-group">
<div class="col-xs-2">
@Html.DropDownListFor(m => m[j].BudgetId, (IEnumerable<SelectListItem>)ViewBag.BudgetId, htmlAttributes: new { @class = "form-control" })
</div>
<div class="col-xs-1">
@Html.DropDownListFor(m => m[j].InvoiceId, (IEnumerable<SelectListItem>)ViewBag.InvoiceId, htmlAttributes: new { @class = "form-control" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].ActualAmount, new { @class = "form-control", @placeholder = "Actual Amount" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].Percentage, new { @class = "form-control", @placeholder = "Percentage" })
</div>
<div class="col-xs-1">
@Html.DropDownListFor(m => m[j].ExtraBudgetary, new SelectList(Enum.GetValues(typeof(TrueFalse))), htmlAttributes: new { @class = "form-control", @placeholder = "Is ExtraBudgetary ?" })
</div>
<div class="col-xs-2">
@Html.TextBoxFor(m => m[j].ExtraBudgetaryNo, new { @class = "form-control", @placeholder = "ExtraBudgetary No" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].CurrencyRate, new { @class = "form-control", @placeholder = "Currency Rate" })
</div>
<div class="col-xs-2">
@Html.TextBoxFor(m => m[j].Description, new { @class = "form-control", @placeholder = "Description" })
</div>
</div>
<div class="form-group hide" id="actualTemplate">
<div class="col-xs-2">
@Html.DropDownListFor(m => m[j].BudgetId, (IEnumerable<SelectListItem>)ViewBag.BudgetId, htmlAttributes: new { @class = "form-control" })
</div>
<div class="col-xs-1">
@Html.DropDownListFor(m => m[j].InvoiceId, (IEnumerable<SelectListItem>)ViewBag.InvoiceId, htmlAttributes: new { @class = "form-control" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].ActualAmount, new { @class = "form-control", @placeholder = "Actual Amount" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].Percentage, new { @class = "form-control", @placeholder = "Percentage" })
</div>
<div class="col-xs-1">
@Html.DropDownListFor(m => m[j].ExtraBudgetary, new SelectList(Enum.GetValues(typeof(TrueFalse))), htmlAttributes: new { @class = "form-control", @placeholder = "Is ExtraBudgetary ?" })
</div>
<div class="col-xs-2">
@Html.TextBoxFor(m => m[j].ExtraBudgetaryNo, new { @class = "form-control", @placeholder = "ExtraBudgetary No" })
</div>
<div class="col-xs-1">
@Html.TextBoxFor(m => m[j].CurrencyRate, new { @class = "form-control", @placeholder = "Currency Rate" })
</div>
<div class="col-xs-2">
@Html.TextBoxFor(m => m[j].Description, new { @class = "form-control", @placeholder = "Description" })
</div>
<div class="col-xs-1">
<button type="button" class="btn btn-white btn-danger btn-round btn-xs removeButton"><i class="fa fa-minus"></i></button>
</div>
</div>
j++;
}
}
</div>
</div>
</div>
</section>
</div>
</div>
<script>
$(document).ready(function () {
budgetIdValidators = {
row: '.col-xs-2',
validators: {
notEmpty: {
message: 'The budget Id is required'
},
numeric: {
message: 'The budget Id must be a numeric number'
}
}
},
invoiceIdValidators = {
row: '.col-xs-1',
validators: {
notEmpty: {
message: 'The invoice Id is required'
},
numeric: {
message: 'The invoice Id must be a numeric number'
}
}
},
actualAmountValidators = {
row: '.col-xs-1',
validators: {
notEmpty: {
message: 'The actual amount is required'
},
numeric: {
message: 'The actual amount must be a numeric number'
}
}
},
percentageValidators = {
row: '.col-xs-1',
validators: {
notEmpty: {
message: 'The percentage is required'
},
numeric: {
message: 'The percentage must be a numeric number'
}
}
},
extraBudgetaryValidators = {
row: '.col-xs-1',
validators: {
notEmpty: {
message: 'The extrabudgetary is required'
}
}
},
extraBudgetaryNoValidators = {
row: '.col-xs-2',
validators: {
notEmpty: {
message: 'The extrabudgetary no is required'
}
}
},
currencyRateValidators = {
row: '.col-xs-1',
validators: {
notEmpty: {
message: 'The currency rate is required'
},
numeric: {
message: 'The currency rate must be a numeric number'
}
}
},
descriptionValidators = {
row: '.col-xs-2',
validators: {
notEmpty: {
message: 'The description is required'
}
}
},
actualIndex = 0;
$('#actualsCreateForm')
.formValidation({
framework: 'bootstrap',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
'[0].BudgetId': budgetIdValidators,
'[0].InvoiceId': invoiceIdValidators,
'[0].ActualAmount': actualAmountValidators,
'[0].Percentage': percentageValidators,
'[0].ExtraBudgetary': extraBudgetaryValidators,
'[0].ExtraBudgetaryNo': extraBudgetaryNoValidators,
'[0].CurrencyRate': currencyRateValidators,
'[0].Description': descriptionValidators,
}
})
.on('click', '.addButton', function () {
actualIndex++;
var $template = $('#actualTemplate'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.attr('data-actual-index', actualIndex)
.insertBefore($template);
$clone
.find('[name="BudgetId"]').attr('name', '[' + actualIndex + '].BudgetId').end()
.find('[name="InvoiceId"]').attr('name', '[' + actualIndex + '].InvoiceId').end()
.find('[name="ActualAmount"]').attr('name', '[' + actualIndex + '].ActualAmount').end()
.find('[name="Percentage"]').attr('name', '[' + actualIndex + '].Percentage').end()
.find('[name="ExtraBudgetary"]').attr('name', '[' + actualIndex + '].ExtraBudgetary').end()
.find('[name="ExtraBudgetaryNo"]').attr('name', '[' + actualIndex + '].ExtraBudgetaryNo').end()
.find('[name="CurrencyRate"]').attr('name', '[' + actualIndex + '].CurrencyRate').end()
.find('[name="Description"]').attr('name', '[' + actualIndex + '].Description').end();
$('#actualsCreateForm')
.formValidation('addField', '[' + actualIndex+ '].BudgetId', budgetIdValidators)
.formValidation('addField', '[' + actualIndex+ '].InvoiceId', invoiceIdValidators)
.formValidation('addField', '[' + actualIndex+ '].ActualAmount', actualAmountValidators)
.formValidation('addField', '[' + actualIndex+ '].Percentage', percentageValidators)
.formValidation('addField', '[' + actualIndex+ '].ExtraBudgetary', extraBudgetaryValidators)
.formValidation('addField', '[' + actualIndex+ '].ExtraBudgetaryNo', extraBudgetaryNoValidators)
.formValidation('addField', '[' + actualIndex+ '].CurrencyRate', currencyRateValidators)
.formValidation('addField', '[' + actualIndex+ '].Description', descriptionValidators);
})
.on('click', '.removeButton', function () {
var $row = $(this).parents('.form-group'),
index = $row.attr('data-actual-index');
$('#actualsCreateForm')
.formValidation('removeField', $row.find('[name="[' + index + '].BudgetId"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].InvoiceId"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].ActualAmount"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].Percentage"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].ExtraBudgetary"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].ExtraBudgetaryNo"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].CurrencyRate"]'))
.formValidation('removeField', $row.find('[name="[' + index + '].Description"]'));
$row.remove();
})
.on('err.field.fv', function (e, data) {
data.element
.data('fv.messages')
.find('.help-block[data-fv-for="' + data.field + '"]').hide();
});
});
</script>
控制器
if (ModelState.IsValid)
{
var status = statusRepository.FindByName("In Process of Actualization");
var user = userRepository.FindByName(SessionPersister.Username);
foreach (var i in acVM)
{
var invoice = invoiceRepository.FindById(i.InvoiceId);
Actual actual = new Actual
{
BudgetId = i.BudgetId,
InvoiceId = i.InvoiceId,
ActualAmount = i.ActualAmount,
ExtraBudgetary = i.ExtraBudgetary,
ExtraBudgetaryNo = i.ExtraBudgetaryNo,
TransactionDate = DateTime.Now,
Currency = "USD",
CurrencyRate = i.CurrencyRate,
Description = i.Description,
//DistributionTemp = i.DistributionTemp,
Percentage = i.Percentage
};
actualRepository.Create(actual);
if (actual != null)
{
if (i.DistributionTemp == true)
{
DistributionTemplate distributionTemp = new DistributionTemplate
{
DistributionName = i.DistributionName,
Percentage = i.Percentage,
ProcessedBy = user.UserId,
Explanation = i.Description,
Validity = i.Validity,
ActualAmount = actual.ActualAmount,
TransactionDate = DateTime.Now
};
distributionTempRepository.Create(distributionTemp);
if (distributionTemp != null)
{
actual.DistributionId = distributionTemp.DistributionId;
actualRepository.Update(actual);
}
}
Process process = new Process
{
InvoiceId = i.InvoiceId,
StatusId = status.StatusId,
ProcessedBy = user.UserId,
ProcessDate = DateTime.Now,
//Confirmatory = relatedUnitManager.UnitId
};
processRepository.Create(process); // Yapılan işlemin kaydedilmesi
ViewBag.BudgetId = new SelectList(budgetRepository.SelectBudgets(), "BudgetId", "BudgetId", i.BudgetId);
ViewBag.DistributionId = new SelectList(distributionTempRepository.SelectDistributions(), "DistributionId", "DistributionName", i.DistributionId);
ViewBag.InvoiceId = new SelectList(invoiceRepository.SelectInvoices(), "InvoiceId", "InvoiceNo", i.InvoiceId);
if (process != null)
{
invoice.LastProcessId = process.ProcessId;
invoiceRepository.Update(invoice); // Yapılan son işleme dair id bilgisinin fatura tablosuna eklenmesi
}
}
else
{
TempData["MessageFail"] += "Something went wrong!";
return RedirectToAction("Details/" + invoice.InvoiceId, "Invoices");
}
acVM = new List<ActualizationVM> { new ActualizationVM { ExtraBudgetary = false, ExtraBudgetaryNo = "", BudgetId = 0, InvoiceId = 0, Description = "", ActualAmount = 0, Percentage = 0, CurrencyRate = 0} };
TempData["MessageSuccess"] += "Invoice is successfully actualized.";
return RedirectToAction("Details/" + invoice.InvoiceId, "Invoices");
}
}
return View(acVM);
编辑2
当我更新命名时,如下命名克隆工作正常,但当我提交表单计数时,仍然没有增加
$clone
.find('[name="[' + actualIndex + '].BudgetId"]').attr('name', '[' + actualIndex + '].BudgetId').end()
.find('[name="[' + actualIndex + '].InvoiceId"]').attr('name', '[' + actualIndex + '].InvoiceId').end()
.find('[name="[' + actualIndex + '].ActualAmount"]').attr('name', '[' + actualIndex + '].ActualAmount').end()
.find('[name="[' + actualIndex + '].Percentage"]').attr('name', '[' + actualIndex + '].Percentage').end()
.find('[name="[' + actualIndex + '].ExtraBudgetary"]').attr('name', '[' + actualIndex + '].ExtraBudgetary').end()
.find('[name="[' + actualIndex + '].ExtraBudgetaryNo"]').attr('name', '[' + actualIndex + '].ExtraBudgetaryNo').end()
.find('[name="[' + actualIndex + '].CurrencyRate"]').attr('name', '[' + actualIndex + '].CurrencyRate').end()
.find('[name="[' + actualIndex + '].Description"]').attr('name', '[' + actualIndex + '].Description').end();
我认为这是不正确的:
$clone
.find('[name="BudgetId"]').attr('name', '[' + actualIndex + '].BudgetId').end()
.find('[name="InvoiceId"]').attr('name', '[' + actualIndex + '].InvoiceId').end()
.find('[name="ActualAmount"]').attr('name', '[' + actualIndex + '].ActualAmount').end()
.find('[name="Percentage"]').attr('name', '[' + actualIndex + '].Percentage').end()
.find('[name="ExtraBudgetary"]').attr('name', '[' + actualIndex + '].ExtraBudgetary').end()
.find('[name="ExtraBudgetaryNo"]').attr('name', '[' + actualIndex + '].ExtraBudgetaryNo').end()
.find('[name="CurrencyRate"]').attr('name', '[' + actualIndex + '].CurrencyRate').end()
.find('[name="Description"]').attr('name', '[' + actualIndex + '].Description').end();
我不确定绑定元素的正确"命名",尽管我以前遇到过这种问题。我的方法是增加我的原始列表,循环浏览它,然后复制绑定的方式