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 )
{
// ...
}