2012-11-24 88 views
6

我正在處理控制器操作處理資產的MVC項目。不同的控制器採取不同的方式,由assetid參數:有些控制器簡單地得到int assetId,其他int id,並使用複雜的對象AssetDTO dto(其中包含持有由assetid屬性)從ActionParameters檢索複雜的對象

我寫的是被添加到一個ActionFilter其他動作方法,並提供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提供給action方法時該怎麼做。

我需要根據類型分別解析每個對象嗎?我希望我可以在AssetIdFilter中指定某種點符號來告訴它assetid所在的位置:dto.assetId

任何我可以使用動態的方法?或反思?等。???

回答

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如下:調用ToString,並呼籲GetProperty時儘管當

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

的代碼沒有null檢查。此外,它不檢查TryParse的成功。使用時請使用這些更正。

也許這個代碼可以使用dynamic來寫,但最後dynamic用法被編譯成使用反射的對象(就像我在這裏所做的一樣),因此對我來說沒有太大的區別。

此外,也許它會更清楚有一個參數,如「idObj.SubObj.id」,但這又取決於首選項,並且代碼將變得一點點更復雜。