2010-03-26 15 views
9

से खाली/शून्य मान हैं मेरे पास एक साधारण डब्ल्यूसीएफ सेवा है जो सर्वर से समय लौटाती है। मैंने पुष्टि की है कि फिडलर के साथ जांच करके डेटा भेजा जा रहा है। यहां परिणाम ऑब्जेक्ट xml है जो मेरी सेवा भेजता है।क्लाइंट डब्ल्यूसीएफ डाटाकंट्रैक्ट में सेवा

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
     <GetTimeResponse xmlns="http://tempuri.org/"> 
      <GetTimeResult xmlns:a="http://schemas.datacontract.org/2004/07/TestService.DataObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
       <a:theTime>2010-03-26T09:14:38.066372-06:00</a:theTime> 
      </GetTimeResult> 
     </GetTimeResponse> 
    </s:Body> 
    </s:Envelope> 

तो, जहां तक ​​मैं कह सकता हूं, सर्वर के अंत में कुछ भी गलत नहीं है। यह अनुरोध प्राप्त कर रहा है और परिणाम लौट रहा है।

लेकिन मेरे चांदी के क्लाइंट क्लाइंट पर, लौटे ऑब्जेक्ट के सभी सदस्य या तो शून्य, खाली या डिफ़ॉल्ट वाउल हैं। जैसा कि आप देख सकते हैं कि सर्वर वर्तमान दिनांक और समय देता है। लेकिन चांदी की रोशनी में, मेरी वस्तु पर टाइम संपत्ति 1/1/0001 12:00 पूर्वाह्न (डिफ़ॉल्ट मान) पर सेट है।

Sooo methinks कि DataContracts सर्वर और Silverlight क्लाइंट के बीच मेल नहीं खाते हैं। सर्वर

[DataContract] 
public class Time 
{ 
    [DataMember] 
    public DateTime theTime { get; set; } 
} 

अविश्वसनीय रूप से सरल के लिए डेटाकंट्रैक्ट यहां दिया गया है। और यहां मेरे Silverlight क्लाइंट पर डेटाकंट्रैक्ट है।

[DataContract] 
public class Time 
{ 
    [DataMember] 
    public DateTime theTime { get; set; } 
} 

सचमुच एकमात्र अंतर एप्लिकेशन के भीतर नामस्थान है। लेकिन फिर भी लौटाए जाने वाले मान शून्य, खाली या .NET डिफ़ॉल्ट हैं।

आपकी मदद के लिए धन्यवाद!

अद्यतन

यहाँ clientbase कि मेरे सभी सेवाओं के माध्यम से चलाया जाता है। मैंने इसे बनाने के लिए excellent article here पढ़ा।

public class ClientBase<T> where T :class 
{ 
    private T Channel { get; set; } 

    private Type ContractType { get; set; } 

    private ClientBase() 
    { 
     ContractType = typeof(T); 
    } 

    public ClientBase(string endPointConfiguration) :this() 
    { 
     Channel = new ChannelFactory<T>(endPointConfiguration).CreateChannel(); 
    } 

    public ClientBase(EndpointAddress address, Binding binding):this() 
    { 
     Channel = new ChannelFactory<T>(binding, address).CreateChannel(); 
    } 

    public void Begin(string methodName, object state, params object[] parameterArray) 
    { 
     Begin(methodName, null, state, parameterArray); 
    } 

    public void Begin(string methodName, EventHandler<ClientEventArgs> callBack, object state, params object[] parameterArray) 
    { 
     if(parameterArray != null) 
     { 
      Array.Resize(ref parameterArray, parameterArray.Length + 2); 
     } 
     else 
     { 
      parameterArray = new object[2]; 
     } 

     parameterArray[ parameterArray.Length - 1 ] = new ObjectClientState {CallBack = callBack, MethodName = methodName, UserState = state}; 
     parameterArray[ parameterArray.Length - 2 ] = new AsyncCallback(OnCallBack); 
     ContractType.InvokeMember("Begin" + methodName, 
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | 
            System.Reflection.BindingFlags.Public, null, Channel, parameterArray); 

    } 

    private void OnCallBack(IAsyncResult result) 
    { 
     ObjectClientState state = result.AsyncState as ObjectClientState; 
     if(state == null) 
      return; 
     Object obj = ContractType.InvokeMember("End" + state.MethodName, 
               System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | 
               System.Reflection.BindingFlags.Public, null, Channel, new object[] {result}); 
     if(state.CallBack != null) 
     { 
      state.CallBack(this, new ClientEventArgs {Object = obj, UserState = state.UserState}); 
     } 
    } 

