ASP.NET MVC模型绑定与全球数字格式 [英] ASP.NET MVC Model Binder with Global Number Formats

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

问题描述

默认的模型粘合剂返回错误的时,我的应用程序在使用不同的编号为小数格式(例如1.2 = 1,2)国家正在使用的是双精度型属性。该网站的文化在我BaseController有条件地设置。

我曾尝试添加自定义模型粘合剂和覆盖bindModel功能,但我看不出如何让周围的错误在那里的文化已经被设置回EN-GB。

默认

所以,我想增加一个动作过滤器,以我的BaseController,设置文化有无奈bindModel看来我的动作过滤器之前被解雇。

我怎样才能解决这个问题?无论是通过让文化到不能复位或bindModel踢之前设置回来?

控制器,其中模型进来无效:

 公众的ActionResult保存(为MyModel基于myModel)
{
    如果(ModelState.IsValid)
    {
        //保存我的模型
    }
    其他
    {
       //引发错误
    }
}

过滤器,其中文化设置:

 公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
    CultureInfo的文化= createCulture(filterContext);    如果(文化!= NULL)
    {
         Thread.CurrentThread.CurrentCulture =文化;
         Thread.CurrentThread.CurrentUICulture =文化;
    }    base.OnActionExecuting(filterContext);
}

自定义模型绑定:

 公共类InternationalDoubleModelBinder:DefaultModelBinder
{
   公众覆盖对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext)
   {
       ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
       如果(valueResult!= NULL)
       {
           如果(bindingContext.ModelType == typeof运算(双)|| bindingContext.ModelType == typeof运算(可空<双>))
           {
               双doubleAttempt;               doubleAttempt = Convert.ToDouble(valueResult.AttemptedValue);               返回doubleAttempt;
           }
        }
        返回null;
   }
}


解决方案

您想您的应用程序使用一个单一的文化,对不对?
如果是这样,你可以用你的web.config全球化标签做到这一点。

 <结构>
    <&的System.Web GT;
        <全球化
           enableClientBasedCulture =真
           文化=EN-GB
           的UICulture =EN-GB/>
    < /system.web>
< /结构>

然后你就可以忘记那些自定义模型粘合剂和使用默认值。

更新:确定,这是一个多语言的应用程序。你如何获得你想要的文化吗?您可以拨打createCulture在MvcApplication类?你可以这样做:

 公共类MvcApplication:一个HttpApplication
{
    // ...
    公共无效Application_OnBeginRequest(对象发件人,EventArgs的发送)
    {
        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天全站免登陆