Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
EPL Standings
Windows 7

Visual Basic 2010 : Implementing Query Interceptors

6/26/2011 4:18:44 PM
Basically interceptors are .NET methods exposed by the service class enabling developers to intercept Http requests and to establish how such requests must be handled, both in reading (query interceptors) and in writing (change interceptors) operations. This section describes both query interceptors and change interceptors.

Understanding Query Interceptors

Query interceptors are public methods for intercepting HTTP GET requests and allow developers to handle the reading request. Such methods are decorated with the QueryInterceptor attribute that simply requires specifying the entity set name. For a better understanding, consider the following interceptor (to be implemented within the NorthwindService class) that returns only orders from the specified culture:

<QueryInterceptor("Orders")> Public Function OnQueryOrders() As  _
Expression(Of Func(Of Order, Boolean))
'Determines the caller's culture
Dim LocalCulture = WebOperationContext.Current.

If LocalCulture = "it-IT" Then
Return Function(ord) ord.ShipCountry = "Italy"
Throw New DataServiceException("You are not authorized")
End If

End Function

OnQueryOrders will be invoked on the service each time an HTTP GET requests is sent to the service. The code just returns only orders where the ShipCountry property’s value is Italy, if the client culture (the caller) is it-IT. Differently, the code throws a DataServiceException. The most important thing to notice in the code is the returned type, which is an Expression(Of Func(Of T, Boolean)). This is an expression tree generated starting from the lambda expression actually returned.The Func object enables generating anonymous methods on-the-fly, receiving two arguments: The first one is the real argument, whereas the second one is the returned type. The lambda expression is the equivalent of the following LINQ query:

Dim query = From ord In Me.CurrentDataSource.Orders
Where ord.ShipCountry = "Italy"
Select ord

The big difference is that this kind of query returns an IQueryable(Of Order), whereas we need to evaluate the result of an expression tree, and this is only possible with lambdas. You can easily test this interceptor by running the service and typing the following Uri in the browser address bar, replacing the port number:


This Uri automatically fetches only orders targeting Italy, if your local culture is it-IT. If it is not, the Visual Studio debugger shows an exception. By the way, it is important to provide sufficient information about exceptions from the server side, because clients need detailed information for understanding what happened. This is a general rule explained here together with a practical example. WCF Data Services provide a simple way for providing descriptive error messages other than throwing exceptions. This requires the following line of code in the InitializeService method:

config.UseVerboseErrors = True

On the client side, failures from query interceptors are handled by DataServiceQueryException objects. This is the reason why I already implemented such an object in the Try..Catch block in the client application’s main window. According to the previous example, if your culture is different from it-IT, when you run the client application, you should get the error message shown in Figure 1.

Figure 1. The detailed information about the error.

Notice how, other than the error message you provided via the DataServiceException, there is a lot of information that can be useful to understand what happened. You thus could implement a log system for redirecting to you, as a developer, all collected information. Until now we talked about query interceptors, which intercept GET requests. We now cover change interceptors.

Understanding Change Interceptors

Change interceptors are conceptually similar to query interceptors, but they differ in that they can intercept http requests of type POST, PUT, and DELETE (that is, CRUD operations via Uri). They are public methods returning no type; therefore, they are always Sub decorated with the ChangeInterceptor attribute pointing to the entity set name. Each interceptor receives two arguments: the data source (generally a single entity) and the System.Data.Services.UpdateOperations enumeration, which allows understanding what request was sent. Take a look at the following interceptor:

<ChangeInterceptor("Orders")> _
Public Sub OnOrdersChange(ByVal DataSource As Order,
ByVal Action As UpdateOperations)
If Action = UpdateOperations.Add OrElse _
Action = UpdateOperations.Change Then

'If data does not satisfy my condition, throws an exception
If DataSource.OrderDate Is Nothing Then
Throw New DataServiceException(400,
"Order date cannot be null")
End If

ElseIf Action = UpdateOperations.Delete Then
If DataSource.ShippedDate IsNot Nothing Then
Throw New DataServiceException(500,
"You are not authorized to delete orders with full info")
End If

End If
End Sub