    public class ClientEventArgs : EventArgs 
    { 
     public object Object { get; set; } 
     public object UserState { get; set; } 

     public T LoadResult<T>() 
     { 
      if(Object is T) 
       return (T) Object; 
      return default(T); 
     } 
    } 

    private class ObjectClientState 
    { 
     public EventHandler<ClientEventArgs> CallBack { get; set; } 
     public string MethodName { get; set; } 
     public object UserState { get; set; } 
    } 
} 

यहाँ मेरी इंटरफ़ेस

[ServiceContract]  

    public interface ITestService 
      { 

       [OperationContract(AsyncPattern = true)] 
       IAsyncResult BeginGetTime(AsyncCallback callback, object state); 

       Time EndGetTime(IAsyncResult result); 

      } 

अब मैं मेरी सेवा वर्ग इस इंटरफ़ेस का उपयोग कर मेरी BaseService वर्ग के माध्यम से कॉल करता है कि है।

public class TestSiteService : ClientBase<ITestService> 
{ 
    public TestSiteService (string endPointConfiguration):base(endPointConfiguration) { } 

    public TestSiteService (EndpointAddress address, Binding binding) : base(address, binding) { } 

    public void GetTime(EventHandler<ClientEventArgs> callBack) 
    { 
     Begin("GetTime", callBack, null, null); 
    } 
} 

आखिर में वह कोड है जो वास्तव में सब कुछ कहता है और काम करता है।

TestSiteService client = new TestSiteService (new EndpointAddress("http://localhost:3483/wcf/Service.svc"), new BasicHttpBinding()); 

client.GetTime(delegate(object res, ClientBase<ITestService>.ClientEventArgs e) 
      { 

       Dispatcher.BeginInvoke(() => lblDisplay.Text = "Welcome " + e.LoadResult<Time>().theTime); 

      }); 

वाह .... मुझे आशा है कि कोई भी यह सब कोड मैं पोस्ट से खो दिया है: पी

+0

क्या आप सेवा विधि और क्लाइंट कोड का उपयोग कर रहे कोड के लिए कोड पोस्ट कर सकते हैं? साथ ही, आपको अपने प्रश्न में अपने कोड को सही तरीके से प्रारूपित करने की आवश्यकता है। प्रश्न संपादित करें, कोड हाइलाइट करें, और Ctrl + K दबाएं। –

+0

ईक! पता नहीं वो कैसे हुआ। सभी तय मैं अपने सेवा क्लाइंट को थोड़ा – Matt

उत्तर

19

क्योंकि आप अपनी DataContractAttribute पर the Namespace property निर्धारित नहीं करते हैं, नाम स्थान नेट से sythesized हो जाएगा वर्ग/नाम स्थान। आप सोप संदेश उदाहरण आप पोस्ट में देख सकते हैं:

http://schemas.datacontract.org/2004/07/TestService.DataObjects

आदेश ठेके पाने के लिए बराबर पर विचार किया जाना है, तो आप एक ही करने के लिए DataContract पर नामस्थान संपत्ति सेट करना होगा दोनों तरफ मूल्य।यही कारण है कि इस तरह एक छोटे से कुछ दिख सकता है:

[DataContract(Namespace="urn:my-test-namespace")] 
+0

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

+1

दिलचस्प, और क्योंकि मेरे पास प्रत्येक एप्लिकेशन के लिए अलग-अलग नामस्थान थे, डेटाकंट्रैक्ट काम नहीं करते हैं। मैंने कुछ नेमस्पेस में जोड़ा और यह सब अभी सही काम करता है! धन्यवाद!! – Matt

+0

बिल्कुल। मैं खुशी से मदद कर सकता है! –

0

ड्रयू मार्श के सही जवाब पर विस्तार (+1 - THX) मैं एक उत्पन्न सेवा संदर्भ जो काम कर रहा था था, लेकिन जब मैं WCF क्लाइंट फैक्टरी एक को लागू करने का प्रयास किया है सही इंटरफ़ेस (लेकिन नामस्थान अलग था) तो मुझे वर्णित समस्या का सामना करना पड़ रहा था।

मेरे पास "सही" नामस्थान होना चाहिए, लेकिन सेवा संदर्भ की डेटाकंट्रैक्ट इकाई से निम्नलिखित विशेषताओं को कॉपी करने के लिए WCF क्लाइंट फैक्टरी कार्यान्वयन में निम्न को कॉपी करने का कोई आसान तरीका नहीं था;

[System.Runtime.Serialization.DataContractAttribute(Name = "BOSPrice", Namespace = "http://schemas.datacontract.org/2004/07/BOSDataService")] 
    [System.SerializableAttribute()] 
संबंधित मुद्दे