具有全局数字格式的 ASP.NET MVC 模型绑定器 [英] ASP.NET MVC Model Binder with Global Number Formats

查看:21
本文介绍了具有全局数字格式的 ASP.NET MVC 模型绑定器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我的应用程序用于对小数使用不同数字格式的国家/地区(例如 1.2 = 1,2)时,默认模型绑定器会返回双精度类型属性的错误.网站的文化在我的 BaseController 中有条件地设置.

我已尝试添加自定义模型绑定器并覆盖 bindModel 函数,但我看不到如何解决那里的错误,因为文化已被设置回默认的 en-GB.

所以我尝试向我的 BaseController 添加一个动作过滤器,在那里设置文化,但不幸的是 bindModel 似乎在我的动作过滤器之前被触发.

我该如何解决这个问题?要么让文化不重置自己,要么在 bindModel 启动之前将其设置回来?

模型无效的控制器:

public ActionResult Save(MyModel myModel){如果(模型状态.IsValid){//保存我的模型}别的{//引发错误}}

过滤设置文化的地方:

public override void OnActionExecuting(ActionExecutingContext filterContext){CultureInfoculture = createCulture(filterContext);如果(文化!= null){Thread.CurrentThread.CurrentCulture = 文化;Thread.CurrentThread.CurrentUICulture = 文化;}base.OnActionExecuting(filterContext);}

自定义模型绑定器:

public class InternationalDoubleModelBinder : DefaultModelBinder{公共覆盖对象 BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext){ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);如果(值结果!= null){if (bindingContext.ModelType == typeof(double) || bindingContext.ModelType == typeof(Nullable)){双双尝试;doubleAttempt = Convert.ToDouble(valueResult.AttemptedValue);返回 doubleAttempt;}}返回空;}}

解决方案

您希望您的应用程序使用单一文化,对吗?如果是这样,您可以使用 web.config 的全球化标签执行此操作.

<预><代码><配置><system.web><全球化enableClientBasedCulture="true"文化=zh-GB"uiCulture="en-GB"/></system.web></配置>

然后你可以忘记那些自定义模型绑定器并使用默认值.

更新: 好的,这是一个多语言应用程序.你如何获得你想要的文化?你能在 MvcApplication 类上调用 createCulture 吗?你可以这样做:

公共类 MvcApplication : HttpApplication{//...public void Application_OnBeginRequest(对象发送者,EventArgs e){CultureInfo 文化 = GetCulture();Thread.CurrentThread.CurrentCulture = 文化;Thread.CurrentThread.CurrentUICulture = 文化;}//...}

此方法在模型绑定之前被调用,因此,同样,您将不需要自定义模型绑定器.我希望它对你有用:)

The default model binder is returning errors for properties that are of type double when my application is being used in countries that use different number formatting for decimals (e.g. 1.2 = 1,2). The culture of the site is set conditionally in my BaseController.

I have tried adding a custom model binder and overriding the bindModel function but I can't see how to get around the error in there as the Culture has already been set back to the default of en-GB.

So I tried adding an action filter to my BaseController that sets the Culture there but unfortunately bindModel seems to get fired before my action filter.

How can I get around this? Either by getting the Culture to not reset itself or set it back before bindModel kicks in?

Controller where model comes in invalid:

public ActionResult Save(MyModel myModel)
{
    if (ModelState.IsValid)
    {
        // Save my model
    }
    else
    {
       // Raise error
    }
}

Filter where Culture is set:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    CultureInfo culture = createCulture(filterContext);

    if (culture != null)
    {
         Thread.CurrentThread.CurrentCulture = culture;
         Thread.CurrentThread.CurrentUICulture = culture;
    }

    base.OnActionExecuting(filterContext);
}

Custom Model Binder:

public class InternationalDoubleModelBinder : DefaultModelBinder
{
   public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   {
       ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
       if (valueResult != null)
       {
           if (bindingContext.ModelType == typeof(double) || bindingContext.ModelType == typeof(Nullable<double>))
           {
               double doubleAttempt;

               doubleAttempt = Convert.ToDouble(valueResult.AttemptedValue);

               return doubleAttempt;
           }
        }
        return null;
   }
}

解决方案

You want your application to use a single culture, right? If so, you can do this with the globalization tag of your web.config.

<configuration>
    <system.web>
        <globalization
           enableClientBasedCulture="true"        
           culture="en-GB"
           uiCulture="en-GB"/>
    </system.web>
</configuration>

And then you can forget those custom model binder and use the default.

UPDATE: Ok, it's a multi-language application. How do you get the culture you want? Can you call createCulture on the MvcApplication class? You could do this:

public class MvcApplication : HttpApplication
{
    //...
    public void Application_OnBeginRequest(object sender, EventArgs e)
    {
        CultureInfo culture = GetCulture();
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;
    }
    //...
}

This method is called before the model bind, so, again, you won't need the custom model binder. I hope it works for you :)

这篇关于具有全局数字格式的 ASP.NET MVC 模型绑定器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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