none
Silverlight Web Service FAQ: วิธีเรียกใช้ web service โดยไม่ใช่ proxy

Answers




    •            
      • สร้าง operation contract ตามเอกสารของ WSDL โดยใช้วิธีการ asynchronous
              ตาม
        WSDL ข้างต้น เรามี operation ที่ชื่อว่า DoWork

      • สร้าง data contract ตามเอกสารของ WSDL
              ใน
        WSDL ข้างต้น ขณะที่เราทำการ input และ output  
        DoWork operation จะเป็นแบบ complex เนื่องจาก มีเพียง 1 element ใน string ดังนั้นเราจะใช้ string ใน data contract
              ส่วนแบบ
        complex อื่นๆ เราจะต้องสร้าง class ให้สอดคล้องกัน

      • สร้าง channel interface ที่สืบทอดมาจาก IClientChannel และ operation contract ที่ได้สร้างไว้ก่อนหน้านี้แล้ว
      • สร้าง ChannelFactory ด้วย BasicHttpBinding และ EndpointAddress ที่เหมาะสม
      • เปิด ChannelFactory และสร้าง channel
      • เปิด channelและทำงานใน operation
      • ปิด channel และ ChannelFactory (ละไว้ในตัวอย่างก่อนหน้านี้)


      BasicHttpBinding binding =new BasicHttpBinding();



      EndpointAddress address =new EndpointAddress("http://localhost:8731/Service1.svc");



      var factory = binding.BuildChannelFactory<IRequestChannel>();



      factory.BeginOpen(openResult =>



      {



      factory.EndOpen(openResult);



      IRequestChannel channel =
      factory.CreateChannel(address);



      channel.BeginOpen(channelOpenResult =>



      {



      Message
      requestmessage =Message.CreateMessage(MessageVersion.Soap11,"http://tempuri.org/IService1/DoWork",
      new DoWork()
      { Name = "abc" });



      channel.BeginRequest(requestmessage, requestResult =>



      {



      Message
      responseMessage = channel.EndRequest(requestResult);



      DoWorkResponse response =
      responseMessage.GetBody<DoWorkResponse>();



      string result = response.DoWorkResult;



      channel.BeginClose(channelCloseResult =>



      {



      channel.EndClose(channelCloseResult);



      factory.BeginClose(closeResult =>



      {



      factory.EndClose(closeResult);



      }, null);



      }, null);



      }, null);



      }, null);



      },null);



      [DataContract(Namespace ="http://tempuri.org/")]



      publicclass DoWork



      {



      [DataMember]



      public string Name {get; set; }



      }



      [DataContract(Namespace ="http://tempuri.org/")]



      publicclass DoWorkResponse



      {



      [DataMember]



      public string
      DoWorkResult {get; set;
      }



      }



    ขั้นตอนที่จำเป็น มีดังต่อไปนี้


         
      • สร้าง BasicHttpBinding
         
      • สร้าง ChannelFactory
         
      • เปิด ChannelFactory และสร้าง IRequestChannel
         
      • เปิด channel และส่ง message
         
      • ตาม xml ใน WSDL ให้สร้างคลาส DoWork ที่สอดคล้องกัน และตรวจสอบ namespace ให้ถูกต้อง โดย instance ของคลาสนี้จะใช้เป็น message body
         
      • หลังจากที่มี message ตอบกลับมา ให้สร้างอีก 1 คลาส ที่ชื่อว่า DoWorkResponse ตามที่ได้อธิบายไว้ใน WSDL
         
      • ปิด channel และ ChannelFactory


    หมายเหตุ: ในขณะที่เปิด/ปิด factory กับ channel พร้อมกัน เราจะต้องส่ง message แบบ asynchronous

    เพื่อหลีกเลี่ยงการสับสน ควรทำแบบ
    asynchronous



    Supa Sethasiripong [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Monday, February 13, 2012 6:18 AM

All replies



  • หลายๆคนอาจจะพบว่า เราไม่ต้องการใช้คุณสมบัติ “Add Service Reference”

    ซึ่งในกรณีนี้ เราจะต้องทำความเข้าใจกับ
    contract ที่ service มีมาให้

    ในการสร้าง
    local DataContracts แล้วส่ง message แบบ manual

    เราจะต้องอ้างอิงเอกสาร
    service ของ WSDL เพื่อสร้าง local DataContracts และส่ง message


    สมมติว่าเรามี service ต่อไปนี้



    [ServiceContract]



    public interfaceIService1



    {



    [OperationContract]



    string DoWork(string
    name);


    }



    เพียงแค่รู้เกี่ยวกับ service ในส่วนของ WSDL เท่านั้น



    <wsdl:messagename="IService1_DoWork_InputMessage">



    <wsdl:partname="parameters"element="tns:DoWork"/>





    กับ xml schema




    <xs:schemaelementFormDefault="qualified"targetNamespace="http://tempuri.org/"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:tns="http://tempuri.org/">



    <xs:elementname="DoWork">



    <xs:complexType>



    <xs:sequence>



    <xs:elementminOccurs="0"name="name"nillable="true"type="xs:string"/>



    </xs:sequence>



    </xs:complexType>



    </xs:element>



    <xs:elementname="DoWorkResponse">



    <xs:complexType>



    <xs:sequence>



    <xs:elementminOccurs="0"name="DoWorkResult"nillable="true"type="xs:string"/>



    </xs:sequence>



    </xs:complexType>



    </xs:element>



    </xs:schema>


    </wsdl:message>



    <wsdl:messagename="IService1_DoWork_OutputMessage">



    <wsdl:partname="parameters"element="tns:DoWorkResponse"/>



    </wsdl:message>



    <wsdl:operationname="DoWork">



    <wsdl:inputwsaw:Action="http://tempuri.org/IService1/DoWork" message="tns:IService1_DoWork_InputMessage"/>



    <wsdl:outputwsaw:Action=http://tempuri.org/IService1/DoWorkResponsemessage="tns:IService1_DoWork_OutputMessage"/>


    </wsdl:operation>



    ข้อมูลที่จำเป็นในการทำงานร่วมกับ service โดยไม่ใช้ proxy มี 2 วิธี

    วิธีหนึ่ง คือ การสร้าง
    client channel (คล้ายกับการใช้ proxy) และการส่ง message โดยตรง



    ServiceContract]



    public interfaceIService1



    {



    [OperationContract(AsyncPattern
    =true)]



    IAsyncResult BeginDoWork(string name,AsyncCallback
    callback, object asyncState);



    string EndDoWork(System.IAsyncResult
    result);



    }


    public interfaceIService1Channel : IService1, IClientChannel
    { }



    ChannelFactory<IService1Channel> factory =new ChannelFactory<IService1Channel>(newBasicHttpBinding(), new
    EndpointAddress("http://localhost:60486/Service1.svc/"));



    factory.BeginOpen(openResult =>



    {



    factory.EndOpen(openResult);



    IService1Channel channel = factory.CreateChannel();



    channel.BeginOpen(channelOpenResult =>



    {



    channel.BeginDoWork("abc",newAsyncCallback((operationResult)
    =>



    {



    string result = channel.EndDoWork(operationResult);



    this.Dispatcher.BeginInvoke(newAction(() =>



    {



    textBlock1.Text = result;



    }));



    }), null);



    }, null);



    }, null);

    Supa Sethasiripong [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, February 13, 2012 6:13 AM



    •            
      • สร้าง operation contract ตามเอกสารของ WSDL โดยใช้วิธีการ asynchronous
              ตาม
        WSDL ข้างต้น เรามี operation ที่ชื่อว่า DoWork

      • สร้าง data contract ตามเอกสารของ WSDL
              ใน
        WSDL ข้างต้น ขณะที่เราทำการ input และ output  
        DoWork operation จะเป็นแบบ complex เนื่องจาก มีเพียง 1 element ใน string ดังนั้นเราจะใช้ string ใน data contract
              ส่วนแบบ
        complex อื่นๆ เราจะต้องสร้าง class ให้สอดคล้องกัน

      • สร้าง channel interface ที่สืบทอดมาจาก IClientChannel และ operation contract ที่ได้สร้างไว้ก่อนหน้านี้แล้ว
      • สร้าง ChannelFactory ด้วย BasicHttpBinding และ EndpointAddress ที่เหมาะสม
      • เปิด ChannelFactory และสร้าง channel
      • เปิด channelและทำงานใน operation
      • ปิด channel และ ChannelFactory (ละไว้ในตัวอย่างก่อนหน้านี้)


      BasicHttpBinding binding =new BasicHttpBinding();



      EndpointAddress address =new EndpointAddress("http://localhost:8731/Service1.svc");



      var factory = binding.BuildChannelFactory<IRequestChannel>();



      factory.BeginOpen(openResult =>



      {



      factory.EndOpen(openResult);



      IRequestChannel channel =
      factory.CreateChannel(address);



      channel.BeginOpen(channelOpenResult =>



      {



      Message
      requestmessage =Message.CreateMessage(MessageVersion.Soap11,"http://tempuri.org/IService1/DoWork",
      new DoWork()
      { Name = "abc" });



      channel.BeginRequest(requestmessage, requestResult =>



      {



      Message
      responseMessage = channel.EndRequest(requestResult);



      DoWorkResponse response =
      responseMessage.GetBody<DoWorkResponse>();



      string result = response.DoWorkResult;



      channel.BeginClose(channelCloseResult =>



      {



      channel.EndClose(channelCloseResult);



      factory.BeginClose(closeResult =>



      {



      factory.EndClose(closeResult);



      }, null);



      }, null);



      }, null);



      }, null);



      },null);



      [DataContract(Namespace ="http://tempuri.org/")]



      publicclass DoWork



      {



      [DataMember]



      public string Name {get; set; }



      }



      [DataContract(Namespace ="http://tempuri.org/")]



      publicclass DoWorkResponse



      {



      [DataMember]



      public string
      DoWorkResult {get; set;
      }



      }



    ขั้นตอนที่จำเป็น มีดังต่อไปนี้


         
      • สร้าง BasicHttpBinding
         
      • สร้าง ChannelFactory
         
      • เปิด ChannelFactory และสร้าง IRequestChannel
         
      • เปิด channel และส่ง message
         
      • ตาม xml ใน WSDL ให้สร้างคลาส DoWork ที่สอดคล้องกัน และตรวจสอบ namespace ให้ถูกต้อง โดย instance ของคลาสนี้จะใช้เป็น message body
         
      • หลังจากที่มี message ตอบกลับมา ให้สร้างอีก 1 คลาส ที่ชื่อว่า DoWorkResponse ตามที่ได้อธิบายไว้ใน WSDL
         
      • ปิด channel และ ChannelFactory


    หมายเหตุ: ในขณะที่เปิด/ปิด factory กับ channel พร้อมกัน เราจะต้องส่ง message แบบ asynchronous

    เพื่อหลีกเลี่ยงการสับสน ควรทำแบบ
    asynchronous



    Supa Sethasiripong [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Monday, February 13, 2012 6:18 AM