2013-01-02 29 views
15

मैं जैसे एक API करना चाहते हैं:क्या मैं एक एमवीसी 4 वेबएपी पोस्ट पर इंटरफ़ेस आधारित ऑब्जेक्ट पास कर सकता हूं?

public class RelayController : ApiController 
{ 
    // POST api/values 
    public void Post([FromBody]IDataRelayPackage package) 
    { 
     MessageQueue queue = new MessageQueue(".\\private$\\DataRelay"); 
     queue.Send(package); 
     queue.Close(); 
    } 
} 

मैं 'पैकेज' के लिए एक शून्य मान हो रही है तो मैं सोच रहा हूँ क्या गलत हो रहा हो सकता है। मेरा एकमात्र विचार यह है कि डिफ़ॉल्ट JSON सीरिएलाइज़र इसे संभाल नहीं सकता है, लेकिन मुझे स्पष्ट नहीं है कि इसे कैसे ठीक किया जाए।

+0

समय के हित में, मैंने एक्सएमएल युक्त स्ट्रिंग को स्वीकार करने के लिए अपने वेबएपीआई पोस्ट को बदलने का फैसला किया है। मैं इस पर वापस सर्कल करने की योजना बना रहा हूं। –

उत्तर

14

आप कस्टम मॉडल बाइंडर के साथ यह काफी आसानी से कर सकते हैं। यहां मेरे लिए क्या काम किया है। (वेब एपीआई 2 और JSON.Net 6 का उपयोग करना)

public class JsonPolyModelBinder : IModelBinder 
{ 
    readonly JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; 

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     var content = actionContext.Request.Content; 
     string json = content.ReadAsStringAsync().Result; 
     var obj = JsonConvert.DeserializeObject(json, bindingContext.ModelType, settings); 
     bindingContext.Model = obj; 
     return true; 
    } 
} 

वेब एपीआई नियंत्रक इस तरह दिखता है। (नोट: भी नियमित रूप से MVC कार्यों के लिए काम करना चाहिए - मैं भी पहले उनके लिए कुछ इस तरह से किया है।)

public class TestController : ApiController 
{ 
    // POST api/test 
    public void Post([ModelBinder(typeof(JsonPolyModelBinder))]ICommand command) 
    { 
     ... 
    } 
} 

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

JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; 
    string json = JsonConvert.SerializeObject(command, typeof(ICommand), settings); 
+0

यह बहुत ही बढ़िया है और जेएसओएन सेवा फैक्ट्री इंटरफेस ओवरलोड किए गए हैं। धन्यवाद! –

+1

इसके अतिरिक्त, JSON.Net अपरिवर्तनीय संदेशों (कोई सार्वजनिक सेटर्स) को बेकार कर सकता है जब तक कि आपकी संपत्ति के नाम आपके कन्स्ट्रक्टर पैरामीटर (केस असंवेदनशील) से मेल खाते हैं। –

+0

आखिरकार, मैंने फैसला किया कि मेरे पोस्ट एक्शन को पैरामीटर के साथ रखना आसान था और कार्रवाई के हिस्से के रूप में पोस्ट बॉडी को deserialize। इस तरह मैं अपवादों को नियंत्रित कर सकता हूं या जो भी मैं करना चाहता हूं। –

3

आप एक इंटरफ़ेस को deserialise करने की कोशिश कर रहे हैं। धारावाहिक को पता नहीं चलेगा कि इसे तब तक तत्काल नहीं किया जाए जब तक यह बताया न जाए।

TypeNameHandling विकल्प Posting a collection of subclasses

पर एक नजर डालें या एक कस्टम JsonConverter बनाने को देखो। इस प्रश्न पर एक नज़र डालें How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?

1

धारावाहिक को एक प्रकार की आवश्यकता होती है जिसे वह बना सकता है, एक खाली (डिफ़ॉल्ट) कन्स्ट्रक्टर वाला। चूंकि एक इंटरफ़ेस का निर्माण नहीं किया जा सकता है, इसलिए क्रमबद्धता विफल हो जाती है और आपको शून्य मान मिलता है।

दो विकल्प:

  1. एक POCO (प्लेन ओल्ड Clr वस्तु) का प्रयोग करें एक डिफ़ॉल्ट निर्माता
  2. Implement your own binder using IActionValueBinder
3

Json.NET (ASP.NET वेब एपीआई के लिए डिफ़ॉल्ट Json serializer साथ) इस स्थिति को संभाल सकता है। आपको बस इतना करना है कि serializer सेटिंग्स को बदलें, और TypeNameHandling को सभी (या ऑब्जेक्ट्स) पर सेट करें। यह आपके जेसन में "$ type" -json प्रॉपर्टी जोड़ देगा, जिसमें आपके इंस्टेंस का प्रकार नाम होगा। दूसरी तरफ यह इस प्रकार फिर से deserialize करने की कोशिश करेंगे।

हमने इसे अपने लिए इस्तेमाल किया, एक सार आधार वर्ग को प्रकार के रूप में लिया।

+0

जब आप कहते हैं "धारावाहिक सेटिंग्स बदलें", तो मैं यह कहां करूं? –

+0

@ डेविड कॉर्नल्सन यह मेरे उत्तर में दिए गए लिंक में दिखाया गया है http://stackoverflow.com/questions/12858748/asp-net-webapi-posting-collection-of-subclasses –