模型绑定时获取参数的自定义属性 [英] Get custom attribute for parameter when model binding

查看:69
本文介绍了模型绑定时获取参数的自定义属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了很多类似的帖子,但是还没有找到控制器parameters的特定答案.

I've seen a lot of similar posts on this, but haven't found the answer specific to controller parameters.

我编写了一个名为AliasAttribute的自定义属性,该属性使我可以在模型绑定期间为参数定义别名.因此,例如,如果我在服务器上具有:public JsonResult EmailCheck(string email),并且希望将email参数绑定到名为 PrimaryEmail SomeCrazyEmail 的字段,则可以映射"此字段使用别名属性,如下所示:public JsonResult EmailCheck([Alias(Suffix = "Email")]string email).

I've written a custom attribute called AliasAttribute that allows me to define aliases for parameters during model binding. So for example if I have: public JsonResult EmailCheck(string email) on the server and I want the email parameter to be bound to fields named PrimaryEmail or SomeCrazyEmail I can "map" this using the aliasattribute like this: public JsonResult EmailCheck([Alias(Suffix = "Email")]string email).

问题:在我的自定义模型活页夹中,我无法保留应用到email参数的AliasAttribute类.它始终返回null. 我已经看到 DefaultModelBinder 类正在做些什么,以在反射器中获取 BindAttribute ,该类相同但对我不起作用.

The problem: In my custom model binder I can't get a hold of the AliasAttribute class applied to the email parameter. It always returns null. I've seen what the DefaultModelBinder class is doing to get the BindAttribute in reflector and its the same but doesn't work for me.

问题:如何在绑定期间获取此属性?

Question: How do I get this attribute during binding?

AliasModelBinder:

AliasModelBinder:

public class AliasModelBinder : DefaultModelBinder
{
    public static ICustomTypeDescriptor GetTypeDescriptor(Type type)
    {
        return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = base.BindModel(controllerContext, bindingContext);

        var descriptor = GetTypeDescriptor(bindingContext.ModelType);
        /*************************/
        // this next statement returns null!
        /*************************/
        AliasAttribute attr = (AliasAttribute)descriptor.GetAttributes()[typeof(AliasAttribute)];

        if (attr == null)
            return null;

        HttpRequestBase request = controllerContext.HttpContext.Request;

        foreach (var key in request.Form.AllKeys)
        {
            if (string.IsNullOrEmpty(attr.Prefix) == false)
            {
                if (key.StartsWith(attr.Prefix, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (string.IsNullOrEmpty(attr.Suffix) == false)
                    {
                        if (key.EndsWith(attr.Suffix, StringComparison.InvariantCultureIgnoreCase))
                        {
                            return request.Form.Get(key);
                        }
                    }
                    return request.Form.Get(key);
                }
            }
            else if (string.IsNullOrEmpty(attr.Suffix) == false)
            {
                if (key.EndsWith(attr.Suffix, StringComparison.InvariantCultureIgnoreCase))
                {
                    return request.Form.Get(key);
                }
            }
            if (attr.HasIncludes)
            {
                foreach (var include in attr.InlcludeSplit)
                {
                    if (key.Equals(include, StringComparison.InvariantCultureIgnoreCase))
                    {
                        return request.Form.Get(include);
                    }
                }
            }
        }
        return null;
    }
}

AliasAttribute:

AliasAttribute:

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class AliasAttribute : Attribute
{
    private string _include;
    private string[] _inlcludeSplit = new string[0];

    public string Prefix { get; set; }
    public string Suffix { get; set; }
    public string Include
    {
        get
        {
            return _include;
        }
        set
        {
            _include = value;
            _inlcludeSplit = SplitString(_include);
        }
    }
    public string[] InlcludeSplit
    {
        get
        {
            return _inlcludeSplit;
        }
    }
    public bool HasIncludes { get { return InlcludeSplit.Length > 0; } }


    internal static string[] SplitString(string original)
    {
        if (string.IsNullOrEmpty(original))
        {
            return new string[0];
        }
        return (from piece in original.Split(new char[] { ',' })
                let trimmed = piece.Trim()
                where !string.IsNullOrEmpty(trimmed)
                select trimmed).ToArray<string>();
    }
}

用法:

public JsonResult EmailCheck([ModelBinder(typeof(AliasModelBinder)), Alias(Suffix = "Email")]string email)
{
    // email will be assigned to any field suffixed with "Email". e.g. PrimaryEmail, SecondaryEmail and so on
}

推荐答案

对此进行讨论,然后偶然发现

Gave up on this and then stumbled across the Action Parameter Alias code base that will probably allow me to do this. It's not as flexible as what I started out to write but probably can be modified to allow wild cards.

这篇关于模型绑定时获取参数的自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