我有一个MVC项目,我根据对象的货币显示不同格式的货币金额 我的项目只处理##。00格式,但我有一些使用欧元的对象需要使用##,00格式而不是##。00。 然后页面以只读模式加载,两种格式都正确显示,但随后表格被编辑,它最初正确显示货币,但如果我点击欧元格式的金额,它会删除",& #34; 超出金额(例如1000,00更改为100000) 在模型中,字段是DataType = Currency并且是小数。此外,如果尝试保存1000,00,则返回无效。
如何让文本框处理这两种货币格式?
这是我的代码
@model Projections.Web.ViewModels.Projections.ProjectionFormView
@Html.HiddenFor(model => model.Number)
@Html.HiddenFor(model => model.Department)
@* -- Quarters -- *@
<div class="edit-fields">
<div class="control-group">
@Html.LabelFor(model => model.Q12017, new {@class = "control-label"})
<div class="controls">
@Html.EditorFor(model => model.Q12017)
</div>
</div>
<div class="control-group">
@Html.LabelFor(model => model.Q22017, new {@class = "control-label"})
<div class="controls">
@Html.EditorFor(model => model.Q22017)
</div>
</div>
<div class="control-group">
@Html.LabelFor(model => model.Q32017, new {@class = "control-label"})
<div class="controls">
@Html.EditorFor(model => model.Q32017)
</div>
</div>
<div class="control-group">
@Html.LabelFor(model => model.Q42017, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Q42017)
</div>
</div>
<div class="control-group">
@Html.LabelFor(model => model.Q12018, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Q12018)
</div>
</div>
</div>
控制器:
public ActionResult Edit(string number, string department)
{
// Get the project we're trying to edit a projection for.
var projects = _db.Projects.FindBy(
x => x.Number == number &&
x.PMUsername == SessionWrapper.CurrentManager,
null,
"Projection").ToList();
if (!projects.Any())
{
return Error(
Notices.ProjectNotFoundTitle,
string.Format(Notices.ProjectNotFound, number)
);
}
var project = projects.SingleOrDefault(x => x.Department == department);
var baseProject = projects.SingleOrDefault(x => x.Department == string.Empty);
// Project doesn't exist, error time!
if (project == null || baseProject == null)
{
return Error(
Notices.DepartmentNotFoundTitle,
string.Format(Notices.DepartmentNotFound, department, number)
);
}
project.Projection = project.Projection ?? new Projection { Number = number, Department = department, Project = project };
SetProjectCulture(project.ProjectCurrencyCode);
var projection = Mapper.Map<ProjectionFormView>(project.Projection);
projection.BaseProjectName = baseProject.Name;
return View(projection);
}
private void SetProjectCulture(string currencyCode)
{
var uiHelper = DependencyResolver.Current.GetService<IThreadUIHelper>();
if (!uiHelper.SetUICulture(currencyCode)) return;
var notice = new Notification(string.Format(Notices.ProjectCurrencyNotice, currencyCode));
NotificationHandler.AddNotification(notice);
}
模型
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Projections.Web.ViewModels.Projections
{
public class Forecast : INotifyPropertyChanged
{
private decimal _q12017;
private decimal _q22017;
private decimal _q32017;
private decimal _q42017;
private decimal _q12018;
[DataType(DataType.Currency)]
public decimal Q12017
{
get { return _q12017; }
set { _q12017 = value; ForecastChanged("Q12017"); }
}
[DataType(DataType.Currency)]
public decimal Q22017
{
get { return _q22017; }
set { _q22017 = value; ForecastChanged("Q22017"); }
}
[DataType(DataType.Currency)]
public decimal Q32017
{
get { return _q32017; }
set { _q32017 = value; ForecastChanged("Q32017"); }
}
[DataType(DataType.Currency)]
public decimal Q42017
{
get { return _q42017; }
set { _q42017 = value; ForecastChanged("Q42017"); }
}
[DataType(DataType.Currency)]
public decimal Q12018
{
get { return _q12018; }
set { _q12018 = value; ForecastChanged("Q12018"); }
}
public decimal Total
{
get
{
var quarters = GetType().GetProperties().Where(x => x.Name.StartsWith("Q")).ToList();
return quarters.Sum(q => (decimal?)q.GetValue(this, null) ?? default(decimal));
}
}
public DateTime? Modified { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void ForecastChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public decimal? this[string name]
{
get
{
var property = GetType().GetProperty(name);
if (property == null) throw new InvalidOperationException("Invalid property specified.");
if (property.PropertyType == typeof(decimal))
{
return property.GetValue(this, null) as decimal?;
}
throw new InvalidOperationException("Invalid property specified.");
}
}
}
}
答案 0 :(得分:0)
默认模型绑定器仅处理具有美式小数点(.
)的小数。如果您需要接受逗号,则需要自定义模型绑定器。我使用以下内容,我找到了原始here。
public class DecimalModelBinder : 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 {
actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
CultureInfo.CurrentCulture);
}
catch (FormatException e) {
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
然后,在Global.asax中的Application_Start
注册:
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
您可能需要将模型绑定器更改为您的特定使用方案。此版本只是根据当前文化进行转换,但如果您要将句点和逗号都作为“小数点”处理,则可能需要在此处执行一些不同类型的处理。