Feed Customization (WCF Data Services)
You may have an application scenario that requires that the property data returned by the data service be serialized in a customized manner rather than in the standard feed format. With OData, you can customize the serialization in a data feed so that properties of an entity may be mapped to unused elements and attributes of an entry or to custom elements of an entry in the feed.
|Feed customization is only supported for Atom feeds. Custom feeds are not returned when the JSON format is requested for the returned feed.|
With WCF Data Services, you can define an alternate entity-property mapping for an Atom payload by manually applying attributes to entity types in the data model. The data source provider of the data service determines how you should apply these attributes.
|When you define custom feeds, you must guarantee that all entity properties that have custom mappings defined are included in the projection. When a mapped entity property is not included in the projection, data loss might occur. For more information, see Query Projections (WCF Data Services).|
Customizing Feeds with the Entity Framework Provider
The data model used with the Entity Framework provider is represented as XML in the .edmx file. In this case, the attributes that define custom feeds are added to the EntityType and Property elements that represent entity types and properties in the data model. These feed customization attributes are not defined in [MC-CSDL]: Conceptual Schema Definition File Format, which is the format that the Entity Framework provider uses to define the data model. Therefore, you must declare feed customization attributes in a specific schema namespace, which is defined as
m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata". The following XML fragment shows feed customization attributes applied to Property elements of the
Products entity type that define the
<Property Name="ProductName" Type="String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false" m:FC_TargetPath="SyndicationAuthorName" m:FC_ContentKind="text" m:FC_KeepInContent="true" /> <Property Name="UnitsInStock" Type="Int16" m:FC_TargetPath="UnitsInStock" m:FC_NsPrefix="Northwind" m:FC_NsUri="http://schemas.examples.microsoft.com/dataservices" m:FC_KeepInContent="true" /> <Property Name="ReorderLevel" Type="Int16" m:FC_TargetPath="UnitsInStock/@ReorderLevel" m:FC_NsPrefix="Northwind" m:FC_NsUri="http://schemas.examples.microsoft.com/dataservices" m:FC_KeepInContent="false" />
These attributes produce the following customized data feed for the
Products entity set. In the customized data feed, the
ProductName property value is displayed in both in the author element and as the
ProductName property element, and the
UnitsInStock property is displayed in a custom element that has its own unique namespace and with the
ReorderLevel property as an attribute:
<entry xml:base="http://localhost:12345/Northwind.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"> <id>http://localhost:12345/Northwind.svc/Products(1)</id> <title type="text" /> <updated>2009-10-02T05:09:44Z</updated> <author> <name>Chai</name> </author> <link rel="edit" title="Products" href="Products(1)" /> <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Order_Details" type="application/atom+xml;type=feed" title="Order_Details" href="Products(1)/Order_Details" /> <category term="NorthwindModel.Products" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:ProductID m:type="Edm.Int32">1</d:ProductID> <d:ProductName>Chai</d:ProductName> <d:UnitsInStock m:type="Edm.Int16">39</d:UnitsInStock> <d:SupplierID m:type="Edm.Int32">1</d:SupplierID> <d:CategoryID m:type="Edm.Int32">1</d:CategoryID> <d:QuantityPerUnit>10 boxes x 20 bags</d:QuantityPerUnit> <d:UnitPrice m:type="Edm.Decimal">18.0000</d:UnitPrice> <d:UnitsOnOrder m:type="Edm.Int16">0</d:UnitsOnOrder> <d:Discontinued m:type="Edm.Boolean">false</d:Discontinued> </m:properties> </content> <Northwind:UnitsInStock Northwind:ReorderLevel="10" xmlns:Northwind="http://schemas.examples.microsoft.com/dataservices">39</Northwind:UnitsInStock> </entry>
For more information, see How to: Customize Feeds with the Entity Framework Provider (WCF Data Services).
|Because extensions to the data model are not supported by the Entity Designer, you must manually modify the XML file that contains the data model. For more information about the .edmx file that is generated by the Entity Data Model tools, see .edmx File Overview (Entity Framework).|
Custom Feed Attributes
The following table shows the XML attributes that customize feeds that you can add to the conceptual schema definition language (CSDL) that defines the data model. These attributes are equivalent to the properties of the EntityPropertyMappingAttribute used with the reflection provider.
Indicates the type of the content. The following keywords define syndication content types.
textThe property value is displayed in the feed as text.
htmlThe property value is displayed in the feed as HTML.
xhtmlThe property value is displayed in the feed as XML-formatted HTML.
These keywords are equivalent to the values of the SyndicationTextContentKind enumeration used with the reflection provider.
This attribute is not supported when the FC_NsPrefix and FC_NsUri attributes are used.
When you specify a value of xhtml for the FC_ContentKind attribute, you must ensure that the property value contains properly formatted XML. The data service returns the value without performing any transformations. You must also ensure that any XML element prefixes in the returned XML have a namespace URI and prefix defined in the mapped feed.
Indicates that the referenced property value should be included both in the content section of the feed and in the mapped location. Valid values are true and false. To make the resulting feed backward-compatible with earlier versions of WCF Data Services, specify a value of true to make sure that the value is included in the content section of the feed.
The namespace prefix of the XML element in a non-syndication mapping. This attribute must be used with the FC_NsUri attribute and cannot be used with the FC_ContentKind attribute.
The namespace URI of the XML element in a non-syndication mapping. This attribute must be used with the FC_NsPrefix attribute and cannot be used with the FC_ContentKind attribute.
The path of the property of the entity to which this feed mapping rule applies. This attribute is only supported when it is used in an EntityType element.
The SourcePath property cannot directly reference a complex type. For complex types, you must use a path expression where property names are separated by a backslash (/) character. For example, the following values are allowed for an entity type
The SourcePath property cannot be set to a value that contains a space or any other character that is not valid in a property name.
The name of the target element of the resulting feed to map the property. This element can be an element defined by the Atom specification or a custom element.
The following keywords are predefined syndication target-path values that point to specific location in an OData feed.
A custom property element.When mapping to a custom element, the target must be a path expression in which nested elements are separated by a backslash (/) and attributes are specified by an ampersand (@). In the following example, the string
When the target is a custom element name, the FC_NsPrefix and FC_NsUri attributes must also be specified.
<Property Name="ReorderLevel" Type="Int16" m:FC_TargetPath="UnitsInStock/@ReorderLevel" m:FC_NsPrefix="Northwind" m:FC_NsUri="http://schemas.examples.microsoft.com/dataservices" m:FC_KeepInContent="false" />
These keywords are equivalent to the values of the SyndicationItemProperty enumeration used with the reflection provider.
|Attribute names and values are case-sensitive. Attributes can be applied either to the EntityType element or to one or more Property elements, but not to both.|
Customizing Feeds with the Reflection Provider
To customize feeds for a data model that was implemented by using the reflection provider, add one or more instances of the EntityPropertyMappingAttribute attribute to the classes that represent entity types in the data model. The properties of the EntityPropertyMappingAttribute class correspond to the feed customization attributes that are described in the previous section. The following is an example of the declaration of the
Order type, with custom feed mapping defined for both properties.
|The data model for this example is defined in the topic How to: Create a Data Service Using the Reflection Provider (WCF Data Services).|
[EntityPropertyMappingAttribute("Customer", SyndicationItemProperty.AuthorName, SyndicationTextContentKind.Plaintext, true)] [EntityPropertyMapping("OrderId", SyndicationItemProperty.Title, SyndicationTextContentKind.Plaintext, false)] [DataServiceKeyAttribute("OrderId")] public class Order
These attributes produce the following customized data feed for the
Orders entity set. In this customized feed, the
OrderId property value displays only in the title element of the entry and the
Customer property value displays both in the author element and as the
Customer property element:
<entry xml:base="http://localhost:12345/OrderItems.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"> <id>http://localhost:12345/OrderItems.svc/Orders(0)</id> <title type="text">0</title> <updated>2009-07-25T21:11:11Z</updated> <author> <name>Peter Franken</name> </author> <link rel="edit" title="Order" href="Orders(0)" /> <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Items" type="application/atom+xml;type=feed" title="Items" href="Orders(0)/Items" /> <category term="CustomDataService.Order" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:Customer>Peter Franken</d:Customer> </m:properties> </content> </entry>
For more information, see How to: Customize Feeds with the Reflection Provider (WCF Data Services).
Customizing Feeds with a Custom Data Service Provider
Feed customization for a data model defined by using a custom data service provider is defined for a resource type by calling the AddEntityPropertyMappingAttribute on the ResourceType that represents an entity type in the data model. For more information, see Custom Data Service Providers (WCF Data Services).
Consuming Custom Feeds
When your application directly consumes an OData feed, it must be able to process any customized elements and attributes in the returned feed. When you have implemented custom feeds in your data model, regardless of the data service provider, the $metadata endpoint returns custom feed information as custom feed attributes in the CSDL returned by the data service. When you use the Add Service Reference dialog or the datasvcutil.exe tool to generate client data service classes, the customized feed attributes are used to guarantee that requests and responses to the data service are handled correctly.
Feed Customization Considerations
You should consider the following when defining custom feed mappings.
The WCF Data Services client treats mapped elements in a feed as empty when they contain only whitespace. Because of this, mapped elements that contain only whitespace are not materialized on the client with the same whitespace. To preserve this whitespace on the client, you must set the value of KeepInContext to true in the feed mapping attribute.
Feed customization has the following OData protocol versioning requirements:
Feed customization requires that both the client and data service support version 2.0 of the OData protocol and later versions.
For more information, see Data Service Versioning (WCF Data Services).