2013-08-16 2 views
2

Я видел много похожих сообщений по этому вопросу, но не нашел ответа, специфичного для контроллера parameters.Получить пользовательский атрибут для параметра при привязке модели

Я написал собственный атрибут под названием AliasAttribute, который позволяет мне определять псевдонимы параметров во время привязки модели. Так, например, если у меня есть: public JsonResult EmailCheck(string email) на сервере, и я хочу, чтобы параметр email быть связанным с полями имени PrimaryEmail или SomeCrazyEmail Я «карта» это с помощью aliasattribute так: public JsonResult EmailCheck([Alias(Suffix = "Email")]string email).

Проблемы: В моей пользовательской модели вяжущий я не могу ухватить в AliasAttribute класса применяется к параметру email. Он всегда возвращает null. Я видел, что класс DefaultModelBinder делает, чтобы получить BindAttribute в отражателе и его же, но не работает для меня.

Вопрос: Как получить этот атрибут во время привязки?

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:

[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 
} 

ответ

0

Бросил на это, а потом наткнулся на базу кода Action Parameter Alias, что, вероятно, позволит мне делать это. Это не так гибко, как то, что я начал писать, но, вероятно, может быть изменен, чтобы позволить дикие карты.

0

то, что я сделал, было моим подклассом атрибутов 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) 
{ 
    // ... 
} 
Смежные вопросы