Silverlight Web Service FAQ: วิธีเรียกใช้ web service โดยไม่ใช่ proxy
-
Monday, February 13, 2012 6:08 AMModeratorSilverlight Web Service FAQ: วิธีเรียกใช้ web service โดยไม่ใช่ proxy
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.
All Replies
-
Monday, February 13, 2012 6:13 AMModerator
หลายๆคนอาจจะพบว่า เราไม่ต้องการใช้คุณสมบัติ “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:18 AMModerator
- สร้าง 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.
- Edited by supa_sModerator Monday, February 13, 2012 6:21 AM
- Marked As Answer by supa_sModerator Tuesday, February 14, 2012 7:00 AM
- สร้าง operation contract
ตามเอกสารของ WSDL โดยใช้วิธีการ asynchronous

