小数和整数的自定义模型绑定器:如何在 MVC 之前获取字符串值并进行更智能的转换

发布于 2024-10-22 08:51:06 字数 770 浏览 4 评论 0 原文

我想扩展默认模型绑定,使其在处理数字时更加智能。当游戏中出现逗号和小数点时,默认设置效果非常糟糕。

我正在尝试做一个新的活页夹

Public Class SmartModelBinder
    Inherits DefaultModelBinder
    Protected Overrides Sub SetProperty(controllerContext As ControllerContext, bindingContext As ModelBindingContext, propertyDescriptor As System.ComponentModel.PropertyDescriptor, value As Object)
        If propertyDescriptor.PropertyType Is GetType(Decimal) Or propertyDescriptor.PropertyType Is GetType(Decimal?) Then
            If value Is Nothing Then
                value = 0
            End If
        End If

        MyBase.SetProperty(controllerContext, bindingContext, propertyDescriptor, value)
    End Sub
End Class

,但此时该值已经转换

如何扩展活页夹以从表单获取字符串值并执行不同的转换?

I want to extend the default model binding to be more smart when dealing with numbers. The default works very bad when are commas and decimals points in the game.

I was trying the do a new binder

Public Class SmartModelBinder
    Inherits DefaultModelBinder
    Protected Overrides Sub SetProperty(controllerContext As ControllerContext, bindingContext As ModelBindingContext, propertyDescriptor As System.ComponentModel.PropertyDescriptor, value As Object)
        If propertyDescriptor.PropertyType Is GetType(Decimal) Or propertyDescriptor.PropertyType Is GetType(Decimal?) Then
            If value Is Nothing Then
                value = 0
            End If
        End If

        MyBase.SetProperty(controllerContext, bindingContext, propertyDescriptor, value)
    End Sub
End Class

But the value is already converted at this point

How can I extend the binder to get the string value from the form and perform a different transformation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

囍笑 2024-10-29 08:51:06

这又如何呢?

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder())

还有一个定制的活页夹。我想我不知道您是否可以通过这种方式覆盖十进制绑定,但它适用于我自己的类型。

public class DecimalModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null)
        {
            return base.BindModel(controllerContext, bindingContext);
        }
        // to-do: your parsing (get the text value from valueProviderResult.AttemptedValue)
        return parsedDecimal;
    }
}

What about this?

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder())

And a custom binder. I guess I don't know if you can override decimal binding in this way, but it works for my own types.

public class DecimalModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null)
        {
            return base.BindModel(controllerContext, bindingContext);
        }
        // to-do: your parsing (get the text value from valueProviderResult.AttemptedValue)
        return parsedDecimal;
    }
}
£烟消云散 2024-10-29 08:51:06

您可能正在寻找的方法是BindModel。以下是默认模型绑定器如何工作的高级概述,假设您有以下类:

public class MyModel
{
  public int Id;
  public string Name;
}

当 MVC 尝试将数据绑定到 MyModel 时,它会在默认模型上调用 BindModel粘合剂。该绑定器确定 MyModel 不是“简单”数据类型(即 intdecimalstring 等) 。然后,它取出可以绑定的可能成员,然后为每个类型找到正确的模型绑定器,并针对字段/属性调用该模型绑定器的 BindModel 方法,因此复杂的模型绑定type 实际上是一个递归调用。

通常,我建议只为十进制编写一个模型绑定程序,并将其设置为该数据类型的模型绑定程序,但我听说其他人对此有问题(我自己还没有尝试过)。因此,我会首先尝试,如果这不起作用,则只需在默认模型绑定器的 BindModel 方法中检查该模型类型并处理该特殊情况。

这是模型绑定的极其高级的概述,甚至不会开始表明它是您需要了解的有关该区域如何工作的所有内容。

The method you are probably looking for is BindModel. Here's a high level overview of how the default model binder works, suppose you have the following class:

public class MyModel
{
  public int Id;
  public string Name;
}

When MVC tries to bind data to MyModel, it calls BindModel on the default model binder. That binder determines that MyModel is not a "simple" data type (i.e. int, decimal, string etc). It then pulls out the possible members that it can bind to, then finds the correct model binder for each of those types and calls that model binder's BindModel method against the field/property, so model binding of a complex type is really a recursive call.

Normally I would suggest writing a model binder just for decimal and setting that as the model binder for that data type, but I've heard others have had issue with that (I haven't tried it myself). So I would try that first, and if that doesn't work, then just check for that model type in the BindModel method of your default model binder and handle that special case.

This is an extremely high level overview of model binding and wouldn't even begin to suggest that it's everything you need to know about how that area works.

迷离° 2024-10-29 08:51:06

我添加了一个额外的答案,因为 Phil Haack 最近在博客中详细介绍了如何做到这一点。他警告说它未经测试,但他使用了 ModelState 并在需要时添加了一个错误,这是我从来不知道何时/如何做的事情,所以这对我很有帮助。

以下是他的帖子的链接:http://haacked。 com/archive/2011/03/19/fixing-binding-to-decimals.aspx

I'm adding an additional answer because Phil Haack blogged recently on exactly how to do this. He warns that it is untested, but he makes use of the ModelState and adds an error if needed, which is something I was never aware of when/how to do, so it was helpful to me.

Here's a link to his post: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文