具有全局数字格式的ASP.NET MVC模型绑定器

时间:2011-02-19 12:00:41

标签: asp.net-mvc localization model number-formatting custom-model-binder

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

我尝试添加自定义模型绑定器并覆盖bindModel函数,但由于Culture已经设置回默认的en-GB,我无法看到如何解决错误。

所以我尝试在我的BaseController中添加一个动作过滤器来设置Culture,但遗憾的是bindModel似乎在我的动作过滤器之前被触发了。

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

模型进入无效的控制器:

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

过滤文化设置的地方:

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;
   }
}

2 个答案:

答案 0 :(得分:3)

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

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

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

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

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

在模型绑定之前调用此方法,因此,您不需要自定义模型绑定器。我希望它适合你:)

答案 1 :(得分:-1)

看看in this article,但简而言之,如果你可以试试这个:

public ActionResult Create(FormCollection values)
{
    Recipe recipe = new Recipe();
    recipe.Name = values["Name"];      

    // ...

    return View();
}

......或者,如果您有型号:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Recipe newRecipe)
{            
    // ...

    return View();
}

本文有完整的参考资料和其他方法。我使用这些2,到目前为止它们对我来说足够了。