You decide how to handle the request depending on the UpdateOperations current value. Add corresponds to an insert operation, Delete to a delete operation, Change to an update operation, and None means that no operations were requested for the data source. The preceding code performs the same actions on both Add and Change operations and throws an exception if the new or existing order has null value in the OrderDate property. A different check is instead performed about Delete requests; in my example the code prevents from deleting an order whenever it has value in the ShippedDate property. No other code is required for handling situations in which supplied data are valid, because the Data Services framework automatically persists valid data to the underlying source. Change interceptors come in when a client application invokes the DataServiceContext.SaveChanges method. On the server side, change interceptors are raised just before sending data to the source and collecting information on the CRUD operation that sent the request.

Other -----------------
- Microsoft Visio 2010 : Adding Sophistication to Your Drawings - Adding ScreenTips and Comments
- Microsoft Visio 2010 : Adding Sophistication to Your Drawings - Positioning Shape Text
- Monitoring and Maintaining Windows 7 : Using Event Viewer
- Monitoring and Maintaining Windows 7 : Setting Up Task Scheduler
- Visual Basic 2010 : Implementing and Consuming WCF Data Services - Implementing Service Operations
- Visual Basic 2010 : Consuming WCF Data Services
- Visual Basic 2010 : Implementing WCF Data Services
- Microsoft Visio 2010 : Adding Sophistication to Your Drawings - Orienting Shape Text
- Microsoft Visio 2010 : Adding Sophistication to Your Drawings - Orienting Shapes on the Page
- Microsoft Visio 2010 : Adding Text to Shapes & Creating and Formatting Text Boxes
- Monitoring and Maintaining Windows 7 : Using System Configuration
- Using Windows 7 Tools to Discover System Information
- Optimizing Windows 7 with Performance Monitor (part 3)
- Optimizing Windows 7 with Performance Monitor (part 2) - Utilizing Customized Counters in Performance Monitor & Managing Performance Monitor Properties
- Optimizing Windows 7 with Performance Monitor (part 1) - Using Resource Monitor
- Visual Basic 2010 : Reflection - Generating Code at Runtime with Reflection.Emit
- Visual Basic 2010 : Reflection - Invoking Code Dynamically
- Visual Basic 2010 : Reflection - Reflecting Types
- Administering Internet Explorer : Troubleshooting Internet Explorer Issues
- Administering Internet Explorer : Understanding Advanced Settings (part 2) - Branding Internet Explorer & Group Policy Settings
Most view of day
- Adobe Dreamweaver CS5 : Using Library Items and Server-side Includes (part 4) - Editing a Library Item
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 2) - Default IPv6 functionality
- Maintaining Desktop Health : Monitoring Reliability and Performance (part 6) - Using Reliability Monitor
- Windows Phone 8 : Configuring Basic Device Settings - Controlling the Keyboard’s Behavior (part 3) - Customizing the Keyboard’s Behavior
- System Center Configuration Manager 2007 : Network Design - Troubleshooting Configuration Manager Network Issues (part 2) - Identifying Network Issues Affecting Configuration Manager
- Printing from a Program, Printing a Document - Print a Document Using the Default Printer, Print a Document Using a Specific Printer
- Troubleshooting Hardware, Driver, and Disk Issues : How to Diagnose Hardware Problems
- Exploring the Vista Task Scheduler
- Windows Server 2008 : Designing the Active Directory Administrative Model (part 3) - Planning to Audit AD DS and Group Policy Compliance, Planning Organizational Structure
- Sharepoint 2013 : Backup and Restore (part 3) - Unattached Content Database Data Recovery
Top 10
- Microsoft Exchange Server 2007 : Implementing Client Access and Hub Transport Servers - Installing the Hub Transport Server
- Microsoft Exchange Server 2007 : Implementing Client Access and Hub Transport Servers - Transport Pipeline
- Microsoft Exchange Server 2007 : Hub Transport Server Policy Compliance Features (part 4) - Message Classification , Rights Management and the Hub Transport Server
- Microsoft Exchange Server 2007 : Hub Transport Server Policy Compliance Features (part 3) - Journaling
- Microsoft Exchange Server 2007 : Hub Transport Server Policy Compliance Features (part 2) - Disclaimers
- Microsoft Exchange Server 2007 : Hub Transport Server Policy Compliance Features (part 1) - Transport Rules
- Microsoft Exchange Server 2007 : Implementing Client Access and Hub Transport Servers - Understanding the Hub Transport Server
- Conducting Research in OneNote 2010 : Translating Text
- Conducting Research in OneNote 2010 : Researching a Topic, Customizing the Research Task Pane
- Conducting Research in OneNote 2010 : Handling the Research Task Pane
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro