Legendary WCF (6): data protocols (B)

Source: Internet
Author: User
The legendary WCF (1): Is this hard to learn?The legendary WCF (2): What about service agreements?Legendary WCF (3): multiple protocolsLegendary WCF (4): send and receive SOAP HeadersLegendary WCF (5): data protocols ()Legendary WCF (6): data protocols (B)Legendary WCF (7): "one-way" & "two-way"Legendary WCF (8): Play with message protocolsLegendary WCF (9): stream and file transferLegendary WCF (10): message interception and tamperingThe legendary WCF (11): Session)The legendary WCF (12): What is the use of server callback?Legendary WCF (13): group chat programThe legendary WCF (14): WCF can also be used as a chat program.

 

 

We continue to boast about it. The last time we blew part of the data agreement, we will continue to do our experiments today. Well, before the experiment, I would like to say that the experiment is risky and you should be careful when writing code.

Experiment started! Now we define two classes with data protocols-student and addrinfo.

[Datacontract]
Public class student
{
[Datamember]
Public string name;
[Datamember]
Public String phone;
[Datamember]
Public addrinfo address;
}

[Datacontract]
Public class addrinfo
{
[Datamember]
Public String province;
[Datamember]
Public String city;
[Datamember]
Public String detailaddr;
}

These two classes have a feature. The address field of the student class is an addrinfo object, and our service definition is as follows:

[Servicecontract (namespace = "mynamespace")]
Public interface iservice
{
[Operationcontract]
Student getstudentinfo ();
}

Public class myservice: iservice
{
Public student getstudentinfo ()
{
Student Stu = new student ();
Addrinfo info = new addrinfo ();
Info. Province = "Guangdong Province ";
Info. City = "Foshan City ";
Info. detailaddr = "Mars road-300 ";
Stu. Name = "Xiao Chen ";
Stu. Phone = "1388888888 ";
Stu. Address = Info;
Return Stu;
}
}

To test whether addrinfo can be successfully serialized or deserialized. The following code registers and starts the service:

Static void main (string [] ARGs)
{
// Server base address
Uri baseaddress = new uri ("http: // localhost: 1378/services ");
// Declare the server host
Using (servicehost host = new servicehost (typeof (myservice), baseaddress ))
{
// Add binding and endpoints
Wshttpbinding binding = new wshttpbinding ();
Host. addserviceendpoint (typeof (iservice), binding, "/test ");
// Add service description
Host. description. behaviors. Add (New servicemetadatabehavior {httpgetenabled = true });
Try
{
// Open the service
Host. open ();
Console. writeline ("service started. ");
}
Catch (exception ex)
{
Console. writeline (ex. Message );
}
Console. readkey ();
}
}

In the code generated by the client, both classes can be correctly generated.

The client test code is as follows:

Static void main (string [] ARGs)
{
WS. serviceclient CLI = new ws. serviceclient ();
WS. Student Stu = cli. getstudentinfo ();
String MSG = "Student name: {0} \ n contact number: {1} \ n" +
"Address: ----------- \ n" +
"Province: {2} \ n" +
"City: {3} \ n" +
"Detailed address: {4 }";
Console. writeline (MSG, Stu. Name, Stu. Phone, Stu. Address. Province, Stu. Address. City, Stu. Address. detailaddr );
Console. readkey ();
}
 

The running result is as follows:

 

 

Next we will continue the experiment.

Each student may have scores of multiple subjects. Therefore, we add another score attribute for the student category.

[Datacontract]
Public class student
{
[Datamember]
Public string name;
[Datamember]
Public String phone;
[Datamember]
Public addrinfo address;
[Datamember]
Public object scores;
}

Public class myservice: iservice
{
Public student getstudentinfo ()
{
Student Stu = new student ();
Addrinfo info = new addrinfo ();
Info. Province = "Guangdong Province ";
Info. City = "Foshan City ";
Info. detailaddr = "Mars road-300 ";
Stu. Name = "Xiao Chen ";
Stu. Phone = "1388888888 ";
Stu. Address = Info;
Dictionary <string, float> m_scores = new dictionary <string, float> ();
M_scores.add ("", 97f );
M_scores.add ("English", 64.5f );
M_scores.add ("Mathematics", 38f );
M_scores.add ("History", 77.6f );
M_scores.add ("Geography", 82.3f );
Stu. Scores = m_scores;
Return Stu;
}
}

The client test code is changed:

Static void main (string [] ARGs)
{
WS. serviceclient CLI = new ws. serviceclient ();
WS. Student Stu = cli. getstudentinfo ();
String MSG = "Student name: {0} \ n contact number: {1} \ n" +
"Address: ----------- \ n" +
"Province: {2} \ n" +
"City: {3} \ n" +
"Detailed address: {4 }";
Console. writeline (MSG, Stu. Name, Stu. Phone, Stu. Address. Province, Stu. Address. City, Stu. Address. detailaddr );
Console. writeline ("---------------------------------------");
Console. writeline ("Student Transcript :");
Dictionary <string, float> scores = Stu. scores as Dictionary <string, float>;
Foreach (VAR item in scores)
{
Console. Write ("{0 }:{ 1} \ n", item. Key, item. value );
}

Console. readkey ();
}

Now we can test it, and an exception will occur, because the score attribute we add to the student class is of the object type, and in the Protocol method, we assign it a dictionary <string, float> type. In this way, it cannot be deserialized even if it can be serialized, because the dictionary <string, float> cannot be recognized.

Now we can add a knowntype feature for the student class to see if it can be identified.

[Datacontract]
[Knowntype (typeof (Dictionary <string, float>)]
Public class student
{
.....
}

At this time, run it again.

Unfortunately, an error is reported,

 

What should we do? Don't give up. Let's continue to modify the student category.

[Datacontract]
[Knowntype ("getknowtypes")]
Public class student
{
[Datamember]
Public string name;
[Datamember]
Public String phone;
[Datamember]
Public addrinfo address;
[Datamember]
Public object scores;

Static type [] getknowtypes ()
{
Return New Type [] {typeof (Dictionary <string, float> )};
}
}

The getknowtypes method is a static method. The name of this method is passed in the knowntype constructor. Check whether this call is successful?

Persistence is victory. See it. This time OK! Happy.

 

Here we can sum up that when some complex types cannot be deserialized (the types cannot be identified), we must consider using knowntypeattribute to mark the external types that may be involved, however, if you encounter complex types such as generic, you must consider addingStatic Method, This method returnsTypeIenumerableGenerally, it can be type [], and this is used in the knowntypeattribute constructor.Method Name.

 

 

Turn to it

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.