Modifying a Data Contract


The methods in a service contract can take parameters and return values. The data for these parameters and return values is included in the SOAP messages that pass between the client application and service. SOAP messages encode data values as tagged XML text. The WCF runtime uses the built-in XML serialization features of the .NET Framework to serialize and deserialize primitive .NET Framework data types, such as integers, real numbers, or even strings. For more complex structured types, the service must specify the exact format for the serialized representation; there could be several ways to depict the same structured data as XML. You define structured types by using data contracts. The WCF runtime can then use data contract serializer (an instance of the DataContractSerializer class) to serialize and deserialize these types.

Using a data contract, you can specify exactly how the service expects the data to be formatted as XML. The data contract is used by a data contract serializer in WCF client applications to describe how to serialize the data for parameters into XML, and by a data contract serializer in the service to deserialize the XML back into data values that it can process. Values returned by a service are similarly serialized as XML and transmitted back to the client application, which deserializes them.

Data Contract and Data Member Attributes

You saw in Chapter 1 how to define a simple data contract representing products in the AdventureWorks database. To remind you, this is what the data contract looks like:

 // Data contract describing the details of a product [DataContract] public class Product {     [DataMember]     public string Name;     [DataMember]     public string ProductNumber;     [DataMember]     public string Color;     [DataMember]     public decimal ListPrice; }

Tagging a class with the DataContract attribute marks it as serializable by using the data contract serializer. The data contract serializer will serialize and deserialize each member of the class marked with the DataMember attribute. In the example shown here, the members of the class are .NET Framework primitive types, and the serializer uses its own built-in rules to convert these types into a form that can be included in an XML message, like this:

 <GetProductResponse xmlns="http://adventure-works.com/2006/07/04">   <GetProductResult   xmlns:d4p1="http://schemas.datacontract.org/2004/07/Products"   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">     <d4p1:Color>N/A</d4p1:Color>     <d4p1:ListPrice>4.9900</d4p1:ListPrice>     <d4p1:Name>Water Bottle - 30 oz.</d4p1:Name>     <d4p1:ProductNumber>WB-H098</d4p1:ProductNumber>   </GetProductResult> </GetProductResponse>

If any of the members of a data contract are themselves structured types, they should also be marked with the DataContract attribute. The data contract serializer can then recursively apply its own serialization and deserialization process to these members.

The DataContract and DataMember attributes have optional properties that you can use to tailor the way in which the data contract serializer performs its work. You will investigate some of these properties in the exercises in this section.

Change the order of members in the Product data contract

  1. Using Visual Studio 2005, open the solution file image from book ProductsService.sln located in the Microsoft Press\WCF Step By Step\Chapter 6\ProductsServiceV2 folder under your \My Documents folder.

    This solution contains the implementation of the ProductsService service providing two versions of the service contract, as described earlier. The client application still uses version 1 of the service contract.

  2. Open the image from book ProductsService.cs file in the ProductsService project and locate the Product class. Note that the order of the members of this class is Name, ProductNumber, Color, and ListPrice.

  3. Using Windows Explorer, delete the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  4. In Visual Studio 2005, start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests should run successfully.

  5. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop, and then close the form.

  6. Return to the Service Trace Viewer, and open the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  7. In the left pane, click the Message tab. Click the fourth message in the http://adventureworks.com/2006/07/04 namespace. This is the GetProductResponse message sent by the service to the client when replying to a GetProduct message.

    Note 

    The WCF service configuration file for this version of the solution enables tracing at the service level rather than the transport level. All messages are traced in their unencrypted format to make it easier for you to examine their contents.

  8. In the lower right pane, click the Message tab. Scroll this pane to display the body of the SOAP message. Note that the order of the fields in this message is Color, ListPrice, Name, and ProductNumber. This sequence is different from the order of the members in the Product class.

    The data contract serializer serializes the members of a data contract in alphabetic order. Rather than let the names of members imply an order, it is recommended that you use the Order property of the DataMember attribute to explicitly specify the sequence of the members.

  9. Close the Products.svclog trace file, but leave the Service Trace Viewer open.

  10. Return to Visual Studio 2005 and edit the image from book ProductsService.cs file in the ProductsService project. Amend the DataMember attributes of each member as shown below, in bold:

     [DataContract] public class Product {     [DataMember(Order=0)]     public string Name;     [DataMember(Order=1)]     public string ProductNumber;     [DataMember(Order=2)]     public string Color;     [DataMember(Order=3)]     public decimal ListPrice; }

    The data contract serializer will serialize members of the Product class starting with the member with the lowest Order value. If two members have the same Order value, then they will be serialized in alphabetic order.

  11. Using Windows Explorer, delete the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  12. In Visual Studio 2005, start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests appear to run successfully. However, if you examine the output from test 2 displaying the details of a product more closely, you should see that the Color is blank and the Price is zero. Changing the order of members in a data contract is a breaking change (you will fix the client application later).

  13. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

  14. Return to the Service Trace Viewer, and open the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  15. In the left pane, click the Message tab. Click the fourth message in the http://adventureworks.com/2006/07/04 namespace. In the lower right pane, click the Message tab. Note that the order of the fields in this message is now Name, ProductNumber, Color, and ListPrice. This sequence now matches the order of the members in the Product class. You can see that the service is emitting the data in the products contract in the correct sequence even though the client application is not receiving this data correctly.

  16. Close the Products.svclog trace file, but leave the Service Trace Viewer open.

