gpt4 book ai didi

asp.net-mvc - 如何从自定义 ModelBinder 中调用 UpdateModel? (MVC)

转载 作者:行者123 更新时间:2023-12-02 02:32:36 25 4
gpt4 key购买 nike

我正在为我的模型中的复杂类型创建一些自定义绑定(bind)器。我的模型由具有自己独立的 Binder 的对象组成。我希望基础对象完成它的肮脏工作,然后通过传递给标准 ModelBinder 路由来填充它封装的复杂对象。我该怎么做?

为了便于说明,我创建了一个非常简单的示例。

假设我的模型包含这些对象。

public class Person
{
public string Name {get; set;}
public PhoneNumber PhoneNumber {get; set;}
}

public class PhoneNumber
{
public string AreaCode {get; set;}
public string LocalNumber {get; set;}
}

我为这些模型中的每一个都准备了以下 Binder 。并不是说 PersonBinder 需要填充 PhoneNumber 但不想复制 PhoneNumber Binder 中的代码。它如何委托(delegate)回标准的Binder路由?

public class PersonBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Person person = new Person();
person.Name = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "Name")).AttemptedValue

// This is where I'd like to have the PhoneNumber object use binding from another customer ModelBinder.
// Of course the bindingContext.ModelName should be updated to its current value + "PhoneNumber"
person.PhoneNumber = ???; // I don't want to explicitly call the PhoneNumberBinder it should go through standard Binding routing. (ie. ModelBinders.Binders[typeof(PhoneNumber)] = new PhoneNumberBinder();)

return person;
}
}

public class PhoneNumberBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
PhoneNumber phoneNumber = new PhoneNumber();
phoneNumber.AreaCode = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "AreaCode")).AttemptedValue
phoneNumber.LocalNumber = bindingContext.ValueProvider.GetValue(String.Format("{0}.{1}", bindingContext.ModelName, "LocalNumber")).AttemptedValue

return phoneNumber;
}
}

当然,我已经在 Global.asax.cs 文件中注册了我的 ModelBinders。

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterRoutes(RouteTable.Routes);

ModelBinders.Binders[typeof(Person)] = new PersonBinder();
ModelBinders.Binders[typeof(PhoneNumber)] = new PhoneNumberBinder();
}

谢谢,

贾斯汀

最佳答案

好吧,我想出了一个解决方案。请随时对其有效性发表评论。

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Person person = new Person();
person.Name = bindingContext.ValueProvider.GetValue("Name").AttemptedValue

if (bindingContext.ModelName == String.Empty)
{
bindingContext.ModelName = "PhoneNumber";
}
else
{
bindingContext.ModelName = bindingContext.ModelName + ".PhoneNumber";
}

PhoneNumber phoneNumber = new PhoneNumber();
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => phoneNumber, phoneNumber.GetType());

IModelBinder binder = ModelBinders.Binders[typeof(PhoneNumber)];
if (binder == null)
{
binder = ModelBinders.Binders.DefaultBinder;
}

person.PhoneNumber = binder.BindModel(controllerContext, bindingContext) as PhoneNumber;

return person;
}

这是我所做的总结。

  1. 使用可全局访问的 ModelBinders.Binders 集合查找 ModelBinder(如果未注册则回退到默认值)
  2. 为我绑定(bind)到的模型创建 ModelMetadataProvider。
  3. 将 bindingContext 的 ModelName 属性设置为我要填充的模型属性(“PhoneNumber”)。

关于asp.net-mvc - 如何从自定义 ModelBinder 中调用 UpdateModel? (MVC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3183931/

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