15 days proficient in WCF-13th days using WCF to play Rest, 13th days using wcf
When we were playing with wcf, we would subconsciously think that wcf exchanged messages through the soap protocol, and could switch between the basic, tcp, and msmq bindings,
It's a mess, but if on that day, wcf no longer uses the soap protocol, but uses strings in json format, isn't it a thing that subverts your understanding of wcf ???
In the traditional sense, wcf is very heavyweight. A clear example is too many configurations, especially the Behavior configuration, and behavior is heavy for wcf.
It is the most important for the expansion and performance of wcf. the hateful thing is that the configuration in binding, behavior, and contract is very conservative.
For example, the base class HttpBindingBase of basicbinding.
If you complain, I will not talk about it. Microsoft may also think this problem is not a small problem. Then we have a lightweight asp.net web api. You can see that it is better than wcf.
It's much simpler. Maybe let our coders focus more on their business. Since wcf has brought this stuff, I have to talk about it.
1. UriTemplate
To talk about rest, you must first talk about UriTemplate, because wcf uses UriTemplate for uri template matching in rest, and then uses the OperationBehavior WebInvoke.
Insert it into the heart of the wcf. This is a bit like the routing matching mechanism in mvc. Here is an example:
1. Use UriTemplate to tell the complete Url that can be monitored
The following figure shows three elements: service address, template, and input parameter ("1"). These three elements are combined, the complete remote url,
Then the complete url is the object monitored by my template (/User/{id.
2. Use UriTemplate to parse url parameters.
Now that you can build a url, You can parse the url, right? The following figure clearly tells you that when the external url = http: // 127.0.1: 1920/HomeService
The uriTemplate to which the/User/1 should be received.
Because UriTemplate has such url construction and parsing capabilities, wcf uses UriTemplate as the parameters of the WebInvoke and WebGet attributes to dynamically
Parse external URLs and assign them to specific service methods based on the URLs. Let's take a look at them.
Ii. Use of WebGet and WebInvoke
As I mentioned earlier, WebGet and WebInvoke use UriTemplate to implement the routing function. In addition, xml is returned by default. json is used here.
Value as the format returned by the Service
1 [ServiceContract] 2 public interface IHomeService 3 { 4 [OperationContract] 5 [WebGet(UriTemplate = "Get/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] 6 Student Get(string id); 7 8 [OperationContract] 9 [WebInvoke(Method = "POST", UriTemplate = "Add", RequestFormat = WebMessageFormat.Json,10 ResponseFormat = WebMessageFormat.Json)]11 string Add(Student stu);12 }
By the way, Rest recommends using Get, Post, Delete, and Put in the Http protocol as the CURD State mechanism. If you understand UriTemplate, you should
This will know what type of url this Template is monitoring. After completing the above coding, we need to use behavior in webconfig to specify to start the "web programming model ",
As shown in the following figure.
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 4 <system.diagnostics> 5 <sources> 6 <source name="System.ServiceModel" switchValue="ActivityTracing"> 7 <listeners> 8 <add name="mylisteners" type="System.Diagnostics.XmlWriterTraceListener" initializeData="E:\1.txt" /> 9 </listeners>10 </source>11 <source name="System.ServiceModel.MessageLogging" switchValue="ActivityTracing">12 <listeners>13 <add name="messagelogging" type="System.Diagnostics.XmlWriterTraceListener" initializeData="E:\2.txt"/>14 </listeners>15 </source>16 </sources>17 <trace autoflush="true"/>18 </system.diagnostics>19 20 <system.serviceModel>21 22 <diagnostics>23 <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtTransportLevel="true" />24 </diagnostics>25 26 <behaviors>27 <serviceBehaviors>28 <behavior>29 <serviceMetadata httpGetEnabled="true" />30 <serviceDebug includeExceptionDetailInFaults="true" />31 </behavior>32 </serviceBehaviors>33 <endpointBehaviors>34 <behavior name="webbehavior">35 <webHttp />36 </behavior>37 </endpointBehaviors>38 </behaviors>39 40 <services>41 <service name="MyService.HomeService">42 <endpoint address="HomeService" binding="webHttpBinding" behaviorConfiguration="webbehavior"43 contract="MyService.IHomeService">44 <identity>45 <dns value="localhost" />46 </identity>47 </endpoint>48 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />49
Actually? That is, the WebHttpBehavior class in the code.
Now, the service address is http: // 127.0.0.1: 1920, and the template of the service method is also specified. As long as the http. sys template is monitored
The service method will be executed. For example, enter http: // 127.0.0.1: 1920/HomeService/Get/1 in the browser to test the Get operation.
As you can see, the get method is successful, and it matches my service method Get correctly.
1 public class HomeService : IHomeService 2 { 3 public Student Get(string id) 4 { 5 return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "001" }; 6 } 7 8 public string Add(Student stu) 9 {10 return "hello";11 }12 }
Then let's take a look at the Add method. I simulated the test in HttpWebRequest as follows.
1 class Program 2 {3 static void Main (string [] args) 4 {5 Run (); 6} 7 8 9 // <summary> 10 // report system error 11 // </summary> 12 // <param name = "ex"> </ param> 13 // <returns> </returns> 14 public static void Run () 15 {16 HttpWebRequest req = (HttpWebRequest) HttpWebRequest. create (" http://127.0.0.1:1920/HomeService/Add "); 17 Encoding encoding = Encoding. UTF8; 18 19 string param = new JavaScriptSerializer (). serialize (new {ID = "10", Name = "hxc", SNS = "001"}); 20 byte [] bs = Encoding. ASCII. getBytes (param); 21 22 string responseData = String. empty; 23 req. method = "POST"; 24 req. contentType = "application/json"; 25 req. contentLength = bs. length; 26 using (Stream reqStream = req. getRequestStream () 27 {28 reqStream. write (bs, 0, bs. length); 29 reqStream. close (); 30} 31 using (HttpWebResponse response = (HttpWebResponse) req. getResponse () 32 {33 using (StreamReader reader = new StreamReader (response. getResponseStream (), encoding) 34 {35 responseData = reader. readToEnd (). toString (); 36} 37} 38} 39}View Code
Well, it's probably so much. If you're not in too much trouble, you can use WCF Rest. Also, don't forget a lot of default configurations. If you think it's too cumbersome,
You can use the asp.net web api.