在Asp.Net MVC千分十进制值 [英] Decimal values with thousand separator in Asp.Net MVC

查看:362
本文介绍了在Asp.Net MVC千分十进制值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一个小数成员,并接受这一类条目的视图的自定义模式类。一切运作良好,直到我加入的JavaScript格式化输入控制里面的号码。格式code格式输入的号码与千位分隔符,当焦点模糊。

问题是,我的模式类中的十进制值是不绑定/与千位分隔符解析好。 ModelState.IsValid返回false当我用1000.00测试它,但它是有效的100.00,没有任何变化。

您可以与我分享,如果您有这方面的任何解决方案?

先谢谢了。

样品类

 公共类Employee
{
    公共字符串名称{;组; }
    公共小数工资{搞定;组; }
}

样品控制器

 公共类EmployeeController:控制器
{
    的[AcceptVerbs(HttpVerbs.Get)
    公众的ActionResult新()
    {
        返回查看();
    }    的[AcceptVerbs(HttpVerbs.Post)
    公众的ActionResult新(员工五)
    {
        如果(ModelState.IsValid)//< - 这是retruning虚假的价值观与,
        {
            //子序列codeS如果条目是有效的。
            //
        }
        返回查看(E);
    }
}

查看示例

 <使用%(Html.BeginForm())
   {%GT;    名称:<%= Html.TextBox(姓名)%>< BR />
    工资待遇:<%= Html.TextBox(工资)%GT;< BR />    <按钮式=提交>保存< /按钮><%}%GT;


我尝试了解决方法使用自定义ModelBinder的亚历山大建议。在万阿英,蒋达清解决。但是该解决方案不与IDataErrorInfo的实施顺利。当因为验证输入0薪水值变为空。任何建议,好吗?
做Asp.Net MVC团队成员来到计算器?我可以从你的帮助不大?

更新code与自定义模型绑定亚历山大建议

模型绑定

 公共类MyModelBinder:DefaultModelBinder {    公众覆盖对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext){
        如果(的BindingContext == NULL){
            抛出新的ArgumentNullException(的BindingContext);
        }        ValueProviderResult valueResult;
        bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName,出valueResult);
        如果(valueResult!= NULL){
            如果(bindingContext.ModelType == typeof运算(十进制)){
                十进制decimalAttempt;                decimalAttempt = Convert.ToDecimal(valueResult.AttemptedValue);                返回decimalAttempt;
            }
        }
        返回null;
    }
}

Employee类

 公共类员工:IDataErrorInfo的{    公共字符串名称{;组; }
    公共小数工资{搞定;组; }    #区域IDataErrorInfo的成员    公共字符串此[字符串COLUMNNAME] {
        获得{
            开关(COLUMNNAME)
            {
                案工资:;无效的工资金额,如果(薪酬和LT = 0)回报;打破;
            }
            返回的String.Empty;
        }
    }    公共字符串错误{
        获得{
            返回的String.Empty;
        }
    }    #endregion
}


解决方案

似乎总有为了使默认的模型绑定高兴能够找到某种形式的解决方法!我想知道,如果你可以创建一个由模型绑定只用了一个伪的属性? (注意,这绝不是大方。我自己,我似乎诉诸类似的把戏像这样越来越多的时候,只是因为他们的工作,他们得到完成的工作......)还请注意,如果你使用一个单独的视图模型(我推荐这个),你可以把这个code在那里,并留下您的域模型非常干净。

 公共类Employee
{
    私人小数_Salary;
    公共字符串MvcSalary //是的,一个字符串。绑定表单值这个!
    {
        {返回_Salary.ToString(); }
        组
        {
            //(在这个伪属性在这里使用一些伪code!)
            如果(AppearsToBeValidDecimal(值)){
                _Salary = StripCommas(值);
            }
        }
    }
    公共小数工资
    {
        {返回_Salary; }
        集合{_Salary =价值; }
    }
}

P.S,我输入这个后,我在现在回头看,我连犹豫是否要发布此,它是如此的丑陋!但如果你认为它可能是有帮助的,我会让你决定...

好运!

-Mike

I have a custom modal class which contains a decimal member and a view to accept entry for this class. Everything worked well till I added javascripts to format the number inside input control. The format code format the inputted number with thousand separator ',' when focus blur.

The problem is that the decimal value inside my modal class isn't bind/parsed well with thousand separator. ModelState.IsValid returns false when I tested it with "1,000.00" but it is valid for "100.00" without any changes.

Could you share with me if you have any solution for this?

Thanks in advance.

Sample Class

public class Employee
{
    public string Name { get; set; }
    public decimal Salary { get; set; }
}

Sample Controller

public class EmployeeController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult New()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult New(Employee e)
    {
        if (ModelState.IsValid) // <-- It is retruning false for values with ','
        {
            //Subsequence codes if entry is valid.
            //
        }
        return View(e);
    }
}

Sample View

<% using (Html.BeginForm())
   { %>

    Name:   <%= Html.TextBox("Name")%><br />
    Salary: <%= Html.TextBox("Salary")%><br />

    <button type="submit">Save</button>

<% } %>


I tried a workaround with Custom ModelBinder as Alexander suggested. The probelm solved. But the solution doesn't go well with IDataErrorInfo implementation. The Salary value become null when 0 is entered because of the validation. Any suggestion, please? Do Asp.Net MVC team members come to stackoverflow? Can I get a little help from you?

Updated Code with Custom Model Binder as Alexander suggested

Model Binder

public class MyModelBinder : DefaultModelBinder {

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
        if (bindingContext == null) {
            throw new ArgumentNullException("bindingContext");
        }

        ValueProviderResult valueResult;
        bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName, out valueResult);
        if (valueResult != null) {
            if (bindingContext.ModelType == typeof(decimal)) {
                decimal decimalAttempt;

                decimalAttempt = Convert.ToDecimal(valueResult.AttemptedValue);

                return decimalAttempt;
            }
        }
        return null;
    }
}

Employee Class

    public class Employee : IDataErrorInfo {

    public string Name { get; set; }
    public decimal Salary { get; set; }

    #region IDataErrorInfo Members

    public string this[string columnName] {
        get {
            switch (columnName)
            {
                case "Salary": if (Salary <= 0) return "Invalid salary amount."; break;
            }
            return string.Empty;
        }
    }

    public string Error{
        get {
            return string.Empty;
        }
    }

    #endregion
}

解决方案

It seems there are always workarounds of some form or another to be found in order to make the default model binder happy! I wonder if you could create a "pseudo" property that is used only by the model binder? (Note, this is by no means elegant. Myself, I seem to resort to similar tricks like this more and more often simply because they work and they get the job "done"...) Note also, if you were using a separate "ViewModel" (which I recommend for this), you could put this code in there, and leave your domain model nice and clean.

public class Employee
{
    private decimal _Salary;
    public string MvcSalary // yes, a string. Bind your form values to this!
    {
        get { return _Salary.ToString(); }
        set
        { 
            // (Using some pseudo-code here in this pseudo-property!)
            if (AppearsToBeValidDecimal(value)) {
                _Salary = StripCommas(value);
            }
        }
    }
    public decimal Salary
    {
        get { return _Salary; }
        set { _Salary = value; }
    }
}

P.S., after I typed this up, I look back at it now and am even hesitating to post this, it is so ugly! But if you think it might be helpful I'll let you decide...

Best of luck!
-Mike

这篇关于在Asp.Net MVC千分十进制值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