ควรใช้แอตทริบิวต์ DataContract และ DataMember เมื่อใด


179

ฉันสับสนมากเกี่ยวกับDataContractคุณลักษณะใน WCF ตามความรู้ของฉันมันถูกใช้สำหรับชนิดที่ผู้ใช้กำหนดเช่นคลาส ฉันเขียนคลาสหนึ่งซึ่งเปิดเผยที่ฝั่งไคลเอ็นต์เช่นนี้

[DataContract]
public class Contact
{
    [DataMember]
    public int Roll { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Address { get; set; }

    [DataMember]
    public int Age { get; set; }
}

มันทำงานอย่างถูกต้อง แต่เมื่อฉันลบDataContractและDataMemberมันยังทำงานได้อย่างถูกต้อง ฉันไม่เข้าใจว่าทำไมมันทำงานอย่างถูกต้อง มีใครบอกได้บ้างว่าการใช้งานจริงDataContractคืออะไร

สัญญาบริการของฉันเป็นแบบนี้

[ServiceContract]    
public interface IRestServiceImpl
{
    [OperationContract]        
    Contact XmlData(string id);      
}

คำตอบที่สมบูรณ์แบบอยู่ที่นี่ stackoverflow.com/questions/5681842/…
Asif Iqbal

คำตอบ:


361

เนื่องจากโปรแกรมเมอร์จำนวนมากถูกครอบงำด้วย[DataContract]และ[DataMember]คุณลักษณะด้วย. NET 3.5 SP1 ไมโครซอฟท์ทำให้ serializer สัญญาข้อมูลจัดการกับคลาสทั้งหมด - แม้ว่าจะไม่มีแอ็ตทริบิวต์เหล่านั้น - เหมือนกับ XML serializer แบบเก่า

เช่นเดียวกับ. NET 3.5 SP1 คุณไม่จำเป็นต้องเพิ่ม data contract หรือ data data attribute อีกต่อไป - ถ้าคุณไม่ต้องการ serializer สัญญาสัญญาข้อมูลจะทำให้เป็นอันดับสาธารณะทั้งหมดในชั้นเรียนของคุณเหมือนกับ XML serializer

HOWEVER: หากไม่เพิ่มคุณสมบัติเหล่านั้นคุณจะสูญเสียความสามารถที่มีประโยชน์มากมาย:

