C# config.SetEntitySetAccessRule"Customers", EntitySetRights.AllRead; Visual Basic config.SetEntitySetAccessRule"Customers", EntitySetRights.AllRead Call this method for each entity set
Trang 1This setting indicates which features are available to clients based on the release version of
those features For example, the ability to project properties in a query (with the Select
ex-tension method) is not available before Version 2 (Version 2 is the current release level as of this writing.)
For entity permissions, the key configuration setting is the DataServiceConfig.SetEntitySet
AccessRule method, as used in the previous example You pass this method the name of an
entity set and a set of rights from the EntitySetRights enumeration.
C#
config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);
Visual Basic
config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead)
Call this method for each entity set you plan to make available or use an asterisk (“*”) as the entity name to simultaneously set rights for all entities at once Table 22-1 lists the rights available for each entity set Combine multiple rights together with a bitwise-Or operator to use a combination of rights
TABLE 22-1 Rights Available for Data Service Entities
EntitySetRights Member Description
None Removes all access rights for the indicated entity set This is the
default for all model entities.
ReadSingle Clients can query a specific entity instance by its primary key.
ReadMultiple Clients can retrieve a set of all entities in an entity set This right
does not permit selection of an individual entity by primary key, although a filter may retrieve similar results.
WriteAppend Clients can add new entity records to an entity set.
WriteReplace Clients can update entities When updating an individual entity,
only those new property values supplied by the client are updated Other property values are cleared or set to their default values The client replaces the original record completely.
WriteDelete Clients can delete existing entity records.
WriteMerge Clients can update entities When updating an individual entity,
only those new property values supplied by the client get
updat-ed Other property values are left unchangupdat-ed The client modifies the existing record in-place.
AllWrite Combination of all the write-specific rights.
AllRead Combination of all the read-specific rights.
All Combination of all the read-specific and write-specific rights.
Trang 2Chapter 22 Providing RESTful Services with WCF Data Services 377
If your entity model exposes database-side or model-defined procedures, you can set their
rights using the DataServiceConfig.SetServiceOperationAccessRule method.
Accessing a Data Service using REST
REST uses standard HTTP verbs to retrieve data and make updates to entities Data queries
that return content in either AtomPub (the default) or JSON format use the GET verb Data updates use the PUT, POST, MERGE, and DELETE verbs, depending on the update operation.
Note This section documents some typical examples of querying and updating entities through
REST For detailed information and examples, visit the Open Data Protocol web site at www.
odata.org.
Querying Entities with REST
REST queries use the HTTP GET verb to identify the content to retrieve The easiest way to use GET is to build a URI that includes all the query components and enter it in the address
bar of a web browser In the exercise shown earlier in this chapter, the running service
dis-played its available entity sets by making an address-based GET request through the browser.
http://example.com/SalesOrder.svc/
Note In lieu of an exercise that demonstrates REST queries, run the service created earlier in this chapter and use its web browser session to test the URIs documented throughout this section.
REST queries start with this URI base and add additional entity information and operators to adjust the query The simplest query involves appending the name of an entity set to the URI base
http://example.com/SalesOrder.svc/Customers
Assuming that the Customers entity set is enabled for multiple-read access, this request re-turns all available entities in AtomPub format
Trang 3<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xml:base="http://localhost:49712/SalesOrder.svc/"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title type="text">Customers</title>
<id>http://localhost:49712/SalesOrder.svc/Customers</id>
<updated>2010-08-11T01:16:42Z</updated>
<link rel="self" title="Customers" href="Customers" />
<entry>
<id>http://localhost:49712/SalesOrder.svc/Customers(1L)</id>
<title type="text" />
<updated>2010-08-11T01:16:42Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Customer" href="Customers(1L)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/
dataservices/related/State" type="application/atom+xml;type=entry"
title="State" href="Customers(1L)/State" />
<link rel="http://schemas.microsoft.com/ado/2007/08/
dataservices/related/OrderEntries" type="application/atom+xml;
type=feed" title="OrderEntries" href="Customers(1L)/OrderEntries" />
<category term="SalesOrderModel.Customer"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int64">1</d:ID>
<d:FullName>Coho Vineyard</d:FullName>
<d:Address1>123 Main Street</d:Address1>
<d:Address2 m:null="true" />
<d:City>Albany</d:City>
<d:StateRegion m:type="Edm.Int64">32</d:StateRegion>
<d:PostalCode>85000</d:PostalCode>
<d:PhoneNumber m:null="true" />
<d:WebSite>http://www.cohovineyard.com</d:WebSite>
<d:AnnualFee m:type="Edm.Decimal">200.0000</d:AnnualFee>
</m:properties>
</content>
</entry>
<entry>
<! Another entry here >
</entry>
<! And so on >
</feed>
Note Internet Explorer 8, the latest version of Microsoft’s web browser (as of this writing), ap-plies a user-friendly interface to AtomPub feed content that hides the underlying XML You can still access the XML by viewing the page source Another option is to disable the interface con-version on all feeds To do this, select Tools | Options from the menu in Internet Explorer On the Options dialog box, select the Content tab and click the Settings button in the Feeds And Web Slices section When the Feed And Web Slice Settings dialog box appears, clear the Turn On Feed Reading View field.
Trang 4Chapter 22 Providing RESTful Services with WCF Data Services 379
This content includes an <entry> tag for each returned entity, with distinct XML tags for each
of the entity’s properties This is the typical format any time your query is based on an entity set Queries to retrieve a single entity append the primary key in parentheses at the end of the URI
http://example.com/SalesOrder.svc/Customers(3L)
This result, as with most results that return a single entity instance, uses the <entry> tag as the top-level XML tag, instead of <feed> Otherwise, the content is generally the same as the
multi-entity results
Note The schema used by REST defines formats for literals, such as the primary key value For example, text-based primary keys must be surrounded by single quotes If your primary key is a long (64-bit) integer, you must add an uppercase “L” to the end of the number Otherwise, the WCF Data Service will not succeed in locating the record.
To return content in JSON format instead of AtomPub, append the $format=json system
query option to the URI
http://example.com/SalesOrder.svc/Customers(3L)?$format=json
If you build your own GET packet, you can also set the accept request header to the
applica-tion/json MIME type.
By default, a query for a single entity returns all properties for that entity To limit the result
to a single scalar property, append the property name to the query
http://example.com/SalesOrder.svc/Customers(1L)/FullName
This query returns simplified XML content that contains the requested data:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<FullName xmlns="http://schemas.microsoft.com/ado/2007/
08/dataservices">Coho Vineyard</FullName>
The $value query option removes the XML wrapper and returns only the data:
http://example.com/SalesOrder.svc/Customers(1L)/FullName/$value
Trang 5This query returns just the retrieved content:
Coho Vineyard
Navigation properties work just like scalar properties within the URI, although they return results formatted more like a multi-entity feed
http://example.com/SalesOrder.svc/Customers(1L)/OrderEntries
Several query options modify the returned returns These options translate into Entity
Framework extension methods that filter, project, or sort the results The $orderby option
sorts multi-entity results by the indicated properties or expressions
http://example.com/SalesOrder.svc/Customers?$orderby=FullName desc
The $filter and $select options limit and project the results using the instructions provided
after the equal signs
http://example.com/SalesOrder.svc/Customers/
?$filter=City eq 'Albany'&$select=ID,FullName
Most traditional operators don’t work in REST; instead, you use a set of abbreviated opera-tors, such as:
■
■ Math operators: add, sub, mul, div, and mod
■
■ Logical operators: and, or, not
■
■ Comparison operators: eq, ne, lt, gt, le, ge
For example, the following query returns orders that have a post–8.75 percent taxed amount
of 500 or more
http://example.com/SalesOrder.svc/OrderEntries?$filter=
(Subtotal mul 1.0875) ge 500
Trang 6Chapter 22 Providing RESTful Services with WCF Data Services 381
Other query options include the $top and $skip operators that work like their extension method counterparts The $count option returns the number of records in the entity or
query
http://example.com/SalesOrder.svc/Customers/$count
The query returns just the numeric count as a string, without any XML wrapper
Note The $count operator is disabled by default To enable it, set the config.
DataServiceBehavior.AcceptCountRequests property to True in the InitializeService method.
The $expand option returns a related set of entities for a result For instance, the follow-ing query returns the specified Customer entity, plus that customer record’s associated
OrderEntries entities as a <feed> tag subordinate to the customer’s <entry> tag block.
http://example.com/SalesOrder.svc/Customers(1L)?$expand=OrderEntries
Malformed query strings result in an HTTP error code 400: “Bad Request.” In all cases, the query options, operators, entity names, and all other elements of the query are
case-sensitive
For more query examples and to discover other query options and formats, see the
“Addressing Resources (WCF Data Services)” and “Query Functions (WCF Data Services)”
pages in the Visual Studio online help The www.odata.org web site also contains numerous
query examples, plus full documentation on the format of all query components
Updating Entities with REST
REST also includes features that let you modify the entities exposed by a WCF Data Service— assuming that write permissions have been enabled for the entities Creating a REST request
that updates content is a little more involved than writing a simple GET-based query Beyond
the basic URI, you must also add details on what to update in the HTTP request’s payload section
Note This section provides general information on building REST updates Specifics on how to package and transmit the request will vary depending on the client libraries used to communi-cate with the service Specific implementation details on transmitting HTTP requests are beyond the scope of this book.
Trang 7To add a new entity, you send a POST request that includes all new property values in AtomPub or JSON format The following AtomPub-formatted request adds a new Customer
entity to the database via the data service:
POST /SalesOrder.svc/Customers HTTP/1.1
Host: example.com
DataServiceVersion: 1.0
MaxDataServiceVersion: 2.0
accept: application/atom+xml
content-type: application/atom+xml
Content-Length: 937
<?xml version="1.0" encoding="utf-8"?>
<Entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title type="text"></title>
<updated>2010-08-31T23:45:12Z</updated>
<author>
<name />
</author>
<category term="SalesOrderModel.Customer"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:FullName>Southridge Video</d:FullName>
<d:Address1>789 Washington Parkway</d:Address1>
<d:City>Phoenix</d:City>
<d:StateRegion m:type="Edm.Int64">3</d:StateRegion>
<d:PostalCode>90909</d:PostalCode>
<d:WebSite>http://www.southridgevideo.com</d:WebSite>
<d:AnnualFee m:type="Edm.Decimal">350.0000</d:AnnualFee>
</m:properties>
</content>
</Entry>
When the new record is successfully inserted, the service returns an image of the new record
in AtomPub or JSON format (as indicated by the accept request header) and an HTTP status
code of 201
Updates to existing entities follow the same pattern, but use the PUT verb instead of POST
This action replaces the existing record with the new content To perform a merge operation—
modifying just those properties specified in the request payload—use the MERGE verb in-stead of PUT.
MERGE /SalesOrder.svc/Customers(4L) HTTP/1.1
Trang 8Chapter 22 Providing RESTful Services with WCF Data Services 383
Updates to a single property use a shortened form of the PUT request The following code updates the AnnualFee property for a Customer entity:
PUT /SalesOrder.svc/Customers(4L)/AnnualFee HTTP/1.1
Host: example.com
DataServiceVersion: 1.0
MaxDataServiceVersion: 2.0
accept: application/xml
content-type: application/xml
Content-Length: 259
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<d:AnnualFee xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
m:type="Edm.Decimal">400.0000</d:AnnualFee>
An even shorter form uses the $value query option to indicate that the payload is stripped
down to just the bare data content
PUT /SalesOrder.svc/Customers(4L)/AnnualFee/$value HTTP/1.1
Host: example.com
DataServiceVersion: 1.0
MaxDataServiceVersion: 2.0
accept: application/xml
content-type: application/xml
Content-Length: 3
400
To remove an entity, issue an HTTP DELETE request, including the query path to the entity in
the request
DELETE /SalesOrder.svc/Customers(4L) HTTP/1.1
An HTTP return code of 200 indicates success
Trang 9This chapter provided a brief introduction to WCF Data Services and REST, which are service-oriented programming tools that make it simple to expose Entity Framework model content
to fully disconnected, remote consumers WCF Data Services is an implementation of the Open Data Protocol (OData) standard that provides a consistent request mechanism for dif-ferent types of server-hosted content
REST combines the power of traditional database queries with the simplicity of web addresses
By forming simple text-based HTTP requests, you can query or update data from a WCF Data Service without the need to know or understand the underlying structure of the data
Chapter 22 Quick Reference
Expose an EF model as a service Create an ASP.NET web application project.
Add the entity model to the project.
Add a WCF Data Service item to the project.
Change the generic class definition of the new service to include the entity container name.
Modify the service’s InitializeService method to set access
rights.
Make the svc file available on a web server.
Provide read access to an entity Add the EF model and WCF Data Service to an ASP.NET
project.
Locate the data service’s InitializeService method.
In that method, call config.SetEntitySetAccessRule, passing
it the name of the entity set and the enumerated value
EntitySetRights.AllRead.
Issue a REST query for a single entity instance Create an HTTP GET request.
In the URI, after the path to the svc hosted file, add /xxx(ID), where “xxx” is the entity set name, and “ID” is the primary key of the instance.
Trang 10385
Symbols
$filter option 380
$orderby option 380
$select option 380
$value option 383
* (asterisk) symbol, using as
entity name 376
.csdl file extensions 217
{ } (curly braces), building
custom collections
using 254
.dbml file extensions 336
.edmx file extensions 217,
218, 325
= (equal sign), comparing
columns to literal
values using 63
>= (greater than or equal
to sign)
comparing columns to
lit-eral values using 63
in Where clause (LINQ)
296
> (greater than sign)
comparing columns to
lit-eral values using 63
<> (inequality sign)
comparing columns to
lit-eral values using 63
<= (less than or equal to
sign)
comparing columns to
lit-eral values using 63
< (less than sign)
comparing columns to
lit-eral values using 63
in Where clause (LINQ)
296
.NET applications, types of configuration files 13
.NET developers, ADO.NET and 3
.NET Framework
See also Entity
Framework (EF) ADO.NET in 213 connection string builders
in 126 data providers 126–127 strongly typed DataSets
in 214 NET objects, tools 8 ( ) parentheses
in expression evaluation 63
using in Where clause (LINQ) 296
@-prefixed placeholders
155, 157, 161, 167, 178
‘ ‘ (single quotes) using BINARY keyword with 250
using GUID keyword with 250
using strings with 249
\SQLEXPRESS appended with SQL Server 2008 Express Edition instances 12 ssdl file extensions 217, 325
- (subtraction) operators, in Entity SQL language 250
.svc service files 370 tt (text templates) file ex-tensions 241
.xsd file extensions created from Connection Wizard 14
creating tables with mouse 28
A
ABS (absolute value) 251 AcceptChanges method
48, 57, 99 Access, provider class li-braries for 126 ACID
rules 192–193 with transactions 204 Acos function 323 acronym, ADO.NET 4 Add Connection dialog box 12
Add Entity dialog box 231–232
Add Function Import dialog box 233–234
Add functions
in Entity SQL language 251
in LINQ to Entities 322 adding
aggregate columns 94–95
BindingNavigator control
to Windows forms 353
calculated columns 71 connections to databases 32
data columns 21–28 data rows to tables 37–41 Entity Framework model
to projects 243
Index