2013-10-29 4 views
5

मेरे पास एक कक्षा है जो इंटरफ़ेस से विरासत में मिली है, और मैं अपने वेब एपीआई से इंटरफ़ेस लौट रहा हूं, समस्या है कि मुझे विरासत वर्ग के मान जेसन स्ट्रिंग के रूप में मिल रहा है।क्यों वेब एपीआई विधि में इंटरफ़ेस लौटाते हैं, तो मुझे इंटरफ़ेस मानों के साथ विरासत कक्षा के मान मिलते हैं?

यह इंटरफ़ेस

public interface IFoo 
    { 
    string A { get ;set ; } 
    string B { get ; set ; } 
    } 

विरासत में प्राप्त कक्षा

public class Child : iFoo 
    { 
    string A { get ; set ; } 
    string B { get ; set ; } 
    string C { get ; set ; } 
    string D { get ; set ; } 
    } 

तब मैं अपने नियंत्रक के GetMethod

public IFoo GetIFoo() 
     { 
     return ChildInstance ; 
     } 

वर्तमान परिणाम दे से IFoo वापसी है मुझे विरासत वर्ग के सभी मूल्य, और दोनों इंटरफ़ेस हैं, लेकिन मुझे केवल वे मान चाहिए जो जेसन परिणाम में इंटरफ़ेस में कार्यान्वित किए गए हैं।

उत्तर

5

जब तक यह जेसन सीरियलाइज़र को हिट करता है, तो यह परवाह नहीं करता कि विधि का रिटर्न प्रकार क्या था। यह सब जानता है कि "मेरे पास यह वस्तु है, चलो देखते हैं कि मैं इसके साथ क्या कर सकता हूं"।

यदि आप चाहते हैं कि धारावाहिक केवल आपके इंटरफ़ेस के गुणों को शामिल करे, तो आप इसे एक ऑब्जेक्ट दें जिससे केवल आपके इंटरफ़ेस में गुण हों। आप उदाहरण का उपयोग करने पर विचार कर सकते हैं इस नए ऑब्जेक्ट में ChildInstance से मूल्यों की प्रतिलिपि बनाने के लिए ऑटोमैपर।

विकल्प अधिक जटिल है - अपने स्वयं के धारावाहिक को कार्यान्वित करना ताकि जेसन सीरियलाइज़र को शामिल होने का मौका न मिले।

+0

आप थोड़ा जटिल विधि के बारे में विस्तार से बता या कुछ उदाहरण के लिए एक लिंक भेज सकते हैं। .. – Mortalus

2

आपकी विधि को उस ऑब्जेक्ट को वापस करने के लिए अनुबंधित किया गया है जो IFoo लागू करता है। यह किसी भी ऑब्जेक्ट को वापस कर सकता है जो IFoo लागू करता है, लेकिन Ifoo खुद को वापस नहीं कर सकता क्योंकि आपके पास इंटरफ़ेस का उदाहरण नहीं हो सकता है। तो यह Child का एक उदाहरण देता है।

JSON serializer को Child का यह उदाहरण दिया गया है और इसके गुणों को पूरा करने के लिए प्रतिबिंब का उपयोग करता है। यह A - D पाता है और इसलिए उन्हें क्रमबद्ध करता है।

यदि आप केवल A - B क्रमबद्ध करना चाहते हैं, तो आपको केवल उस कक्षा का एक उदाहरण वापस करना होगा जो केवल A - B लागू करता है।

यह सब कहकर, यदि आप एएसपी एमवीसी का उपयोग कर रहे हैं, तो http://www.creave.dk/post/2009/10/07/Excluding-properties-from-being-serialized-in-ASPNET-MVC-JsonResult.aspx देखें।

public class Child : iFoo 
{ 
    string A { get ; set ; } 
    string B { get ; set ; } 

    [ScriptIgnore] 
    string C { get ; set ; } 
    [ScriptIgnore] 
    string D { get ; set ; } 
} 

करने के लिए अपने वर्ग परिभाषा बदलकर तो फिर तुम JSON serializer निर्देश दिए हैं करने के लिए केवल A - B serialise।

0

आप गतिशील लौटने कोई आपत्ति नहीं है, तो आप कुछ इस तरह करते हैं:

दूसरा पहलू है कि यह केवल तरीके से काम करता है अगर आप, json serializer उपयोग करें ताकि आप "स्वीकार निर्दिष्ट करने के लिए है: आवेदन/जेसन "इसके लिए काम करने के लिए।

public class Person 
{ 
    public string Name { get; set; } 
} 

public class User : Person 
{ 
    public string Title { get; set; } 
    public string Email { get; set; } 
} 

public dynamic Get() 
{ 
    var user = new User { Title = "Developer", Email = "[email protected]", Name = "MyName" }; 

    return new { user.Name, user.Email }; 
} 
0

यदि नियंत्रक विधि का रिटर्न प्रकार एक इंटरफ़ेस है तो आप केवल इंटरफ़ेस गुणों को क्रमबद्ध करने के लिए एक्शन फ़िल्टर भी लागू कर सकते हैं।इंटरफ़ेस को लागू करने वाले वर्ग पर किसी भी विशेषता को बदलने के बिना आप हमेशा अपनी इंटरफ़ेस परिभाषा के साथ सिंक में रहते हैं।

इसके लिए

आप पहली बार के रूप में समझाया here एक कस्टम InterfaceContractResolver अनुबंध समाधानकर्ता बनाने के लिए चाहते हैं:

public class InterfaceContractResolver : DefaultContractResolver 
    { 
     private readonly Type _interfaceType; 
     public InterfaceContractResolver(Type interfaceType) 
     { 
      _interfaceType = interfaceType; 
     } 

     protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
     { 
      IList<JsonProperty> properties = base.CreateProperties(_interfaceType, memberSerialization); 
      return properties; 
     } 
    } 

तो (या तो के रूप में समझाया here विशेषता के रूप में या विश्व स्तर पर आप एक के रूप में इस चाहते हैं, तो एक कार्रवाई फ़िल्टर जोड़ें डिफ़ॉल्ट व्यवहार) कि नियंत्रक विधि की वापसी प्रकार को देखता है और अगर यह एक अंतरफलक अनुबंध समाधानकर्ता ऊपर परिभाषित का उपयोग करता है:

public class InterfaceFilterAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
     { 
      ObjectContent content = actionExecutedContext.Response.Content as ObjectContent; 
      if (content != null) 
      { 
       Type returnType = actionExecutedContext.ActionContext.ActionDescriptor.ReturnType; 
       if (returnType.IsInterface && content.Formatter is JsonMediaTypeFormatter) 
       { 
        var formatter = new JsonMediaTypeFormatter 
         { 
          SerializerSettings = 
           { 
            ContractResolver = new InterfaceContractResolver(returnType) 
           } 
         }; 
        actionExecutedContext.Response.Content = new ObjectContent(content.ObjectType, content.Value, formatter); 
       } 
      } 
     } 
    } 
संबंधित मुद्दे