文本框拒绝##,00格式

时间:2016-12-19 13:19:08

标签: html asp.net-mvc textbox currency

我有一个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.");
        }
    }
}

}

1 个答案:

答案 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());

您可能需要将模型绑定器更改为您的特定使用方案。此版本只是根据当前文化进行转换,但如果您要将句点和逗号都作为“小数点”处理,则可能需要在此处执行一些不同类型的处理。