  • หากไม่มี[DataContract]คุณจะไม่สามารถกำหนด XML เนมสเปซเพื่อให้ข้อมูลของคุณอยู่ได้
  • โดยไม่ต้อง[DataMember]คุณจะไม่สามารถเป็นอันดับคุณสมบัติที่ไม่ใช่แบบสาธารณะหรือสาขา
  • โดยไม่ต้อง[DataMember]คุณจะไม่สามารถกำหนดคำสั่งของอนุกรม ( Order=) และ DCS จะเป็นอันดับคุณสมบัติทั้งหมดตามลำดับตัวอักษร
  • หากไม่มี[DataMember]คุณจะไม่สามารถกำหนดชื่ออื่นให้กับอสังหาริมทรัพย์ของคุณ ( Name=)
  • หากไม่มี[DataMember]คุณไม่สามารถกำหนดสิ่งต่าง ๆ เช่นIsRequired=หรือคุณลักษณะที่มีประโยชน์อื่น ๆ
  • หากไม่มี[DataMember]คุณจะไม่สามารถทิ้งคุณสมบัติสาธารณะบางรายการได้คุณสมบัติสาธารณะทั้งหมดจะถูกจัดลำดับโดย DCS

ดังนั้นสำหรับวิธีแก้ปัญหา "quick'n'dirty" การละทิ้ง[DataContract]และ[DataMember]คุณลักษณะจะใช้งานได้ - แต่ก็ยังเป็นความคิดที่ดีที่จะมีมันไว้ในคลาสข้อมูลของคุณ - เพื่อให้ชัดเจนยิ่งขึ้นเกี่ยวกับสิ่งที่คุณกำลังทำ เข้าถึงคุณลักษณะเพิ่มเติมทั้งหมดที่คุณไม่ได้รับหากไม่มี ...


คุณหมายถึงโดยค่าเริ่มต้นทุกประเภทข้อมูลจะถูกทำเครื่องหมายเป็นอนุกรมและเราใช้ DataContract / DataMember เพื่อ จำกัด พวกเขา
santosh singh

2
@Santosh: หากคุณมีชั้นเรียนที่มีคุณสมบัติสาธารณะบางอย่างจะมีการจัดลำดับโดย WCF Data Contract Serializer เว้นแต่คุณจะใช้ [DataContract] / [DataMember] อย่างชัดแจ้งคุณจะได้รับ 100% ในการบอกสิ่งที่ได้รับต่อเนื่องและ ไม่ใช่อะไร
marc_s

36
@Aththis: นั่นไม่จริงทั้งหมด ในฐานะของ NET 3.5 SP1, WCF จะมีความสุขการเรียนเป็นอันดับโดยไม่ต้องใด ๆ [DataContract]และ[DataMember]แอตทริบิวต์ ... แต่ทันทีที่คุณเริ่มใช้หนึ่งในคุณลักษณะเหล่านั้นแล้วนี้พฤติกรรมการ "เริ่มต้น" จะหยุดทำงาน - เร็วที่สุดเท่าที่คุณจะมีเพียงครั้งเดียว [DataMember]ในของคุณ class จากจุดนั้นเป็นต้นไปจะมีเพียงคุณสมบัติเหล่านั้นที่มีแอตทริบิวต์นี้เท่านั้น
marc_s

4
Oohh! ขอบคุณสำหรับการชี้แจงจุดนั้น! ฉันจะขุดมันต่อไปอีกเล็กน้อย!
Arthis

6
Youhou! มันหิน !! Merci beaucoup!
Arthis

16

ในแง่ของ WCF เราสามารถสื่อสารกับเซิร์ฟเวอร์และลูกค้าผ่านข้อความ สำหรับการถ่ายโอนข้อความและจากความคาดหวังด้านความปลอดภัยเราจำเป็นต้องสร้างข้อมูล / ข้อความในรูปแบบต่อเนื่อง

สำหรับการจัดลำดับข้อมูลเราใช้ [datacontract] และแอตทริบิวต์ [datamember] ในกรณีของคุณหากคุณใช้datacontractWCF จะใช้DataContractSerializerอย่างอื่น WCF ใช้XmlSerializerซึ่งเป็นเทคนิคการจัดลำดับเริ่มต้น

ให้ฉันอธิบายรายละเอียด:

โดยทั่วไป WCF รองรับการทำให้เป็นอนุกรม 3 ประเภท:

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer : - ลำดับเริ่มต้นเหมือนกับคลาส

DataContractSerializer / NetDataContractSerializer : - ลำดับเริ่มต้นคือตัวอักษร

XmlSerializer : - XML ​​Schema นั้นกว้างขวาง

DataContractSerializer / NetDataContractSerializer : - XML ​​Schema มีข้อ จำกัด

XmlSerializer : - ไม่รองรับการกำหนดเวอร์ชัน

DataContractSerializer / NetDataContractSerializer : - รองรับการกำหนดเวอร์ชันได้

XmlSerializer : - ความเข้ากันได้กับ ASMX

DataContractSerializer / NetDataContractSerializer : - ความเข้ากันได้กับ. NET Remoting

XmlSerializer : - ไม่จำเป็นต้องมีแอตทริบิวต์ใน XmlSerializer

DataContractSerializer / NetDataContractSerializer : - คุณสมบัติที่ต้องการในการทำให้เป็นอนุกรมนี้

ดังนั้นสิ่งที่คุณใช้ขึ้นอยู่กับความต้องการของคุณ ...


8

สัญญาข้อมูลคือข้อตกลงอย่างเป็นทางการระหว่างบริการและลูกค้าที่อธิบายข้อมูลที่จะแลกเปลี่ยนอย่างเป็นนามธรรม กล่าวคือในการสื่อสารลูกค้าและบริการไม่จำเป็นต้องแชร์ประเภทเดียวกันเพียงสัญญาข้อมูลเดียวกัน สัญญาข้อมูลกำหนดได้อย่างแม่นยำสำหรับแต่ละพารามิเตอร์หรือชนิดส่งคืนข้อมูลใดที่เป็นอนุกรม (เปลี่ยนเป็น XML) เพื่อแลกเปลี่ยน

Windows Communication Foundation (WCF) ใช้เครื่องมือการทำให้เป็นอนุกรมที่เรียกว่า Data Contract Serializer โดยค่าเริ่มต้นเพื่อทำให้เป็นอนุกรมและ deserialize ข้อมูล (แปลงเป็นและจาก XML) ชนิดดั้งเดิมของ. NET Framework ทั้งหมดเช่นจำนวนเต็มและสตริงรวมถึงบางประเภทที่ถือว่าเป็น primitives เช่น DateTime และ XmlElement สามารถถูกทำให้เป็นอนุกรมโดยไม่ต้องมีการเตรียมการอื่นและถือเป็นสัญญาข้อมูลเริ่มต้น . NET Framework หลายชนิดก็มีสัญญาข้อมูลที่มีอยู่

คุณสามารถค้นหาบทความเต็มได้ที่นี่


2
ทั้งหมดนี้เป็นเรื่องจริงและเป็นเรื่องดี แต่มันไม่ได้ตอบคำถามของ OP ว่าเหตุใด serializer สัญญาข้อมูลจึงทำงานได้โดยไม่มีแอตทริบิวต์ [DataContract] และ [DataMember] ในชั้นเรียนของคุณ ....
marc_s

ใครช่วยบอก DataContract ที่ใช้จริงได้บ้าง - ผมคิดว่าส่วนน้อยของคำถามจะตอบ
IAbstract

2

สัญญาข้อมูลคือข้อตกลงอย่างเป็นทางการระหว่างบริการและลูกค้าที่อธิบายข้อมูลที่จะแลกเปลี่ยนอย่างเป็นนามธรรม

สัญญาข้อมูลอาจชัดเจนหรือโดยนัย ประเภทที่เรียบง่ายเช่น int, string ฯลฯ มีสัญญาข้อมูลโดยนัย วัตถุที่ผู้ใช้กำหนดเป็นประเภทที่ชัดเจนหรือซับซ้อนซึ่งคุณต้องกำหนดสัญญาข้อมูลโดยใช้แอตทริบิวต์ [DataContract] และ [DataMember]

สัญญาข้อมูลสามารถกำหนดได้ดังนี้

