2012-11-24 14 views
6

से एक जटिल ऑब्जेक्ट पुनर्प्राप्त करें मैं एक एमवीसी प्रोजेक्ट पर काम कर रहा हूं जहां नियंत्रक क्रियाएं संपत्तियों से निपटती हैं। विभिन्न नियंत्रकों अलग तरीके से assetid पैरामीटर में ले: कुछ नियंत्रकों बस int assetId, अन्य int id मिलता है, और अन्य एक जटिल वस्तु AssetDTO dtoएक्शन पैरामीटर

मैं एक ActionFilter कि में जोड़ा जाता है लिख रहा हूँ (जो एक संपत्ति है कि assetid रखती शामिल हैं) का उपयोग करते हुए एक्शन विधि और एक्शन पैरामीटर नाम के साथ प्रदान किया जाता है जहां मुझे संपत्ति मूल्य मिल सकता है।

कार्रवाई विधि:

[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 एक आदिम रूप में प्रदान की जाती है काम करेंगे। मुझे यकीन नहीं है कि जब परिसंपत्ति आईडी को जटिल विधि में क्रिया विधि में प्रदान किया जाता है तो क्या करना है।

क्या मुझे इस प्रकार के आधार पर अलग-अलग ऑब्जेक्ट को अलग करने की आवश्यकता होगी? मुझे आशा है कि मैं AssetIdFilter में किसी प्रकार का डॉट-नोटेशन निर्दिष्ट कर सकता हूं ताकि यह कह सके कि संपत्ति कहाँ स्थित है: 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

ठीक है, हाँ, आपने अपने प्रश्न का उत्तर दिया। एक तरह से डॉट संकेतन का उपयोग करने के लिए होगा:

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

कोड अशक्त चेकों नहीं है जब ToString बुला और हालांकि जब GetProperty बुला:

//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 इस प्रकार है। इसके अलावा, यह TryParse की सफलता की जांच नहीं करता है। उपयोग किए जाने पर इन सुधारों को लागू करें।

शायद यह कोड dynamic का उपयोग करके लिखा जा सकता है, लेकिन अंत में dynamic उपयोग प्रतिबिंब (कुछ मैंने यहां किया है) का उपयोग करके ऑब्जेक्ट में संकलित किया गया है, इस प्रकार मेरे लिए कोई बड़ा अंतर नहीं है।

इसके अलावा, शायद "idObj.SubObj.id" जैसे पैरामीटर होने के लिए यह और अधिक स्पष्ट होगा, लेकिन यह फिर से वरीयता पर निर्भर करता है, और कोड थोड़ा अधिक जटिल हो जाएगा।

संबंधित मुद्दे