Wcf4.0 -- restful WCF services (2) (add, delete, modify, and query)

Source: Internet
Author: User
Tags wsdl

The Restful service is designed to implement a system that is easy to integrate and can be called across platforms (for example). [Part 1] describes how to build a restful service using WCF.
This article further uses an instance to record how to implement a specific restful WCF Service and client call services for addition, deletion, modification, and query.

One of the new features of WCF 4.0 is that it is easier for WCF to be presented using rest APIs. The uritemplate parameters in webgetattribute and webinvokeattribute in WCF 3.5 originally do not support the rest URL format. For the sake of the rest function, microsoft also specially released the WCF rest starter kit component, allowing developers to use WCF 3.5 to develop truly restful-based applications. The URL corresponds to the operation contract in the specified service contract, in WCF 4.0, the core of WCF has been integrated with the URL engine in rest starter kit. webgetattribute and webinvokeattribute can support the rest function. Many rest APIs of Windows azure services are the use Developed by WCF.

 

It mainly involves the following:
1. How to interact through JSON data;
2. How to handle server errors and identify different exceptions on the client;
3. How to Use Microsoft. httpclient (the 3rd-party component provided by Microsoft );

Project in this example:

PS: Although there are two projects in a solution, there is no reference to the project before. It relies entirely on HTTP message transmission.
1. Create a server project:
With Extension Manager of vs2010, you can download a "WCF rest service template ". Through this, we can quickly create a WCF rest service. It is a service created in the Web application project. Unlike the WCF Service described in the previous article, register the service in the application_start event in globel. asax. The registered "taskservice" automatically becomes the service base address, namely http: // <machine_name >:< port>/taskservice/
Public class Global: httpapplication <br/>{< br/> void application_start (Object sender, eventargs e) <br/>{< br/> registerroutes (); <br/>}</P> <p> private void registerroutes () <br/>{< br/> routetable. routes. add (New serviceroute ("taskservice", <br/> New webservicehostfactory (), typeof (taskservice); <br/>}< br/>}
2. Service implementation:
The server directly operates the DB through linq2entities. To return JSON data, the parameters and return values are designed as poco classes. After linq2entities generates codeCopyA copyDeleteChange to poco class. (Now there is a T4 template for ADO. Net poco generator. I don't know if it can simplify my current practice ...)
Namespace wcfrestservice2.model <br/>{< br/> [datacontract] <br/> public class pocotask <br/>{< br/> [datamember] <br/> Public Virtual int id {Get; set ;}< br/> [datamember] <br/> Public Virtual String title {Get; Set ;} <br/> [datamember] <br/> Public Virtual string detail {Get; Set ;}< br/> [datamember] <br/> Public Virtual int state {Get; set ;}< br/> [datamember] <br/> Public Virtual datetime updateddate {Get; Set ;}< br/>}< br/>}
Rest makes good use of the http get/post/Put/delete method and binds it to different methods of the service. For example, the get method does not require the client to provide too much data, so it is suitable for scenarios where only primary keys or query fields are provided for queries. Post is suitable for data insertion, put is applied to data update, and delete is directly used to delete data. Of course, the difference between Uris can also all be post or put. If the semantics is consistent with the call scenario, it is easier to understand and get used to services.
Server implementation segment:
(1) query (HTTP/get). The accessed uritemplate is defined here. The complete access address is "base address + uritemplate", for example:
Http: // localhost: Port/taskservice/tasks/State/{state} And responseformat is set to JSON format.
You can also modify the defaultoutgoingresponseformat attribute of the <standardendpoint> node in the configuration file to control the response format.
[Webget (uritemplate = "tasks/State/{state}", <br/> responseformat = webmessageformat. JSON)] <br/> public list <pocotask> gettasksbystate (string state) <br/> {<br/> using (var db = new tasksentities ()) <br/>{< br/> int S = int32.parse (State); <br/> var query = dB. task. where (t => T. state = S |-1 = s); <br/> return getpocodata (query); <br/>}< br/>}
(2) create (HTTP/post). The data format in post is defined as JSON through requestformat. When the WCF framework receives a request for JSON data, it is automatically deserialized into a pocotask instance. Then I create an entity instance in EF, copy the pocotask data to entity, and insert the DB.
[Webinvoke (uritemplate = "tasks/Add", method = "Post", <br/> requestformat = webmessageformat. JSON)] <br/> Public void create (pocotask) <br/>{< br/> var CTX = weboperationcontext. current; <br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. OK; <br/> try <br/> {<br/> using (VAR DB = new tasksentities ()) <br/>{< br/> var task = new task (); <br/> copyvalue (pocotask, task); <br/> task. updateddate = datetime. now; <br/> dB. addtotask (task); <br/> dB. savechanges (); <br/>}< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. created; <br/>}< br/> catch (exception ex) <br/>{< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. expectationfailed; <br/> CTX. outgoingresponse. statusdescription = ex. message; <br/>}< br/>}
(3) Update (HTTP/Put): first identify the entity through the ID, and then update the client data to the entity.
[Webinvoke (uritemplate = "tasks/{ID}", method = "put", <br/> requestformat = webmessageformat. JSON)] <br/> Public void Update (string ID, pocotask) <br/>{< br/> var CTX = weboperationcontext. current; <br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. OK; <br/> try <br/> {<br/> using (VAR DB = new tasksentities () <br/>{< br/> var nid = convert. toint32 (ID); <br/> var target = dB. task. singleordefault (t => T. id = NID); <br/> target. title = pocotask. title; <br/> target. detail = pocotask. title; <br/> target. state = pocotask. state; <br/> target. updateddate = datetime. now; <br/> dB. savechanges (); <br/>}< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. accepted; <br/>}< br/> catch (exception ex) <br/>{< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. expectationfailed; <br/> CTX. outgoingresponse. statusdescription = ex. message; <br/>}< br/>}
(4) Delete (HTTP/delete)
[Webinvoke (uritemplate = "tasks/{ID}", method = "delete")] <br/> Public void Delete (string ID) <br/> {<br/> var CTX = weboperationcontext. current; <br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. OK; <br/> try <br/> {<br/> using (VAR DB = new tasksentities () <br/>{< br/> var nid = convert. toint32 (ID); <br/> var task = dB. task. singleordefault (t => T. id = NID); <br/> dB. task. deleteobject (task); <br/> dB. savechanges (); <br/>}< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. accepted; <br/>}< br/> catch (exception ex) <br/>{< br/> CTX. outgoingresponse. statuscode = system. net. httpstatuscode. expectationfailed; <br/> CTX. outgoingresponse. statusdescription = ex. message; <br/>}< br/>}
In exception handling on the server, different codes are returned through outgoingresponse. statuscode, so that the client can know what errors have occurred on the server. However, I do not know how to obtain outgoingresponse. statusdescription on the client. If possible, we can know the details of the error.
In this example:
A) query successful -- system. net. httpstatuscode. OK (default)

B) created successfully -- system. net. httpstatuscode. Created
C) Update successful -- system. net. httpstatuscode. Accepted
D) Deletion successful -- system. net. httpstatuscode. Accepted

For enumeration of system. net. httpstatuscode, see msdn: http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx.

3. Client implementation:

Because rest is based on HTTP, developers of rest clients cannot reference WSDL like traditional WebServices or other WCF services and enjoy "luxury" code generation, A strong type of local proxy is used to call the service. Developers can only assemble HTTP requests, but because of this direct httprequest assembly, the client is truly language-independent. Here I have to mention Microsoft. http. dll and Microsoft. http. Extensions. dll, which are rest client packages provided by Microsoft. You can more easily operate httprequest/response, you can go down here: http://aspnet.codeplex.com/releases/view/24644

Client segment:
(1) query (HTTP/get). The httpclient. Get method returns httpresponsemessage and httpresponsemessage. content returns JSON data. Deserialization is performed using the JSON. Net 3rd component. In addition, the task class is defined separately on the client to operate data through the instantiated class. (Because the client cannot generate a proxy through WSDL)
// Get data by State <br/> var client = new httpclient (); <br/> var strurl = "http: // localhost: 1180/taskservice/tasks/State/{0} "; <br/> strurl = string. format (strurl, combobox1.selectedvalue); <br/> var response = client. get (strurl); <br/> response. ensurestatusissuccessful (); <br/> var JSON = response. content. readasstring (); <br/> var DATA = jsonconvert. deserializeobject <list <task> (JSON );
(2) create (HTTP/post), serialize the data into JSON format and put it into httpcontent, and then use httpclient. Post to submit httpcontent data.
Httpcontent must specify that contenttype is in JSON format.
// Add task <br/> var task = gettask (); <br/> var client = new httpclient (); <br/> var strurl = "http: // localhost: 1180/taskservice/tasks/Add "; <br/> var response = client. post (strurl, getcontent (task); <br/> response. ensurestatusissuccessful ();
(3) Update (HTTP/Put)
// Update task <br/> var task = gettask (); <br/> var client = new httpclient (); <br/> var strurl = "http: // localhost: 1180/taskservice/tasks/{0} "; <br/> strurl = string. format (strurl, task. ID); <br/> var response = client. put (strurl, getcontent (task); <br/> response. ensurestatusissuccessful ();
(4) Delete (HTTP/delete)
// Delete task <br/> var task = gettask (); <br/> var client = new httpclient (); <br/> var strurl = "http: // localhost: 1180/taskservice/tasks/{0} "; <br/> strurl = string. format (strurl, task. ID); <br/> var response = client. delete (strurl); <br/> response. ensurestatusissuccessful ();
A getcontent (Task task) method is missing:
Private httpcontent getcontent (Task task) <br/>{< br/> var strcontent = jsonconvert. serializeobject (task); <br/> var DATA = system. text. encoding. utf8.getbytes (strcontent); <br/> return httpcontent. create (data, "application/JSON"); <br/>}
Response. ensurestatusissuccessful is used to check response. statuscode.

Finally, I will leave some thoughts on rest WCF design:
(1) Does it seem to not support transactions?
(2) cannot the type be too complex?
(3) Duplicate metadata definition?

Conclusion-rest simplifies your design, but it is not easy to do...

[Rest WCF series]
Restful WCF Services (1) (Getting Started)
Restful WCF services (2) (implement add, delete, modify, and query)
Restful WCF services (3) (raw Stream)
Restful WCF Services (4) (Basic Security)
Restful WCF services (Instance) (concurrent Synchronization Service syncservice)

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.