在我的ASP.NET MVC核心代码优先项目中,我有一个类型为float的属性SaleAmount的模型,我已成功以货币格式显示但是当我使用此属性保存数据时,我将此字段设为SQL Server数据库中为null。在调试模式下,当我在控制器中的这一行oAnnualSales.SaleAmount = item.SaleAmount;
上放置断点时(如下所示),我可以看到item.SaleAmount
为空。
查看:
public class AnnualSale
{ @model IList<MyProj.Models.SaleViewModel>
<div class="row">
<div class="col-md-9">
<form asp-controller="DbRelated" asp-action="UpdateSales" asp-route-returnurl="@ViewData[" ReturnUrl"]" method="post">
<table class="table">
<thead>
<tr>
<th></th>
<th>
State Name
</th>
<th>
Sale Amount
</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>@Html.HiddenFor(r => r[i].StateId)</td>
<td>
@Html.EditorFor(r => r[i].StateName)
</td>
<td>
@Html.EditorFor(r => r[i].SaleAmount)
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
[Key]
public int Sale_Id { get; set; }
public int? FiscalYear { get; set; }
[DisplayFormat(DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
public float? SaleAmount { get; set; }
public int StateId { get; set; }
public StateName StateName { get; set; }
}
模型:
public class AnnualGrant
{
[Key]
public int Sale_Id { get; set; }
public int? FiscalYear { get; set; }
[DisplayFormat(DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
public float? SaleAmount { get; set; }
public int StateId { get; set; }
public StateName StateName { get; set; }
}
控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UpdateSales(List<SaleViewModel> model, string returnUrl = null)
{
if (ModelState.IsValid)
{
foreach (var item in model)
{
var oAnnualSales = _context.AnnualSales.Where(r => r.StateId.Equals(item.StateId)).FirstOrDefault();
if (oAnnualSales != null)
{
oAnnualSales.FiscalYear = item.FY;
oAnnualSales.SaleAmount = item.SaleAmount;
}
else
{
AnnualSale oAnnualSaleNew = new AnnualSale { StateId = item.StateId, FiscalYear = item.FY, SaleAmount = item.SaleAmount};
_context.Add(oAnnualSaleNew);
}
}
await _context.SaveChangesAsync();
return View(model);
}
// If we got this far, something failed, redisplay form
return View();
}
答案 0 :(得分:0)
正如您对问题的评论中所提到的,使用该值发布货币符号等字符将不会解析为浮动?,因此将恢复为null。您可以通过编写一个使用float.TryParse的快速单元测试或控制台应用程序来测试它,它将返回0.您需要(不推荐)将金额更改为字符串,或者(推荐)具有货币类型和金额作为不同的属性。使用金额过帐货币符号也依赖于用户输入货币符号,这不太可能发生
答案 1 :(得分:0)
ASP.NET MVC默认不支持此功能,但您可以使用自定义模型绑定器解决此问题。
首先需要为自定义模型绑定创建一个新类:
public class FloatModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
if (bindingContext.ModelMetadata.EditFormatString.StartsWith("{0:c", StringComparison.InvariantCultureIgnoreCase))
{
actualValue = float.Parse(valueResult.AttemptedValue, NumberStyles.Currency);
}
else
{
actualValue = float.Parse(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
}
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
然后你需要将它添加到MVC绑定器中,方法是将它添加到Application_Start方法中:
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(float?), new FloatModelBinder());
}