.NET Technical bits: May 2010

Monday, May 10, 2010

IEnumerable vs. IQueryable

IQueryable

• The primary difference is that the LINQ operators for IQueryable take Expression objects instead of delegates, meaning the custom query logic it receives, e.g., a predicate or value selector, is in the form of an expression tree instead of a delegate to a method.
• IQueryable extends the IEnumerable interface, so anything you can do with a "plain" IEnumerable, you can also do with an IQueryable.
• The expression can simply be a constant expression of the object itself or a more complex tree of a composed set of query operators and operands. The query provider's IQueryProvider.Execute() or IQueryProvider.CreateQuery() methods are called with an Expression passed to it, and then either a query result or another IQueryable is returned, respectively.
• IQueryable allows for out-of memory things like a remote data source, such as a database or web service.
• IQueryable is a very powerful feature that enables a variety of interesting deferred execution scenarios (like paging and composition based queries).

IEnumerable

• IEnumerable doesn’t have the concept of moving between items, it is a forward only collection. It’s very minimalistic; something that most any data source can provide. Using only this minimal functionality, LINQ can provide all of these great operators.
• IEnumerable is great for working with sequences that are iterated in-memory.
• IEnumerable just has a GetEnumerator() method that returns an Enumerator for which you can call its MoveNext() method to iterate through a sequence of T

LINQ Query Syntax versus Method Syntax

Most queries in the introductory LINQ documentation are written as query expressions by using the declarative query syntax introduced in C# 3.0. However, the .NET common language runtime (CLR) has no notion of query syntax in itself. Therefore, at compile time, query expressions are translated to something that the CLR does understand: method calls. These methods are called the standard query operators, and they have names such as Where, Select, GroupBy, Join, Max, Average, and so on. You can call them directly by using method syntax instead of query syntax.
The following example shows a simple query expression and the semantically equivalent query written as a method-based query.