You need to regenerate the proxy for the client application to make things work properly. Before doing that though, it is worth also looking at how changing the names of data members also affects a data contract.

In a manner similar to the service contract, the data contract serializer uses the name of each data member to form the name of each serialized field. Consequently, changing the name of a data member is also a breaking change that requires updating client applications. Like the operations in a service contract, you can provide a logical name for data members that the data contract serializer will use in place of the physical name of the data members; the DataMember attribute provides the Name property for this purpose. You can use this feature to rename the physical members of a data contract while keeping the logical names the same, like this:

 [DataContract] public class Product {     [DataMember(Order=0)]     public string Name;   // Serializer uses physical name of member     [DataMember(Order=1, Name="ProductNumber")]     public string Number; // Field renamed. Serializer uses Name property      }

The DataContract attribute provides a Namespace property. By default, WCF uses the namespace “http://schemas.datacontract.org/2004/07” with the .NET Framework namespace containing the data contract appended to the end. In the ProductsService service, the Product data contract is a member of the Products .NET Framework namespace, so messages are serialized with the namespace “http://schemas.datacontract.org/2004/07/Products.” You can override this behavior by specifying a value for the Namespace property of the DataContract attribute. This is good practice; you can include date information in the namespace to help identify a specific version of the data contract. If you update the data contract, then modify the namespace with the update date.

Change the namespace of the Product data contract

  1. In Visual Studio 2005, edit the image from book ProductsService.cs file in the ProductsService project.

  2. Modify the DataContract attribute for the Product class as shown in bold below:

     [DataContract (Namespace=     "http://adventure-works.com/datacontract/2007/03/01/Product")] public class Product {      }

    (For the purposes of this exercise, pretend that the current date is 1 March 2007.)

  3. Using Windows Explorer, delete the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  4. In Visual Studio 2005, start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests should run, but this time test 2 is also missing the product number and name (previously, only the color and price were omitted). Changing the namespace for a data contract is another example of a breaking change.

  5. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

  6. Return to the Service Trace Viewer, and open the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  7. In the left pane, click the Message tab. Click the fourth message in the http://adventureworks.com/2006/07/04 namespace. In the lower right pane, click the Message tab. Verify that the namespace for the fields in the message body is new namespace; the <GetProductResult> element creates an alias for the namespace called “d4p1,” and the fields in the message are prefixed with this alias.

  8. Close the Products.svclog trace file, but leave the Service Trace Viewer open.

You can see that the ProductsService service is formatting messages as expected, although the client application is not currently processing them correctly. The next step is to regenerate the proxy for the client application. You will also take the opportunity to switch the client application to use version 2 of the ProductsService interface.

Regenerate the proxy class and update the WCF client application

  1. Open a Visual Studio 2005 Command Prompt window and move to the folder \Microsoft Press\WCF Step By Step\Chapter 6\ProductsServiceV2\ProductsService\bin folder under your \My Documents folder.

  2. Run the following command to generate the schema files and WSDL description file the ProductsService service:

     svcutil ProductsService.dll

    This command should generate the following files:

    • adventure-works.com.2006.07.04.wsdl

    • adventure-works.com.2006.08.31.wsdl

    • adventure-works.com.2006.07.04.xsd

    • adventure-works.com.2006.08.31.xsd

    • schemas.microsoft.com.2003.10.Serialization.xsd

    • schemas.microsoft.com.2003.10.Serialization.Arrays.xsd

    • Products.xsd

    • adventure-works.com.datacontract.2007.03.01.xsd

    Notice that as the service now contains two service contracts, this command generates two WSDL description files with their corresponding schemas.

  3. Run the following command to generate the proxy class from the WSDL description file for the version 2 interface (2006.08.31) and the schema files:

     svcutil /namespace:*,ProductsClient.ProductsService adventure- works.com.2006.08.31.wsdl *.xsd /out:ProductsV2.cs

    Note 

    If you need to generate a proxy for the version 1 interface (2006.07.04), then simply specify the appropriate WSDL file.

  4. Leave the Visual Studio 2005 Command Prompt window open, and return to Visual Studio 2005.

  5. In the ProductsClient project, delete the image from book Products.cs file.

  6. In the Project menu, click Add Existing Item. Move to the Microsoft Press\WCF Step By Step\Chapter 6\ProductsServiceV2\ProductsService\bin folder, located under your \My Documents folder, and add the file image from book ProductsV2.cs.

  7. The client application currently invokes the ListProducts operation. This operation is not available in version 2 of the ProductsService service. Edit the image from book Program.cs file in the ProductsClient project. In the Main method, change the code that performs test 1 to call the ListSelectedProducts method, passing in a product name that matches all bicycle frames:

     // Obtain a list of all bicycle frames Console.WriteLine("Test 1: List all bicycle frames"); string[] productNumbers = proxy.ListSelectedProducts("Frame");

  8. Start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests should run successfully, and test 2 should now display valid data for product WB-H098 (a 30-oz water bottle of indeterminate color that costs $4.99).

  9. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

You can now see that you should carefully assess the impact of updating a data contract, as doing so can cause client applications to malfunction in ways that are not always apparent. The nature of SOAP serialization means that reorganized or misplaced fields end up being assigned default values, which are very easy to miss!

You can also add new members to a data contract. Under some circumstances, you can perform this task without breaking existing client applications.

Note 

Adding a member to a data contract changes the schema exported by WCF. Client applications use this schema to determine the format of the data they send and receive in SOAP message. Many client applications that use SOAP (including those built by using WCF, and ASP.NET Web services) will happily ignore additional fields in SOAP messages. However, a small number of client applications created by using other technologies can enable strict schema validation. If you have to support these types of client applications, you cannot add new fields to a data contract without updating those client applications as well. In these cases, you should adopt a data contract versioning strategy similar to that shown for versioning service contracts. For more information, see the topic, Best Practices: Data Contract Versioning in the Microsoft Windows SDK documentation, also available on the Microsoft Web site at http://windowssdk.msdn.microsoft.com/en-us/library/ms733832.aspx.

Add a new field to the Product data contract to examine how a client handles unexpected fields

  1. Using Visual Studio 2005, edit the image from book ProductsService.cs file in the ProductsService project.

  2. Add the following member, shown in bold, to the end of the Product data contract:

     public class Product {     …    [DataMember(Order=0)]     public decimal StandardCost; }

    The StandardCost in the Product table in the AdventureWorks database records the cost of the product to the Adventure Works organization. The difference between the value in the ListPrice column and this one is the profit that Adventure Works makes whenever it sells an item. Adding this member with the Order property set to zero causes it to be serialized as the second member of the data contract. The Name member, which also has the Order property set to zero, will be output first, as it comes alphabetically before StandardCost.

    Note 

    As mentioned earlier, I would not normally recommend that you rely on alphabetical order to determine the sequence of members in a data contract, but in this case there is a reason for this approach; you will quickly be able to see what happens in a client application when an unexpected data member appears in the middle of a data contract.

  3. Find the GetProduct method in the ProductsServiceImpl class. In this method, update the SQL statement that retrieves product information from the database, as follows:

     // Retrieve the details of the selected product by using a DataReader string queryString =     @"SELECT ProductNumber, Name, Color, ListPrice, StandardCost       FROM Production.Product       WHERE ProductNumber = '" + productNumber + "'";

  4. In the block of code belonging to the if statement that populates the product passed back to the client application, add the following statement to copy the value in the StandardCost column to the Product object:

     if (productsReader.Read()) {     …     product.StandardCost = productsReader.GetDecimal(4); }

  5. Using Windows Explorer, delete the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  6. In Visual Studio 2005, start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests should run successfully, including test 2, which completely ignores the new member of the data contract. Adding a new member in the middle of a data contract does not affect the client application at all.

  7. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

  8. Return to the Service Trace Viewer, and open the Products.svclog file in the Microsoft Press\WCF Step By Step\Chapter 6 folder under your \My Documents folder.

  9. In the left pane, click the Message tab. Click the fourth message in the http://adventureworks.com/2006/07/04 namespace. Remember that this is the GetProductResponse message sent by the service to the client when replying to a GetProduct message.

  10. In the lower right pane, click the Message tab. Scroll this pane to display the body of the SOAP message. Notice that the StandardCost field appears between the Name and ProductNumber fields.

    The data contract serializer serializes every member of the data contract. The WCF client application is not expecting the StandardCost field, and as it does not perform strict schema validation, the client application simply ignores this extra field.

  11. Close the Products.svclog trace file, and exit the Service Trace Viewer open.

  12. Regenerate the proxy object for the client application:

    • In the Visual Studio 2005 Command Prompt window, run the command:

       svcutil ProductsService.dll

    • Run the command:

       svcutil /namespace:*,ProductsClient.ProductsService adventure- works.com.2006.08.31.wsdl *.xsd /out:ProductsV2.cs

  1. Return to Visual Studio 2005. In the ProductsClient project, delete the image from book ProductsV2.cs file and replace it with the new file located in the Microsoft Press\WCF Step By Step\Chapter 6\ProductsServiceV2\ProductsService\bin folder, located under your \My Documents folder.

  2. Edit the image from book Program.cs file in the ProductsClient project. In the Main method, add a statement after the code that performs test 2, to display the standard cost:

     Console.WriteLine("Price: " + product.ListPrice); Console.WriteLine("Standard Cost: " + product.StandardCost); Console.WriteLine();

  3. Start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    All tests should run successfully, and test 2 should now include the standard cost ($1.8663).

  4. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

While it is acceptable for a client application to discard a field sent by the service, this scenario can cause complications if the client application is later expected to send data to the service that includes this missing field. You will examine this scenario in the next exercise.

Add another operation to the WCF service for investigating data contract serialization

  1. In Visual Studio 2005, edit the image from book ProductsService.cs file in the ProductsService project.

  2. Add the following operation to the IProductServiceV2 service contract:

     public interface IProductServiceV2 {     …     // Update the details of the specified product in the database     [OperationContract]     void UpdateProductDetails(Product product); }

    A client application will be able to use this operation to modify the details of a product in the database.

  3. Add the implementation of the UpdateProductDetails method to the end of the ProductsServiceImpl class:

     public class ProductsServiceImpl : … {     …     public void UpdateProductDetails(Product product)     {         string msg = String.Format("Number: {0}\nName: {1}",             product.ProductNumber, product.Name);         System.Windows.Forms.MessageBox.Show(msg);     } }

    This method displays the product number and name sent by the client application. In the real world, this method would also update the database with the information in the parameter passed to the method. To keep things straightforward, the logic to perform this task has been omitted.

  4. Build the solution.

  5. Regenerate the proxy object for the client application:

    • In the Visual Studio 2005 Command Prompt window, run the command:

       svcutil ProductsService.dll

    • Run the command:

       svcutil /namespace:*,ProductsClient.ProductsService adventure- works.com.2006.08.31.wsdl *.xsd /out:ProductsV2.cs

  1. Return to Visual Studio 2005. In the ProductsClient project, delete the image from book ProductsV2.cs file and replace it with the new file located in the Microsoft Press\WCF Step By Step\Chapter 6\ProductsServiceV2\ProductsService\bin folder, located under your \My Documents folder.

  1. Edit the image from book Program.cs file in the ProductsClient project. In the Main method, add the following statements that test the new operation to the try block:

     try {     …     // Modify the details of this product     Console.WriteLine("Test 5: Modify the details of a product");     product.ProductNumber = "WB-H098";     product.Name = "Water Bottle - 1 liter";     proxy.UpdateProductDetails(product);     Console.WriteLine("Request sent");     Console.WriteLine();     // Disconnect from the service     proxy.Close(); }

  2. Start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    When test 5 runs, a message box appears displaying the product number and the new product name.

    Click OK to close the message box.

  3. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

The client application successfully sends a Product object to the WCF service using the definition from the data contract. But what happens if the client application uses a version of the data contract that has a missing field?

Add another field to the Product data contract and examine the default value

  1. In Visual Studio 2005, edit the image from book ProductsService.cs file in the ProductsService project and add the following member, shown in bold, to the end of the Product data contract:

     public class Product {     …    [DataMember(Order=4)]     public bool FinishedGoodsFlag; }

    The FinishedGoodsFlag in the Product table indicates whether the product is a complete item (such as a water bottle) or a component used to construct other parts (such as a chaining nut).

  2. In the UpdateProductDetails method in the ProductsServiceImpl class, modify the statements that display the product details to include the FinishedGoodsFlag member:

     public void UpdateProductDetails(Product product) {     string msg = String.Format("Number: {0}\nName: {1}\nFlag: {2}",         product.ProductNumber, product.Name, product.FinishedGoodsFlag);     System.Windows.Forms.MessageBox.Show(msg); }

  3. Start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    When test 5 runs, the message box displays the value False for the FinishedGoodsFlag. The client application is still using the old version of the Product data contract and did not populate this field–this is the default value for a Boolean field in a SOAP message.

    Click OK to close the message box.

  4. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

As when changing the order of data members, you should be very mindful of existing client applications when adding a new member to a data contract. If the client application does not populate every field in a serialized object, WCF will use default values–False for Booleans, 0 for numerics, and null for objects. If these default values are unacceptable, you can customize the serialization and deserialization process by adding methods annotated with the OnSerializing and OnDeserializing attributes to the WCF service.

More Info 

The details of customizing the serialization process are beyond the scope of this book, but for more information, examine the topic Version Tolerant Serialization Callbacks in the Microsoft Windows SDK documentation, also available on the Microsoft Web site at http://windowssdk.msdn.microsoft.com/en-us/library/ms733734.aspx.

Data Contract Compatibility

If you need to version a data contract, you should do so in a manner that maintains compatibility with existing client applications. The DataMember attribute provides two properties that can assist you:

  • IsRequired. If you set this property to True, then the SOAP message that the service receives must include a value in this data member. By default, the value of this property is False, and the WCF runtime will generate default values for any missing fields.

  • EmitDefaultValue. If you set this property to True, the WCF runtime on the client will generate a default value for a data member if it is not included in the SOAP message sent by the client application. This property is True by default.

If you need to maintain strict conformance to a data contract in future versions of the service, you should set the IsRequired property of each data member in the data contract to True and set the EmitDefaultValue property to False when building the first version of a service. You should never make a data member mandatory (IsRequired set to True ) in a new version of a data contract if it was previously optional (IsRequired set to False).

It is possible for a client application to request data conforming to a data contract from a service, modify that data, and then submit it back to the service, in a manner similar to calling the GetProduct method followed by the UpdateProductDetails method in the ProductsService example. If a client application uses the old version of a data contract that is missing one or more members, such as the FinishedGoodsFlag, what happens to this information when the client sends the data back to the service? The WCF runtime implements a technique called “Round-tripping” to ensure that data does not get lost.

Examine how the WCF runtime performs round-tripping

  1. In Visual Studio 2005, edit the image from book ProductsService.cs file in the ProductsService project.

  2. In the GetProduct method in the ProductsServiceImpl class, add the statement shown in bold below to the end of the block belonging to the if statement that populates the Product object returned to the client application:

     if (productsReader.Read()) {     …     product.FinishedGoodsFlag = true; }

    Remember that the default value for Booleans is false.

  3. Start the solution without debugging. In the ProductsServiceHost form, click Start. In the client console window, press Enter.

    When test 5 runs, the message box displays the value True for the FinishedGoodsFlag. This is the value originally provided by the service and which has been sent through the client application and back to the service. Although the client application does not know anything about this field, it has managed to preserve its value.

    Click OK to close the message box.

  4. Press Enter to close the client console window. In the ProductsServiceHost form, click Stop and then close the form.

The WCF library performs round-tripping by using the IExtensibleDataObject interface. If you examine the code in the image from book ProductsV2.cs file, you will see that the client proxy version of the Product class implements this interface. This interface defines a single property called ExtensionData, of type ExtensionDataObject. The ExtensionData property generated for the client proxy simply reads and writes data to a private field of type ExtensionObjectData, like this:

 public partial class Product : object,     System.Runtime.Serialization.IExtensibleDataObject {     private System.Runtime.Serialization.ExtensionDataObject         extensionDataField;         …     public System.Runtime.Serialization.ExtensionDataObject ExtensionData     {         get         {             return this.extensionDataField;         }         set         {             this.extensionDataField = value;         }     } }

The extensionDataField field acts as a “bucket” for all undefined data items received by the client; rather than discarding them, the proxy automatically stores them in this field. When the client proxy transmits the Product object back to the service, it includes the data in this field. If you need to disable this feature (if you want to ensure strict schema compliance in client applications, for example), you can set the IgnoreExtensionDataObject property of the data contract serializer in the endpoint behavior to true for the endpoint that the client is using. You can perform this task by using the client application configuration file, like this:

 <system.serviceModel>     <behaviors>         <endpointBehaviors>             <behavior name="IgnoreBehavior">                 <dataContractSerializer ignoreExtensionDataObject="true" />             </behavior>         </endpointBehaviors>     </behaviors>     ...     <client>         <endpoint address="net.tcp://localhost:8080/TcpProductsService"             behaviorConfiguration="IgnoreBehavior" ... />     </client> </system.serviceModel>

You can also disable extension data objects on the server-side by setting the IgnoreExtensionDataObject property of data contract serializer for a single service endpoint or for all server endpoints by adding a service behavior.

image from book
Data Contract Serialization and Security

Remember that a data contract provides a potential entry point for a malicious user to hack into your system–by attempting a SQL Injection attack, for example. You must design your data contracts to be resistant to misuse such as this.

Another common example is a “Denial of Service” attack. In this type of attack, a user invokes methods in your service by sending them vast quantities of data. Your service then spends much of its time simply trying to receive and read this data, and performance suffers accordingly. To avoid this type of attack, don’t define data contracts that involve large, nested data structures, arrays, or collections of indeterminate length. If you must define data contracts that allow a user to send an array, collection, or nested data, then limit the size of the data they can send by using the readerQuota properties of the service bindings:

 <system.serviceModel>     <bindings>         <netTcpBinding>             <binding name="ProductsServiceTcpBindingConfig">                 <readerQuotas maxDepth="2" maxStringContentLength="1024"                  maxArrayLength="1024" />                 ...             </binding>         </netTcpBinding>     </bindings>     <services>         <service ...>             <endpoint binding="netTcpBinding"             bindingConfiguration="ProductsServiceTcpBindingConfig" .../>             ...         </service>     </services> </system.serviceModel>

The readerQuotas properties include:

  • MaxArrayLength. This is the maximum length of any array, in bytes, that the user can send to the service.

  • MaxDepth. If a data structure contains nested data structures, this value specifies the maximum level of nesting allowed.

  • MaxStringContentLength. This is the maximum length of any string, in characters, that the user can send to the service.

If a client application attempts to send a message of a size that exceeds these parameters, WCF will abort the request. By default, these properties are set to zero, which turns off any restrictions on data length.

image from book




Microsoft Windows Communication Foundation Step by Step
Microsoft Windows Communication Foundation Step by Step (Step By Step Developer Series)
ISBN: 0735623368
EAN: 2147483647
Year: 2007
Pages: 105
Authors: John Sharp

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net