Asp.net mvc 在模型绑定时获取参数的自定义属性

Asp.net mvc 在模型绑定时获取参数的自定义属性,asp.net-mvc,c#-4.0,model-binding,Asp.net Mvc,C# 4.0,Model Binding,我看过很多类似的帖子,但是没有找到控制器参数的答案 我编写了一个名为AliasAttribute的自定义属性,它允许我在模型绑定期间为参数定义别名。因此,例如,如果我在服务器上有:public-JsonResult-EmailCheck(string-email),并且我希望将email参数绑定到名为PrimaryEmail或SomeCrazyEmail的字段,我可以使用以下别名属性来“映射”它:public-JsonResult-EmailCheck([Alias(Suffix=“email”

我看过很多类似的帖子,但是没有找到控制器
参数的答案

我编写了一个名为
AliasAttribute
的自定义属性,它允许我在模型绑定期间为参数定义别名。因此,例如,如果我在服务器上有:
public-JsonResult-EmailCheck(string-email)
,并且我希望将
email
参数绑定到名为PrimaryEmail或SomeCrazyEmail的字段,我可以使用以下别名属性来“映射”它:
public-JsonResult-EmailCheck([Alias(Suffix=“email”)]string-email)

问题:在我的自定义模型活页夹中,我无法获得应用于
email
参数的
AliasAttribute
类。它总是返回null。 我已经看到DefaultModelBinder类是如何在reflector中获取BindAttribute的,它是相同的,但对我不起作用

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

Alias ModelBinder:

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;
    }
}
别名属性:

[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>();
    }
}

放弃了这个,然后偶然发现了可能允许我这么做的代码库。它不像我开始写的那样灵活,但可能可以修改以允许通配符。

我所做的是使属性子类
System.Web.Mvc.CustomModelBinderAttribute
,然后允许您返回使用别名修改的自定义模型绑定器版本

例如:

public class AliasAttribute : System.Web.Mvc.CustomModelBinderAttribute
{
    public AliasAttribute()
    {
    }

    public AliasAttribute( string alias )
    {
        Alias = alias;
    }

    public string Alias { get; set; }

    public override IModelBinder GetBinder()
    {
        var binder = new AliasModelBinder();

        if ( !string.IsNullOrEmpty( Alias ) )
            binder.Alias = Alias;

        return binder;
    }
}
然后允许这种用法:

public ActionResult Edit( [Alias( "somethingElse" )] string email )
{
    // ...
}
public ActionResult Edit( [Alias( "somethingElse" )] string email )
{
    // ...
}