gpt4 book ai didi

asp.net-mvc - asp.net MVC 1.0 和 2.0 货币模型绑定(bind)

转载 作者:行者123 更新时间:2023-12-04 18:16:31 25 4
gpt4 key购买 nike

我想创建模型绑定(bind)功能,以便用户可以输入“,”“。”等用于绑定(bind)到我的 ViewModel 的 double 值的货币值。

我可以通过创建自定义模型绑定(bind)器在 MVC 1.0 中执行此操作,但是自从升级到 MVC 2.0 后,此功能不再起作用。

有没有人有任何想法或更好的解决方案来执行此功能?更好的解决方案是使用一些数据注释或自定义属性。

public class MyViewModel
{
public double MyCurrencyValue { get; set; }
}

一个首选的解决方案是这样的......
public class MyViewModel
{
[CurrencyAttribute]
public double MyCurrencyValue { get; set; }
}

下面是我在 MVC 1.0 中模型绑定(bind)的解决方案。
public class MyCustomModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object result = null;

ValueProviderResult valueResult;
bindingContext.ValueProvider.TryGetValue(bindingContext.ModelName, out valueResult);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueResult);

if (bindingContext.ModelType == typeof(double))
{
string modelName = bindingContext.ModelName;
string attemptedValue = bindingContext.ValueProvider[modelName].AttemptedValue;

string wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;
string alternateSeperator = (wantedSeperator == "," ? "." : ",");

try
{
result = double.Parse(attemptedValue, NumberStyles.Any);
}
catch (FormatException e)
{
bindingContext.ModelState.AddModelError(modelName, e);
}
}
else
{
result = base.BindModel(controllerContext, bindingContext);
}

return result;
}
}

最佳答案

您可以尝试以下方法:

// Just a marker attribute
public class CurrencyAttribute : Attribute
{
}

public class MyViewModel
{
[Currency]
public double MyCurrencyValue { get; set; }
}


public class CurrencyBinder : DefaultModelBinder
{
protected override object GetPropertyValue(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor,
IModelBinder propertyBinder)
{
var currencyAttribute = propertyDescriptor.Attributes[typeof(CurrencyAttribute)];
// Check if the property has the marker attribute
if (currencyAttribute != null)
{
// TODO: improve this to handle prefixes:
var attemptedValue = bindingContext.ValueProvider
.GetValue(propertyDescriptor.Name).AttemptedValue;
return SomeMagicMethodThatParsesTheAttemptedValue(attemtedValue);
}
return base.GetPropertyValue(
controllerContext,
bindingContext, propertyDescriptor,
propertyBinder
);
}
}

public class HomeController: Controller
{
[HttpPost]
public ActionResult Index([ModelBinder(typeof(CurrencyBinder))] MyViewModel model)
{
return View();
}
}

更新:

这是对活页夹的改进(参见前面代码中的 TODO 部分):
if (!string.IsNullOrEmpty(bindingContext.ModelName))
{
var attemptedValue = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName).AttemptedValue;
return SomeMagicMethodThatParsesTheAttemptedValue(attemtedValue);
}

为了处理集合,您需要在 Application_Start 中注册活页夹。因为您将无法再使用 ModelBinderAttribute 来装饰列表:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(MyViewModel), new CurrencyBinder());
}

然后您的操作可能如下所示:
[HttpPost]
public ActionResult Index(IList<MyViewModel> model)
{
return View();
}

总结重要部分:
bindingContext.ValueProvider.GetValue(bindingContext.ModelName)

此绑定(bind)器的进一步改进步骤是处理验证(AddModelError/SetModelValue)

关于asp.net-mvc - asp.net MVC 1.0 和 2.0 货币模型绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2453591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com