加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-4 – 下划线字符串模型绑定器

发布时间:2020-12-16 07:33:04 所属栏目:asp.Net 来源:网络整理
导读:我的印象是,当绑定到复杂模型时,处理所有公共属性并尝试对每个属性进行匹配绑定. 我正在尝试解决变量命名问题以便建模 class Model { public string Foo {get;set;} public string FooBar {get;set;}} 与查询字符串很好地配合使用 ?foo=foofoo_bar=foo_bar
我的印象是,当绑定到复杂模型时,处理所有公共属性并尝试对每个属性进行匹配绑定.

我正在尝试解决变量命名问题以便建模

class Model {
      public string Foo {get;set;}
      public string FooBar {get;set;}
}

与查询字符串很好地配合使用

?foo=foo&foo_bar=foo_bar

有没有比自定义模型绑定器更好的方法?无论如何,我的工作不起作用.简单地跳过了FooBar.

public class StringModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)
        {
            var model = base.BindModel(controllerContext,bindingContext);

            if (model != null)
                return model;

            var modelName = Regex.Replace(bindingContext.ModelName,"([a-z])([A-Z])","$1_$2").ToLowerInvariant();

            var value = bindingContext.ValueProvider.GetValue(modelName);

            return value;
        }

    }

注册

ModelBinders.Binders.Add(typeof(string),new StringModelBinder());

解决方法

I was under the impression that when binding to a complex model,all
public properties were processed and a match binding attempted for
each.

不,这是一个错误的印象.默认模型绑定器将尝试仅绑定在Request中具有相应值的属性.在您的情况下,您没有FooBar属性的相应值,因此它不会被绑定.

实际上,如果我们能写出来会很好:

public class Model
{
    public string Foo { get; set; }

    [ParameterName("foo_bar")]
    public string FooBar { get; set; }
}

所以让我们实现这一点.我们首先编写一个基本属性:

[AttributeUsageAttribute(AttributeTargets.Property)]
public abstract class PropertyBinderAttribute : Attribute,IModelBinder
{
    public abstract object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext);
}

和自定义模型绑定器:

public class CustomModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext,ModelBindingContext bindingContext,PropertyDescriptor propertyDescriptor)
    {
        var propertyBinderAttribute = propertyDescriptor
            .Attributes
            .OfType<PropertyBinderAttribute>()
            .FirstOrDefault();

        if (propertyBinderAttribute != null)
        {
            var value = propertyBinderAttribute.BindModel(controllerContext,bindingContext);
            propertyDescriptor.SetValue(bindingContext.Model,value);
        }
        else
        {
            base.BindProperty(controllerContext,bindingContext,propertyDescriptor);
        }
    }
}

如您所见,此自定义模型分析模型的元数据,如果使用PropertyBinderAttribute的实例修饰属性,它将使用它.

然后,我们将使用Application_Start中的自定义模型绑定器替换默认模型绑定器:

ModelBinders.Binders.DefaultBinder = new CustomModelBinder();

现在剩下的就是实现我们用来装饰我们的模型属性的ParameterNameAttribute绑定器:

public class ParameterNameAttribute : PropertyBinderAttribute
{
    private readonly string parameterName;
    public ParameterNameAttribute(string parameterName)
    {
        this.parameterName = parameterName;
    }

    public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(this.parameterName);
        if (value != null)
        {
            return value.AttemptedValue;
        }
        return null;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读