class QueryVMethodSyntax
{
static void Main()
{
int[] numbers = { 5, 10, 8, 3, 6, 12};

//Query syntax:
IEnumerable numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;

//Method syntax:
IEnumerable numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

foreach (int i in numQuery1)
{
Console.Write(i + " ");
}
Console.WriteLine(System.Environment.NewLine);
foreach (int i in numQuery2)
{
Console.Write(i + " ");
}

// Keep the console open in debug mode.
Console.WriteLine(System.Environment.NewLine);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
/*
Output:
6 8 10 12
6 8 10 12
*/

The output from the two examples is identical. You can see that the type of the query variable is the same in both forms: IEnumerable<(Of <(T>)>).
To understand the method-based query, let's examine it more closely. On the right side of the expression, notice that the where clause is now expressed as an instance method on the numbers object, which as you will recall has a type of IEnumerable. If you are familiar with the generic IEnumerable<(Of <(T>)>) interface, you know that it does not have a Where method. However, if you invoke the IntelliSense completion list in the Visual Studio IDE, you will see not only a Where method, but many other methods such as Select, SelectMany, Join, and Orderby. These are all the standard query operators.
Although it looks as if IEnumerable<(Of <(T>)>) has been redefined to include these additional methods, in fact this is not the case. The standard query operators are implemented as a new kind of method called extension methods. Extensions methods "extend" an existing type; they can be called as if they were instance methods on the type. The standard query operators extend IEnumerable<(Of <(T>)>) and that is why you can write numbers.Where(...).

LINQ - Mixed Query and Method Syntax

This example shows how to use method syntax on the results of a query clause. Just enclose the query expression in parentheses, and then apply the dot operator and call the method. In the following example, query #7 returns a count of the numbers whose value is between 3 and 7. In general, however, it is better to use a second variable to store the result of the method call. In this manner, the query is less likely to be confused with the results of the query.

// Query #7.

// Using a query expression with method syntax
int numCount1 =
(from num in numbers1
where num < 3 || num > 7
select num).Count();

// Better: Create a new variable to store
// the method call result
IEnumerable numbersQuery =
from num in numbers1
where num < 3 || num > 7
select num;

int numCount2 = numbersQuery.Count();

Because Query #7 returns a single value and not a collection, the query executes immediately.
The previous query can be written by using implicit typing with var, as follows:

var numCount = (from num in numbers...
It can be written in method syntax as follows:
var numCount = numbers.Where(n => n < 3 || n > 7).Count();
It can be written by using explicit typing, as follows:
int numCount = numbers.Where(n => n < 3 || n > 7).Count();

LINQ Queries - Method Syntax

Some query operations must be expressed as a method call. The most common such methods are those that return singleton numeric values, such as Sum, Max, Min, Average, and so on. These methods must always be called last in any query because they represent only a single value and cannot serve as the source for an additional query operation. The following example shows a method call in a query expression:

List numbers1 = new List() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
List numbers2 = new List() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
// Query #4.
double average = numbers1.Average();

// Query #5.
IEnumerable concatenationQuery = numbers1.Concat(numbers2);


If the method has parameters, these are provided in the form of a lambda expression, as shown in the following example:

// Query #6.
IEnumerable largeNumbersQuery = numbers2.Where(c => c > 15);


In the previous queries, only Query #4 executes immediately. This is because it returns a single value, and not a generic IEnumerable<(Of <(T>)>) collection. The method itself has to use foreach in order to compute its value.
Each of the previous queries can be written by using implicit typing with var, as shown in the following example:

// var is used for convenience in these queries
var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);

LINQ Queries - Query Syntax

The recommended way to write most queries is to use query syntax to create query expressions. The following example shows three query expressions. The first query expression demonstrates how to filter or restrict results by applying conditions with a where clause. It returns all elements in the source sequence whose values are greater than 7 or less than 3. The second expression demonstrates how to order the returned results. The third expression demonstrates how to group results according to a key. This query returns two groups based on the first letter of the word.

// Query #1.
List numbers = new List() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// The query variable can also be implicitly typed by using var
IEnumerable filteringQuery =
from num in numbers
where num < 3 || num > 7
select num;

// Query #2.
IEnumerable orderingQuery =
from num in numbers
where num < 3 || num > 7
orderby num ascending
select num;

// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable<IGrouping> queryFoodGroups =
from item in groupingQuery
group item by item[0];

Note that the type of the queries is IEnumerable<(Of <(T>)>). All of these queries could be written using var as shown in the following example:
var query = from num in numbers...
In each previous example, the queries do not actually execute until you iterate over the query variable in a foreach statement.

How to: Write LINQ Queries in C#

The three ways in which you can write a LINQ query in C#:

1. Use query syntax. Please refer this post.
2. Use method syntax. Please refer this post.
3. Use a combination of query syntax and method syntax. Please refer this post.

Thursday, May 6, 2010

WCF Message Security

When using message security, the user credentials and claims are encapsulated in every message using the WS-Security specification to secure messages. This option gives the most flexibility from an authentication perspective. You can use any type of security credentials you want, largely independent of transport, as long as both the client and the service agree.



Use message security for the following scenarios:

• You are sending a message to a WCF service, and the message is likely to be forwarded to other WCF services or may be routed through intermediate systems.
• Your WCF clients are accessing the WCF service over the Internet, it’s possible that other intermediate systems may be used in between, and security is your top consideration.

Using message security has following advantages:

• It provides end-to-end security. Because message security directly encrypts and signs the message, having intermediaries does not break the security.
• It allows partial or selective message encryption and signing, thus improving overall application performance.
• Message security is transport-independent and can be used with any transport protocol.
• It supports a wide set of credentials and claims, including issue token, which enables federated security.

Using message security has following disadvantages:

• This option may reduce performance compared to transport security because each individual message is encrypted and signed.
• It does not support interoperability with older ASP.NET Web Services (ASMX) clients because it requires both the client and service to support WS-Security specifications.

WCF Transport Security

When using transport security, the user credentials and claims are passed using the transport layer. In other words, user credentials are transport-dependent, which allows fewer authentication options compared to message security. Each transport protocol (TCP, IPC, MSMQ, or HTTP) has its own mechanism for passing credentials and handling message protection. The most common approach for this is to use Secure Sockets Layer (SSL) for encrypting and signing the contents of the packets sent over Secure HTTP (HTTPS).

Transport security is used to provide point-to-point security between the two endpoints (service and client). If there are intermediary systems between the client and the service, each intermediate point must forward the message over a new SSL connection.



Use transport security for the following scenarios:

• You are sending a message directly from your application to a WCF service and the message will not be routed through intermediate systems.
• You have both the service and the client in an intranet.

Using transport security has the following advantages:

• It provides interoperability, meaning that communicating parties do not need to understand the WS-Security specification.
• It may result in better performance.
• Hardware accelerators can be used to further improve performance.

Using transport security has the following disadvantages:

• Because security is applied on a point-to-point basis, there is no provision for multiple hops or routing through intermediate application nodes.
• It supports a limited set of credentials and claims compared to message security.
• It is transport-dependent upon the underlying platform, transport mechanism, and security service provider such as NTLM or Kerberos

WCF Transfer Security

After selecting a binding, you can decide which type of transfer security, otherwise known as security mode, to use for your WCF service. You can provide security on the transport level or the message level. Each option has its own advantages and disadvantages. For instance, transport security secures the entire communication channel (e.g., by using SSL) and therefore only supports point-to-point communication over a single transport. Message security protects each message individually and therefore supports multipoint communication, multiple transports, or even partial message encryption if necessary. Most scenarios are best supported by using transport security. The following security modes are available across the standard bindings.








ModeDescription
NoneNo security is provided; all information is passed in clear text.
TransportMutual authentication and message protection are provided at the transport level.
MessageMutual authentication and message protection are provided at the message level
BothMutual authentication and message protection are provided at both the transport and message levels. This is far more than is necessary for most scenarios.
TransportWithMessageCredentialClient authentication is provided at the message level, and message protection and service authentication are provided at the transport level.
TransportCredentialOnlyMutual authentication is provided at the transport level; no message protection is provided. This option is available only on basicHttpBinding.

WCF Bindings and Behaviors

When you create an overall security policy – for example, transfer security with authentication and authorization for your services – you can use bindings and behaviors to configure the required settings.

Bindings and behaviors are described as follows:

Bindings. Bindings control the security mode, client credential type, and other security settings.

Behaviors. Service behaviors control impersonation levels, how client credentials are authenticated and authorized, and service credentials.

You can configure bindings and behaviors, or you can program against the object model. Your binding selection determines the available security options for WCF. The following table summarizes the most commonly used bindings in WCF.








BindingCommon scenariosDefault security settings
basicHttpBindingLegacy Web service protocolsNo security
netTcpBindingBinary TCP communication between machinesTransport security with Windows authentication
wsFederationHttpBindingFederated security scenariosMessage security with issue token authentication
wsHttpBindingLeveraging security standards (WS-Security)Message security with Windows authentication


By default, every WCF binding will provide transfer security and user authentication except for BasicHttpBinding. If necessary, you can change the security settings to suit your scenario requirements.

Wednesday, May 5, 2010

WCF Key Security Features and Scope of WCF Security

Any Service-Oriented Architecture (SOA) needs to support security features that provide auditing, authentication, authorization, confidentiality, and integrity for the messages exchanged between the client and the service. Windows Communication Foundation (WCF) provides these security features by default for any application that is built on top of the WCF framework.

Key security features include:

Auditing - Effective auditing and logging is the key to non-repudiation. Non-repudiation guarantees that a user cannot deny performing an operation or initiating a transaction.

Authentication - Authentication allows you to confidently identify the clients of your service. These might be end users, other services, processes, or computers. WCF supports mutual authentication, which identifies both the client and the service in tandem, to help in preventing man-in-the-middle attacks

Authorization - Authorization determines what system resources and operations can be accessed by the authenticated user. This allows you to grant specific application and resource permissions for authenticated users.

Confidentiality - Confidentiality, also referred to as privacy, is the process of making sure that data remains private and confidential, and that it cannot be viewed by unauthorized users. Encryption is frequently used to enforce confidentiality. Privacy is a key concern, particularly for data / messages passed across networks.

Integrity - Integrity is the guarantee that data is protected from accidental or deliberate modification. Like privacy, integrity is a key concern, particularly for data / messages passed across networks. Integrity for data in transit is typically provided by using hashing techniques and message authentication codes.

Scope of WCF Security

The above fundamental security features are covered in the following WCF features:

Transfer security. Responsible for providing message confidentiality, data integrity, and authentication of communicating parties.

Authorization. Responsible for providing a framework for making authorization decisions.

Auditing. Responsible for logging security-related events to the audit log.

WCF Security

Securing your WCF service requires knowledge of the WCF security features related to auditing and logging, authentication, authorization, confidentiality, and integrity. Use behaviors and bindings to configure security for your WCF service. Bindings and behaviors allow you to configure transfer security, authentication, authorization, impersonation, and delegation as well as auditing and logging. Transfer security is the means by which WCF secures messages over the network. WCF gives you two options to implement transfer security: transport security and message security. Transport security secures the entire communication channel (e.g., by using SSL), while message security secures each message individually. WCF supports a variety of authentication options including username, Windows, and certificate authentication. Depending on your authentication method, you can choose to authorize your users by using role-based security or resource-based security. Use WCF impersonation and delegation to flow the identity and security context of your client-side original caller to the back end in order to support a granular authorization approach.