2013-11-20 11 views
5

इस प्रकार मैं एक ग्राहक से एक वेब एपीआई विधि करने के लिए पोस्ट करने के लिए कोशिश कर रहा हूँ:पोस्ट

// Create list of messages that will be sent 
IEnumerable<IMessageApiEntity> messages = new List<IMessageApiEntity>(); 
// Add messages to the list here. 
// They are all different types that implement the IMessageApiEntity interface. 

// Create http client 
HttpClient client = new HttpClient {BaseAddress = new Uri(ConfigurationManager.AppSettings["WebApiUrl"])}; 
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

// Post to web api 
HttpResponseMessage response = client.PostAsJsonAsync("Communications/Messages", messages).Result; 

// Read results 
IEnumerable<ApiResponse<IMessageApiEntity>> results = response.Content.ReadAsAsync<IEnumerable<ApiResponse<IMessageApiEntity>>>().Result; 

मेरे जाल एपीआई नियंत्रक कार्रवाई इस तरह दिखता है:

public HttpResponseMessage Post([FromBody]IEnumerable<IMessageApiEntity> messages) 
{ 
    // Do stuff 
} 

मेरी समस्या यह है कि messages वेब एपीआई नियंत्रक कार्रवाई में आने पर हमेशा खाली (लेकिन शून्य नहीं) है। मैंने डीबगर में सत्यापित किया है कि क्लाइंट पक्ष पर messages ऑब्जेक्ट में पोस्ट होने से ठीक पहले इसमें आइटम हैं।

मुझे संदेह है कि ऑब्जेक्ट को पार करने की कोशिश करते समय इंटरफ़ेस प्रकार को ठोस प्रकार में परिवर्तित नहीं किया जा सकता है, लेकिन मुझे नहीं पता कि यह काम करने के बारे में कैसे जाना है। इसे कैसे प्राप्त किया जा सकता है?

उत्तर

7

मुझे पता चला कि कस्टम मॉडल बाइंडर के बिना इसे कैसे किया जाए। मामले में किसी और सवाल का जवाब इस मुद्दे पोस्ट किया जा रहा है ...

ग्राहक:

// Create list of messages that will be sent 
IEnumerable<IMessageApiEntity> messages = new List<IMessageApiEntity>(); 
// Add messages to the list here. 
// They are all different types that implement the IMessageApiEntity interface. 

// Create http client 
HttpClient client = new HttpClient {BaseAddress = new Uri(ConfigurationManager.AppSettings["WebApiUrl"])}; 
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

// Post to web api (this is the part that changed) 
JsonMediaTypeFormatter json = new JsonMediaTypeFormatter 
{ 
    SerializerSettings = 
    { 
     TypeNameHandling = TypeNameHandling.All 
    } 
}; 
HttpResponseMessage response = client.PostAsync("Communications/Messages", messages, json).Result; 

// Read results 
IEnumerable<ApiResponse<IMessageApiEntity>> results = response.Content.ReadAsAsync<IEnumerable<ApiResponse<IMessageApiEntity>>>().Result; 

Register विधि के लिए WebApiConfig.cs में जोड़ें:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; 

कुंजी प्रकार के रूप में भेजने के लिए है जेसन का हिस्सा और स्वचालित प्रकार के नाम हैंडलिंग चालू करें, ताकि वेब एपीआई यह पता लगा सके कि यह किस प्रकार है।

+0

धन्यवाद। एक जादू की तरह काम करता है। मुझे बहुत मदद की। –

+0

एक नया 'SerializerSettings' को चालू करने के बजाय मैं डिफ़ॉल्ट अद्यतन करने का सुझाव देता हूं (बस इसे अपने' WebApiConfig.cs' में करें)।इस तरह आप अन्य डिफ़ॉल्ट serializer सेटिंग्स खोना नहीं है। –

0

आप इंटरफ़ेस प्रकार का तरीका क्यों उपयोग करते हैं? वेब एपीआई की तरह दिखता है, यह नहीं पता कि संदेश तर्क को भौतिक बनाने के लिए किस तरह का उदाहरण इस्तेमाल किया जाना चाहिए। ऐसा लगता है कि आपको इस कार्रवाई के लिए कस्टम मॉडल बाइंडर लिखना है।

+0

उत्तर के लिए धन्यवाद। मैं एक इंटरफेस प्रकार का उपयोग कर रहा हूं क्योंकि मुझे एक एपीआई कॉल में विभिन्न प्रकार के संदेशों की एक सूची पोस्ट करने में सक्षम होना चाहिए। मैंने पहले ही कहा है कि मुझे लगता है कि समस्या इंटरफ़ेस प्रकार को ठोस प्रकार में परिवर्तित नहीं किया जा रहा है। आप जो वर्णन कर रहे हैं उसका एक उदाहरण सहायक होगा। – mayabelle

+0

सबसे पहले आपको अपने अनुरोध में ठोस प्रकार के IMessageApiEntity निर्दिष्ट करने के लिए कुछ डेटा भेजना होगा। तो आपको अपने आईमोडेल बाइंडर ([छोटे उदाहरण] (http://www.dotnetcurry.com/ShowArticle.aspx?ID=584) को लागू करना चाहिए) और बाद में [FromBody] विशेषता को [ModelBinder (Typeof (YourCustomModelBinderTypeName) में प्रतिस्थापित करें]] आपके "संदेश" विधि पैरामीटर के लिए –

0

मुझे कुछ सप्ताह पहले .NET कोर वेबएपीआई के साथ एक ही समस्या थी। नीचे लाइन जोड़ने की प्रस्तावित समाधान मेरे लिए काम नहीं किया:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; 

मैं एक सामान्य उद्देश्य यह है कि मेरी IEnumerable ले जा सकता है, जहां टी तब मैं अपने इच्छित वर्ग

[Serializable] 
public class GenericListContainer<T> where T : class 
{ 
    #region Constructors 

    public GenericListContainer() 
    { 

    } 

    public GenericListContainer(IEnumerable<T> list) 
    { 
     List = list; 
    } 
    #endregion 

    #region Properties 

    public IEnumerable<T> List { get; set; } 

    #endregion 
} 

है बना दी करने के लिए अपने WebAPI पद्धति को बदल:

[Route("api/system-users/save-collection-async")] 
[HttpPost] 
[ProducesResponseType(typeof(string), 200)]  
public async Task<IActionResult> SaveSystemUserCollectionAsync([FromBody] GenericListContainer<SystemUser> dto) 
{ 
    var response = await _systemUserService.SaveSystemUserCollectionAsync(dto.List); 
    return Ok(response); 
} 

इस विधि रिटर्न बचाया उपयोगकर्ता के आईडी (मेरे मामले में Guid)।

उम्मीद है कि यह किसी और की मदद करेगा!