2012-11-24 14 views
6

コントローラアクションがAssetsを処理するMVCプロジェクトで作業しています。異なるコントローラは、異なる方法でassetIdパラメータに取る:一部のコントローラには、単に私がに追加されたのActionFilterを書いています(assetIdを保持しているプロパティを含む)複雑なオブジェクトAssetDTO dtoActionParametersから複雑なオブジェクトを取得します。

を使用してint assetId、他のint id、およびその他の取得しますこのアクションメソッドにはactionParameter名が与えられ、そこで私は資産価値を得ることができます。

アクションメソッド:

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

属性は次のように定義されます

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

予想通りこれは動作しますが、assetIdはプリミティブとして提供されている場合のみ動作します。 assetIdが複雑なオブジェクト内でアクションメソッドに提供されているときに何をすべきかわかりません。

タイプごとにオブジェクトを別々に解析する必要がありますか?私はAssetIdFilterで何らかのドット表記法を指定して、assetIdがどこにあるかを指定することができます:dto.assetId

どのようにしてダイナミクスを使用できますか?または反射?? ect。???

答えて

7

、ここダイナミックはrescue.youに来るようにactionFilterAttributeを変更することができます。

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

歓声!

0

あなたの質問に答えました。一つの方法は、ドット表記を使用することです:次のように

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

そしてAssetIdAttributeは次のとおりです。

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

しかしGetPropertyを呼び出すときにToStringを呼び出し、時にコードがnullチェックを持っていません。また、TryParseの成功をチェックしません。これらの補正は、使用するときに適用してください。

dynamicを使ってこのコードを書くことができるかもしれませんが、最後にdynamicというリフレクションを使用してオブジェクトにコンパイルされます(これは私がここで行ったようなものです)。

また、 "idObj.SubObj.id"のようなパラメータを持つことがより明確になるかもしれませんが、これもやはり設定に依存し、コードは少し複雑になるになります。

関連する問題