  • มันอธิบายรูปแบบภายนอกของข้อมูลที่ส่งผ่านไปยังและจากการดำเนินการบริการ

  • มันกำหนดโครงสร้างและประเภทของข้อมูลที่แลกเปลี่ยนในข้อความบริการ

  • มันแมปประเภท CLR กับ XML Schema
  • มันกำหนดวิธีการที่ชนิดของข้อมูลที่เป็นอันดับและ deserialized คุณจะแปลงวัตถุเป็นลำดับไบต์ที่สามารถส่งผ่านเครือข่ายได้ ด้วยการดีซีเรียลไลเซชันคุณรวมวัตถุจากลำดับของไบต์ที่คุณได้รับจากแอปพลิเคชันการโทร
  • เป็นระบบการกำหนดเวอร์ชันที่ช่วยให้คุณจัดการการเปลี่ยนแปลงข้อมูลที่มีโครงสร้าง

เราจำเป็นต้องรวม System.Runtime.Serialization อ้างอิงกับโครงการ แอสเซมบลีนี้เก็บแอตทริบิวต์ DataContract และ DataMember


2
  1. สัญญาข้อมูล: ระบุว่าคลาสเอนทิตีของคุณพร้อมสำหรับกระบวนการทำให้เป็นอนุกรม

  2. สมาชิกข้อมูล: มันระบุว่าฟิลด์เฉพาะเป็นส่วนหนึ่งของสัญญาข้อมูลและสามารถต่อเนื่องกันได้


0

นอกจากนี้เมื่อคุณโทรจากคำขอ http มันจะทำงานได้อย่างถูกต้อง แต่เมื่อคุณพยายามโทรจาก net.tcp ในครั้งนั้นคุณจะได้รับทุกอย่าง


0

แอ็ตทริบิวต์ DataMember ไม่จำเป็นต้องเพิ่มลงในข้อมูลซีเรียลไลซ์ เมื่อไม่ได้เพิ่มแอตทริบิวต์ DataMember XMLSerializer รุ่นเก่าจะทำให้ข้อมูลเป็นอนุกรม การเพิ่ม DataMember จะมีคุณสมบัติที่มีประโยชน์เช่นคำสั่งซื้อชื่อคุณสมบัติที่ไม่สามารถใช้งานได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.