The examples shown in this chapter are common cases so far when you use the WCF data service. They demonstrate how to use WCF to build rest Web services. These services use the webget and webinvoke features class to manually define a system for publishing data. If you use the ADO. NET Entity Framework to read data when building a rest web service, you can use the WCF data service to automatically complete most tasks. Using the WCF Data Service templates and components provided by Visual Studio 2010, you can create an abstraction layer provided by the WCF data service and then use this abstraction layer to build a rest web service. You can add a WCF data service to a web application. Program To implement the WCF data service. First, you need to define an entity framework that describes the data published to the outside, and then add the WCF data service to the Web application. The WCF Data Service template is based on system. data. service. dataservice generation-related data service class: The dataservice type parameter is the objectcontext class for the object model. You should use this type to replace the above Code . When the service starts running, the initializeservice method is automatically executed. You can add code for the entity model entity published by the Service and the read permission of the specified client to the initializeservice method. For example, you can indicate that data in a group of entities is read-only, and data in another group of entities is writable. The following exercises describe how to use a WCF Data Service template to create and consume rest Web Services. Exercise: Build a WCF data service that publishes sales information 1. Start Visual Studio and create a new web site using the ASP. Ne empty website template. The website is saved in the solutions \ WCF \ step. By. Step \ chapter15 folder of the local file system. 2. In the solution browser window, click c: \... \ salesdata project. In the Properties window, set the automatic port property to false, and then set the port number to 48000. 3. In the solution browser window, right-click the c: \... \ salesdata project and click Add new project. In the Add new project dialog box, select ADO. Net object data template. In the Name field, enter salesdatamodel. edmx and click Add. When Visual Studio displays a dialog box, Visual Studio is allowed to add the data model to the app_code folder of the project. 4. In the Object Data Model Wizard, on the select model content page, click Generate from database, and then click Next. 5. On the Select data connection page, click Create new connection. In the Connection Properties dialog box, enter. \ sqlexpress in the service name segment. In the select or enter Database Name field, enter adventureworks, and then click OK. 6. On the Select data connection page, confirm that the check box before saving the object connection settings to Web. config is selected. If necessary, change the connection string name to adventureworksentities. Click Next. 7. On the Select data object page, select the contact (person), salesorderdetail (sales), and salesorderheader (sales) tables. For other options, make sure the values are the same as those in the following Table. Then, click "finish.
Option |
Value |
The name of the generated object is singular or plural. |
Selected |
Include foreign key columns in the Model |
Selected |
Model namespace |
Adventureworksmodel < |
Shows the final entity model. When a customer places an order, the order may contain multiple subitems. The salesorderheader table contains the order information (such as the order date, customer ID, and so on), while the salesorderdetail table creates a row of records for each subitem of the order (such as product ID, order quantity, and so on ). 8. Generate a solution. 9. In the solution browser window, add another project to the C: \... \ salesdata project. In the Add new project dialog box, select the WCF Data Service template. Enter salesdataservice. SVC in the Name field and click Add. The Visual Studio template generates a new file named salesdataservice. CS, which contains a class named salesdataservice. As described above, this class inherits the dataservice class. 10. In text editing mode, open the salesdataservice. CS file, and add the following using declaration to the header of the file 11. Delete the comment in the definition of the salesdataservice class. Modify it to the following code: The adventureworksentites class is an objectcontext type automatically generated by the ADO. Net Object Model Wizard. This type is used to access data presented by this entity model. . For security reasons, the WCF Data Service template does not automatically publish any external resources, such as the entity set implemented by the entity model. You must create a policy that allows or disables resource access in the initailizeservice method. This method accepts a dataserviceconfiguration object as its parameter. In this object, you can define resource access policies. 12. In the initializeservice method, delete the annotation and add the following code: setentitysetaccessrule of the dataserviceconfiguration class to specify the access level of each entity defined by the client for the entity model. In this exercise, the WCF data service only allows read-only operations on data. The setentitysetaccessrule method receives two parameters.
- Object set name. In the object model, this parameter is the same as the name of an object set, but the parameter is in the form of a plural number. The value of this parameter can contain * wildcards to indicate all entity sets, although this is not recommended.
- The access permission granted to the object set. The value of this parameter is from the system. Data. Service. entitysetrights Enumeration type. This enumeration defines various read and write access permissions. You can use or operator to merge object set permissions. The following table summarizes the values of the entitysetrights enumeration:
Option |
value |
none |
data access is denied. Default settings for all objects. |
readsingle |
authorize read from a single project in the entity set |
readmultiple |
authorized dataset reading |
writeappend |
authorize a new data item in the dataset |
writereplace |
authorize data replacement |
writedelete |
authorize the deletion of data items from the dataset |
writemerge |
authorize data merging |
allread |
abbreviation of readsingle or readmultiple |
allwrite |
abbreviation of writeappend, writereplace, writedelete, or writemerge |
all |
abbreviation of all read and write operations |
13. Pay attention to the last line of the initializeservice method. Each entity set (contacts, salesorderheaders, and salesorderdetails) may contain thousands of rows of data, and the client program may use a single query to obtain all the data. To prevent unlimited queries from consuming network bandwidth, the setentitypagesize method limits the number of items returned by the query. In this exercise, the value is 25. The first parameter of the setentitypagesize method is used to specify the object name. Likewise, this parameter can use wildcards to indicate that it applies to all objects. However, unlike the setentitysetaccessrule method, the use of wildcard * In setentitypagesize is recommended. 14. Generate a solution. This is what you need to do to build a rest web service using the WCF Data Service template. When a service is running, the dataservice class automatically publishes data based on the relationship between the entity name and the object in the entity model. You can specify the URI that matches the object model architecture. The WCF Data Service provides a series of operations that you can use to selectively obtain data from a single column, Sort data, or perform aggregate Computing Based on data. In the next exercise, you will check these operations. Exercise: test the WCF Data Service salesdata1. open the salesdataservice in text mode in the solution browser window. SVC file, which contains the following code: use the information in the file to determine how to start the salesdataservice service during WCF running. The factory feature indicates that the dataservicehostfactory type is located under the system. Data. Services namespace. This type is provided by the WCF data service, and its purpose is to create a WCF data service instance based on the type specified by the service feature, and call the initializeservice method of this type (salesdataservice) to set a security policy, then start the service. 2. Right-click the salesdataservice. SVC file and click View in the browser. The service starts running. ie starts and displays the following content: 3. Enter http: // localhost: 48000/salesdata/salesdataservice. svc/contacts in the address bar of IE. IE displays the first 25 contacts in the adventureworks database. Data is displayed in atom information source format. As shown in: Note: Due to the different ie configurations, you may need to disable the feed-off view to display data. The method to disable this function is ie-tool-ie option-content tag-Information Source (feeds) -- Set-cancel the start information source reading view. Click OK to close the information source Setting Dialog Box. then click OK to close the IE option dialog box. Then restart IE and enter the http: // localhost: 48000/salesdata/salesdataservice address. SVC/contacts, you will get the result shown. 4. Enter http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderdetials In the IE Address Bar. The first 25 records in the salesorderdetails table are displayed in IE. If you need to access data other than the first 25 pieces of data, the WCF data service allows you to use the $ skip and $ top options in the query to obtain data in blocks. These query options are similar to the Skip and TOP Parameters in section 1. 5. In the IE Address Bar, enter http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderdetials? $ Skip = 50. You will get 25 data records from 51 records in the salesorderdetials table of adventureworks data and display them in IE. Note that the displayed data is listed in ascending order in the salesorderid column, which is the primary key of the salesorderdetails table in the database. 6. In the IE Address Bar, enter http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderdetials? $ Orderby = unitprice. Now the data is sorted in ascending order by unitprice. You can also switch to http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderdetials in descending order of unitprice? $ Orderby = unitprice desc7. the WCF Data Service extracts data from an object. For example, http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderheaders? $ Select = salesorderid, orderdate, customerid, totaldue. This URI forms a ing to restrict the returned data to only the salesorderid, orderdate, customerid, and totaldue columns. You can also specify a prefix to limit that the returned data items are queried based on the values executed using the $ filter option. The following URI shows the salesorderid and totaldue: http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderheaders? $ Select = salesorderid, totaldue & $ filter = customerid EQ 998. the WCF Data Service also easily traverses the relationship between entities and related data values. Enter the following URI in the IE Address Bar: http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderheaders (43682 ). This URI obtains the value of salesorderid based on the primary key column in The adventureworks database, a single salesorderdetial project. If you want to find the details of the order contact, you only need to add "/contact": http: // localhost: 48000/salesdata/salesdataservice after the URI. SVC/salesorderheaders (43682)/contact. To find the Order details, you only need to add/salesorderdetails after the URI:
Http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderheaders (43682)/salesorderdetails. 9. In the IE Address Bar, enter URI: http: // localhost: 48000/salesdata/salesdataservice. svc/salesorderheaders? Expand = contact this query gets the first 25 rows of the salesorderheader, but the $ expand option will make the WCF data service get the information of the contacts associated with each order at the same time. 10. Close IE and return to Visual Studio. You have built a WCF data service and learned how to access it through a web browser. This service uses ASP. NET to develop the web server to host the WCF data service. Of course, now you can easily deploy it on IIS. In addition, you can use webservicehost to build a custom Host Program to host this service, as in section 1 of this chapter. Using a client program to consume the WCF Data Service salesdata is very simple. Using this service, you can perform many complex queries. Although the atompub protocol is widely accepted, it is difficult to understand and convert the data formats returned by the protocol. You cannot expect end users to understand the data formats. Fortunately, you can consume the WCF data service by building a client program, so that the server data is presented to the end user in a more understandable format. To achieve this goal, you must generate a client library for the WCF data service. The client acts as a proxy for the WCF data service to read data published by the WCF data service. You can use either of the following methods to generate a client library: Use the datasvcutil utility in the command line, or add a service reference wizard in Visual Studio. If datasvcutil is used, open the Visual Studio command line tool and enter the following command (Red Line) when the WCF data service is running: This command creates a table named salesclient. CS code file, which contains the method used by the client program to send requests to the WCF data service. The client library discloses data through a series of sets and attributes that are closely related to the entity model in the WCF data service. When a client program tries to obtain data from these sets and attributes, the client Library generates the corresponding HTTP requests and sends them to the service. When the service returns data, the client database converts the returned data in the atompub format to A. NET Framework set and type, so that the client program can easily use these sets and types. In the following exercise, you will build a client program that connects to the salesdata service and then execute the same request when using IE to access the service. Exercise: Create a test client program for the salesdata service. 1. Add a new console program project to the salesdata solution in Visual Studio. And name it salesdataclient. The project is saved in the WCF \ step. By. Step \ solutions \ chapter15 \ salesdata folder. 2. In the solution browser window, right-click the salesdataclient project and click Add service reference. In the add service reference dialog box, click automatic detection. Find the salesdata service, enter salesdataservice in the namespace field, and click OK. In a rough view, the add data web service reference dialog box is consistent with the add soap web service reference. However, Visual Studio can identify the data web service, and then the client library generated accordingly matches the data published by the data service without matching the method corresponding to the soap web service operation. The client library of the WCF data service contains a class that inherits the dataservicecontext type. This class has one or more common attributes of the dataservicequery type. This class name is generally the same as the name of the object objectcontext on which the WCF data service depends. For example, the salesdataservice service uses an objectcontext object named adventureworksentities to connect to the relevant entity model. Therefore, the dataservicecontext type generated for the client library is also named adventureworksentities. The dataservicecontext class executes a role similar to the objectcontext class in the object framework. The client connects to the data source through the dataservicecontext object, and then obtains data from the dataservicequery attribute published by the data service. Each dataservicequery attribute is a generic set that displays data from the relevant entities provided for the WCF data service. In the salesdataservice service, the entity model allows you to read the contact, salesorderheader, and salesorderdetails data tables in the adventureworks database. In the client library, the adventureworksentities class also contains the dataservicequery type attributes named contacts, salesorderheader, and salesorderdetails. The client library also provides definitions of the types (contact, salesorderheader, and salesorderdetail) contained in each dataservicequery set. The client first executes a LINQ query on the dataservicequery set, and then creates an appropriate HTTP request in the client library to obtain the corresponding data from the service. After obtaining matched data, the WCF Data Service fills in the dataservicequery set. The client finally iterates the set and obtains data from each subitem. 3. open program in the salesdataclient project in text editing mode. CS file, add the following declaration to the top of the file: 4. in the main method of the program class, add the following code: This declaration connects to the salesdata service. As previously described, the adventureworksentities type is a dataservicecontext object that acts as a proxy for sending requests to salesdata. The URI specified in the constructor is the address of the salesdata service. 5. Add the following code to the main method. The above code obtains the Order details from the salesdata service and displays the last name and name of each contact. Note that when you reference the contracts set in the adventureworksentities object, the client library sends the corresponding http get request (http: // localhost: 48000/salesdata/salesdataservice. SVC/contacts) to the salesdata service, and then fill in the contracts set. This request has the same restrictions as using IE, which means that this request only returns the information of the first 25 contacts. 6. Add the following code to the main method: the above Code is similar to the Code in the previous step, but it is used to query the salesorderdetails set. This behavior causes the adventureworksentities object to send an http get request (http: // localhost: 48000/salesdata/salesdataservice. SVC/salesorderdetails) to the salesdata service. Similarly, this request only returns the first 25 data records. 7. Add the following life to the main method. The above code obtains 25 salesorderdetails records starting from 51st records in the adventureworks database. 8. Add the following code to the main method: the above Code gets the salesorderdetails record sorted by unit price. 9. Add the following code to the main method. The above Code uses the LINQ syntax to filter and process data, and lists the salesorderid and totaldue fields of all customer orders with the customer ID 99. 10. Add the following code to the main method: the code snippet above gets the contact information of the order and each order. 11. regenerate the solution. Now you can test the client program. However, before the test, it is very useful to configure tracing for the salesdata service. After tracing is enabled, you can view the details of the request sent by the client program to the service. Exercise: configure the trail and test the salesdata service in the client program. 1. Open Web. config in the C: \... \ salesdata project using the WCF Service configuration editor. 2. In the configuration panel, click the diagnosis node. In the diagnosis panel, click the start tracking link. 3. Click the link after the tracking level to enter the tracking Settings dialog box, set the tracking level to information, and then click OK. 4. Click the servicemodeltracelistener link. In the listener Settings dialog box, set the log file attribute to web_tracelog.svclog and its path to the solutions \ WCF \ step. By. Step \ chapter15 folder. then click OK. 5. Save the configuration file and close the WCF Service configuration editor. 6. In the solution window, open the Properties window of the salesdata solution, set the c: \... \ salesdata and salesdataclient projects to be the Start Project of the salesdata solution, and click OK. 7. Start the solution in non-adaptive mode. Minimize Ie When ie appears. In the console window of the client program, confirm that the first 25 customers are displayed: 8. Press enter, and then confirm that the first 25 salesorderdetails continue to appear. The order numbers for these records range from 43659 to 43661 (each order contains multiple subitems ). 9. Press enter and confirm that a different salesorderdetial data record set is displayed in the window. The number of this batch of orders ranges from 43662 to 43666.10. Press enter again, And salesorderdetails continues to be sorted in ascending order according to the unitprice field. 11. Press enter again, And salesorderdetails will continue to sort by unitprice field drop. 12. Press enter again and you will see that salesorderid and totaldue are displayed in the window, with order numbers from 43682 to 69485. 13. Press enter to view the order number and the list of Customer names corresponding to each order. 14. Press enter to end the program and close the console window of the client. 15. In the Windows taskbar, right-click ASP. NET development server and click STOP. 16. Start the service tracing viewing tool and open web_tracelog.svclog in the solutions \ WCF \ step. By. Step \ chapter15 folder. 17. In the service tracking and viewing tool, click the behavior tag and then click the first action named "Process Action. On the right panel, select the "received a message over a channel" project. In the lower right pane, scroll the scroll bar of the corresponding content of the label until the to field is found. The URI corresponding to this field is http: // localhost: 48000/salesdata/salesdataservice. svc/contacts. This URI is generated for the first test in the client program. 18. On the behavior panel, the second process action is performed. On the right panel, click "received a request over a channel", and then in the panel below, confirm that the to value is http: // localhost: 48000/salesdata/salesdataservice. SVC/salesorderdetails19. repeat the above process to verify the other five addresses. 20. Close the service tracing viewer and return to Visual Studio. You may want to build a client program to modify data using the WCF data service. The client library implements a model that allows you to locally modify data associated with entities published by the Service, then, the savachanges method of the dataservicecontext object used to connect the Service sends these changes to the Service in batches. You must note that the WCF data service must explicitly specify an appropriate access permission in the initializeservice method to allow changes to the entity. The following code shows how to update a contacts object. The following code shows you how to create a new contract object. When you create a client library for the WCF data service, the add service wizard generates a static create method for each object type. This method contains parameters that make the object non-empty. The wizard also generates an addto method for each object. You can call this method to add the newly created object to the appropriate set object of dataservicecontext. Finally, call the savechanges method to submit the changes to the service. The savechanges method generates an http post request and transmits the newcontact data as the message body to the service. If you modify an object, first send a query to the WCF data service, change the field to be changed, then call the updateobject method of the dataservicecontext object to notify the change, and finally call savechanges to send the change to the service. The dataservicecontext object generates an http put request or an HTTP merge message for each modified object, and then transmits the object data to the service as the message body. For example, the following code shows how to change the email address of a client encoded as 99: If you want to delete an object, the method is similar to that of updating an object. Obtain an object, call the dataseobject method of the dataservicecontext object, and call the savechanges method. The savechanges method generates an HTTP Delete message and sends it to the WCF data service. The following code deletes a customer code 101. Note that the savechanges method is called in the preceding three examples. If you want to perform multiple changes (insert, update, delete, or union of multiple operations), you only need to call savechanges at the last time. Dataservicecontext objects track the status of all objects in a variable set within them, and then generate the corresponding http post, put, merge, and delete messages for each change, then, send these messages to the WCF data service one by one. If you want further optimization, you can specify the savechangesoptions. replaceonupdate. Batch parameter in the savechanges method. This flag will make the dataservicecontext object send all the changes in a separate message. This method reduces the number of network traffic and improves the client performance. Batch Processing can also run as a transaction, and all operations can either succeed or fail. This is very helpful for designing data consistency in applications. Each batch of requests generates a separate HTTP Response to the client. The response message contains the response results of all operations in the batch. If any operation fails, the response message only contains the response result indicating that the batch operation failed. When using any multi-user data program, concurrency exceptions may occur. Therefore, you must correctly process the concurrency in the client. In addition, you also need to ensure data consistency when modifying the associated data. Handle exceptions in the client segment when a client program sends a request to the WCF data service, the request may fail for multiple reasons. For example, a client program may attempt to access unauthorized data or execute a query that is not allowed by the Service. If the failure is caused by the way the client program interacts with the Service (the opposite is caused by other reasons such as network failure), the service throws a dataserviceexception. The dataserviceexception type is a serializable exception. It is designed to allow the client to communicate with the reason why the WCF data service fails. When the client receives a dataserviceexception, the client database deserializes the exception into a dataserviceclientexception object, and then passes the object to the client program. If an exception occurs when your program executes a query, the dataserviceclientexception exception will be encapsulated in the dataservicequeryexception object, and the exception message of dataserviceclientexcaption will be "error occurred during request execution ". You can read the dataserviceclientexception exception object and obtain the cause of the exception by checking the innerexcpetion attribute of the dataservicequeryexception object. If a client program sends a request instead of a query, when the WCF data service encounters an exception, the service returns a dataservicerequestexception. The client program should capture dataservicequeryexception during query execution, and capture dataservicerequestexcaption exceptions when performing other types of operations (such as modifying data. The client program should also capture dataserviceclientexception exceptions to handle other exceptions thrown by the WCF data service when performing other types of operations.