2012-11-24 5 views
6

Je travaille sur un projet MVC où les actions du contrôleur concernent les ressources. Différents contrôleurs prennent dans le paramètre assetId de manière différente: Certains contrôleurs simplement obtenir int assetId, d'autres int id, et d'autres à l'aide d'un objet complexe AssetDTO dto (qui contient une propriété qui détient le assetId)Récupérer un objet complexe à partir d'ActionParameters

Je suis en train d'écrire un ActionFilter qui est ajouté à la méthode d'action et est fourni avec le nom d'actionParameter où je peux obtenir la valeur de l'actif.

Méthode d'action:

[AssetIdFilter("assetId")] 
    public ActionResult Index(int assetId) 
    { 
      ... 
    } 

L'attribut est défini comme:

public class AssetIdFilterAttribute : ActionFilterAttribute 
{ 
    public string _assetIdParameterKey { get; set; } 

    public AssetIdFilterAttribute (string assetIdParameterKey) 
    { 
     _assetIdParameterKey = assetIdParameterKey; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     int assetId; 
     if (Int32.TryParse(filterContext.ActionParameters[_assetIdParameterKey].ToString(), out assetId)) 
     { 
        ...... 
     } 
    } 

Cela fonctionne comme prévu, mais ne fonctionnera que lorsque le assetId est fourni primitive. Je ne suis pas sûr que faire quand assetId est fourni dans un objet complexe dans la méthode d'action. Dois-je analyser chaque objet différemment selon le type? J'espère que je peux spécifier une sorte de notation de point dans le AssetIdFilter pour indiquer où l'assetId est localisé: dto.assetId

N'importe quelle manière je peux employer la dynamique? ou réflexion? ect. ???

Répondre

7

et ici dynamique vient au rescue.you peut changer le ActionFilterAttribute être:

 public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      dynamic assetIdHolder = filterContext.ActionParameters[_assetIdParameterKey]; 
      if (assetIdHolder.GetType().IsPrimitive) 
      { 
       //do whatever with assetIdHolder    
      } 
      else 
      { 
       //do whatever with assetIdHolder.assetId 
      } 
     } 

acclamations!

0

Eh bien, oui, vous avez répondu à votre question. Un moyen serait d'utiliser la notation dot:

//simple case: 
[AssetId("id")] 
public ActionResult Index(string id) { 
    //code here 
} 

//complex case: 
[AssetId("idObj", AssetIdProperty = "SubObj.id")] 
public ActionResult index(IdObject idObj) { 
    //code here 
} 

Et AssetIdAttribute est la suivante:

public class AssetIdAttribute : ActionFilterAttribute 
{ 
    public string _assetIdParameterKey { get; set; } 

    public string AssetIdProperty { get; set; } 

    public AssetIdFilterAttribute(string assetIdParameterKey) 
    { 
     _assetIdParameterKey = assetIdParameterKey; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     int assetId; 
     var param = filterContext.ActionParameters[_assetIdParameterKey]; 
     int.TryParse(GetPropertyValue(param, this.AssetIdProperty).ToString(), out assetId); 
     //you code continues here. 
    } 

    private static string GetPropertyValue(object souce, string property) 
    { 
     var propNames = string.IsNullOrWhiteSpace(property) || !property.Contains('.') ? new string[] { } : property.Split('.'); 
     var result = souce; 
     foreach (var prop in propNames) 
     { 
      result = result.GetType().GetProperty(prop).GetValue(result); 
     } 
     return result.ToString(); 
    } 
} 

Le code ne pas vérifie null lors de l'appel ToString et lors de l'appel GetProperty bien. En outre, il ne vérifie pas le succès de TryParse. S'il vous plaît appliquer ces corrections lorsqu'il est utilisé.

Peut-être que ce code pourrait être écrit en utilisant dynamic, mais à la fin dynamic utilisation est compilé en objet en utilisant la réflexion (quelque chose comme ce que j'ai fait ici), donc pas de grande différence pour moi.

En outre, il serait peut-être plus clair d'avoir un paramètre comme « idObj.SubObj.id », mais cela dépend encore une fois la préférence, et le code deviendra un peu plus complexe.

Questions connexes