Tuesday, 16 March 2010

Cross Domain Policy File Usage Recommendations for Silverlight 3

Silverlight allows you to make web service calls to web services that are a part of the same website with no restrictions, but by default does not allow cross-domain calls. In order for a Silverlight app coming from one domain to be able to consume data from services in a different domain, the service must allow the app to do so by providing a policy file which grants access. When calling a cross-domain service, Silverlight will check the existence of the ClientAccessPolicy.xml file. This is a format defined by Silverlight and provides a way to define who can access what services. If it is not found, it will then default to look for the CrossDomain.xml policy file, which is the default file implemented for Adobe Flash.

Note: ClientAccessPolicy.xml is more feature rich, but CrossDomain.xml should be used if you want to give access to both Silverlight and Flash applications in one step. It is not necessary to have both files together.

Silverlight 3 currently supports the following WCF Service bindings:

1) customBinding

2) basicHttpBinding

3) pollingDuplexHttpBinding

Policy File Location

The policy file must be located at the root of the “domain” (hostname + port), so if your service is located at http://my.service.com:8000/Service/SomeService.svc/Endpoint, the policy file must be located at http://my.service.com:8000/ClientAccessPolicy.xml.

For IIS-hosted service, simply put the static policy files (ClientAccessPolicy.xml and/or CrossDomain.xml) in the root directory of the service (for example, in the c:\inetpub\wwwroot directory of an IIS web server).

For Self-hosted WCF service, you will have to have your WCF service host serve up the policy file on demand. Here’s an example:

1) First, create a service contract that can serve up the XML content:

[ServiceContract]
public interface IClientAccessPolicy
{
[OperationContract]
[WebGet(UriTemplate = "/ClientAccessPolicy.xml")]
XElement GetClientAccessPolicy();
}

2) Secondly, create a base service class to implement the IClientAccessPolicy interface like so:

public class BaseWebService: IClientAccessPolicy
{
public XElement GetClientAccessPolicy()
{
return new XElement("access-policy",
new XElement("cross-domain-access",
new XElement("policy",
new XElement("allow-from",
new XAttribute("http-request-headers", "*"),
new XElement("domain",
new XAttribute("uri", "*"))),
new XElement("grant-to",
new XElement("resource",
new XAttribute("path", "/"),
new XAttribute("include-subpaths", "true"))))));
}
}

3) Lastly, on the host application:

Uri[] addresses = new Uri[] { "www.mydomain.com" };
var host = new ServiceHost(typeof(SomeService), addresses);
var endpoint = host.AddServiceEndpoint(typeof(IClientAccessPolicy),
new WebHttpBinding(), string.Empty);
endpoint.Behaviors.Add(new WebHttpBehavior());
var smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);

Policy Files

1) ClientAccessPolicy.xml (unlimited cross site access)

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

<cross-domain-access>

<policy>

<allow-from http-request-headers="*">

<domain uri="*"/>

</allow-from>

<grant-to>

<resource include-subpaths="true" path="/"/>

</grant-to>

</policy>

</cross-domain-access>

</access-policy>

You can limit access to the service for a specific domain by providing a URI value like so:

<allow-from http-request-headers="*">

<domain uri="http://www.somedomainalpha.com" />

<domain uri="http://www. somedomainbeta.com" />

</allow-from>

You can use wildcards in the domain names to allow sub-domains. E.g., *.somedomain.com allows requests from mail.somedomain.com, admin.somedomain.com, and so on. You can also limit access to a specific service on the domain by specifying the resource path as follows:

<grant-to>

<resource path="/service/" include-subpaths="true"/>

</grant-to>

2) CrossDomain.xml

<?xml version="1.0"?>

<!DOCTYPE cross-domain-policy SYSTEM

"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

<cross-domain-policy>

<allow-http-request-headers-from domain="*" headers="*"/>

</cross-domain-policy>

Custom Doubly Linked List in C#

Of course you can use the generic LinkedList(T) class instead of this custom implementation for a specific project of mine and I thought I would like to blog it for future references.

The custom IDoubleLinkedNode<T> Interface:

/// <summary>

/// Node interface to support the DoubleLinkedList class

/// </summary>

/// <typeparam name="T"></typeparam>

public interface IDoubleLinkedNode<T>

: IComparable<T>, IEquatable<T>

{

T Next { get; set; }

T Previous { get; set; }

}

The custom DoubleLinkedList<T> class:

/// <summary>

/// Custom doubly linked list.

/// This is created to replace the Generic LinkedList(T) so that

/// the target object implements the node interface

/// (Next, Previous etc...) IDoubleLinkedNode

/// instead of being wrapped in a LinkedListNode object.

/// This also supports a custom implementation of Merged Sort

/// Algorithm for sorting the list

/// which is unavailable in the Generic LinkedList(T),

/// in that case, will have to be extended.

/// </summary>

/// <typeparam name="T">IDoubleLinkedNode type</typeparam>

public class DoubleLinkedList<T> : ICollection<T>

where T : IDoubleLinkedNode<T>

{

// Holds the first item.

private T head;

// Holds the last item to allow us add fast.

private T tail;

private int count;

#region Sort

/// <summary>

/// Sort the linked list using merge sort based

/// on the IComparable implementation

/// </summary>

public void Sort()

{

head = Merge_Sort(head);

}

#region Private Merge Sort

/// <summary>

/// Initiate a merge sort on the doublylinkedlist node item

/// Based on the IComparable ordering rule

/// </summary>

/// <param name="first"></param>

/// <returns></returns>

private T Merge_Sort(T first)

{

// If node is empty or single, then we don't need to sort

if (first == null || first.Next == null)

return first;

// Get the next item

T second = Split(first);

first = Merge_Sort(first);

second = Merge_Sort(second);

return Merge(first, second);

}

/// <summary>

/// Split the Linked Node into 2 parts, mainly

/// alternating through the pointers into 2 seperate

/// link nodes. Eg. 1 -> 2 -> 3 -> 4 -> 5 will be splitted

/// into 1 -> 3 -> 5 and 2 -> 4 respectively

/// </summary>

/// <param name="item"></param>

/// <returns></returns>

private T Split(T item)

{

// If it is the last item, we will return nothing

if (item == null || item.Next == null)

return default(T);

// Assign alternate items to the second item

T second = item.Next;

// Assign alternate items pointers to the current item

item.Next = second.Next;

// Continue assigning the alternate pointers

second.Next = Split(second.Next);

// Return the second concatenated list

return second;

}

/// <summary>

/// Perform merge of the first and second item based on the

/// </summary>

/// <param name="first"></param>

/// <param name="second"></param>

/// <returns></returns>

private T Merge(T first, T second)

{

if (first == null)

return second;

if (second == null)

return first;

// If both are not null, we will run the comparer

// If first is less than second

if (first.CompareTo(second) < 0)

{

first.Next = Merge(first.Next, second);

first.Next.Previous = first;

first.Previous = default(T);

return first;

}

else

{

second.Next = Merge(first, second.Next);

second.Next.Previous = second;

second.Previous = default(T);

return second;

}

}

#endregion

#endregion

#region [] accessor

/// <summary>

/// This is for convenience

/// </summary>

/// <param name="index"></param>

/// <returns></returns>

public T this[int index]

{

get

{

// Throw an exception if the index is not valid.

if (index < 0)

throw new ArgumentOutOfRangeException();

// Get the first item.

var item = head;

// Loop until we reach the item we want.

for (int i = 0; i < index; i++)

{

// If there is no next item throw an exception.

if (item.Next == null)

throw new ArgumentOutOfRangeException();

// Go to the next item.

item = item.Next;

}

// Return the value of the item.

return item;

}

}

#endregion

#region ICollection<T> Members

public void Add(T value)

{

if (value == null)

throw new ArgumentNullException("value");

var item = value;

// Check if we need to update the first and last

// fields.

if (head == null)

head = item;

if (tail != null)

{

tail.Next = item;

item.Previous = tail;

}

tail = item;

count++;

}

public void Clear()

{

head = default(T);

tail = default(T);

count = 0;

}

public bool Contains(T value)

{

var item = head;

// Loop until we reach the end of the list.

while (item != null)

{

// Check if we match.

if (item.Equals(value))

return true;

// Otherwise go on.

item = item.Next;

}

return false;

}

public void CopyTo(T[] array, int arrayIndex)

{

throw new NotImplementedException();

}

public int Count

{

get { return count; }

}

public bool IsReadOnly

{

get { return false; }

}

public bool Remove(T value)

{

if (head == null)

return false;

// Get the first item.

var item = head;

// Check if the first item matches.

if (item.Equals(value))

{

// If so move the next item to the first one.

head = item.Next;

head.Previous = default(T);

count--;

// If first is null the list has been cleared.

// Last is also to set null.

if (head == null)

tail = default(T);

return true;

}

else

{

// Loop until we reach the end.

while (item.Next != null)

{

// Check the values.

if (item.Next.Equals(value))

{

// If we match store the one after the next

// as the next one.

item.Next = item.Next.Next;

// If this is not the last item,

// then we set the previous value

if (item.Next != null)

item.Next.Previous = item;

count--;

// If the next item is null, set this item

// as the last one.

if (item.Next == null)

tail = item;

return true;

}

// Move to the next item.

item = item.Next;

}

}

return false;

}

#endregion

#region IEnumerable<T> Members

public IEnumerator<T> GetEnumerator()

{

// Get the first item.

var item = head;

// Loop until we reach the end.

while (item != null)

{

// Return the item.

yield return item;

// Move to the next one.

item = item.Next;

}

}

#endregion

#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()

{

return GetEnumerator();

}

#endregion

}

Piped Converters for Silverlight

When working with Silverlight, there will be instances where you will require more than one converter to convert a binding item. As Silverlight supports only a single converter per binding object, what do we do? The solution? Simply create a converter to wrap all other converters in sequence, with the help of Attributes decorations, so that it will call each converter top-down when calling Convert, and bottom-up when calling ConvertBack.

Please note: The follow code is my slight modification (for Silverlight) from the article by Josh Smith located at http://www.codeproject.com/KB/WPF/PipingValueConverters_WPF.aspx which is the solution implemented for WPF. Please have a read through that link to get a better understanding of what this class should be doing

Create two classes:

The Attribute Class

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

namespace SilverlightClassLibrary1

{

/// <summary>

/// This attribute is used to decorate the Converters for use with

/// PipeConverter

/// so that more than one converters can be called at anyone time.

/// </summary>

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]

public sealed class PipedConverterAttribute : Attribute

{

// Fields

private Type _parameterType;

private Type _sourceType;

private Type _targetType;

// Methods

public PipedConverterAttribute(Type sourceType,

Type targetType)

{

if (sourceType == null)

{

throw new ArgumentNullException("sourceType");

}

if (targetType == null)

{

throw new ArgumentNullException("targetType");

}

this._sourceType = sourceType;

this._targetType = targetType;

}

public override int GetHashCode()

{

return (this._sourceType.GetHashCode() +

this._targetType.GetHashCode());

}

// Properties

public Type ParameterType

{

get

{

return this._parameterType;

}

set

{

this._parameterType = value;

}

}

public Type SourceType

{

get

{

return this._sourceType;

}

}

public Type TargetType

{

get

{

return this._targetType;

}

}

}

}

The Actual PipedConverter:

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Data;

using System.Collections.Specialized;

using System.Collections;

using System.Collections.Generic;

using System.Collections.ObjectModel;

namespace SilverlightClassLibrary1

{

/// <summary>

/// This is used to group a list of converters together,

/// calling them in sequence.

/// Eg. If you have three items, the targetType of the

/// firstItem must match the sourceType

/// of the secondItem and so forth.

/// </summary>

[System.Windows.Markup.ContentProperty("Converters")]

public class PipedConverter : IValueConverter

{

#region Backing Fields

private readonly ObservableCollection<IValueConverter>

_converters = new ObservableCollection<IValueConverter>();

private readonly Dictionary<IValueConverter,

PipedConverterAttribute> _cachedAttributes

= new Dictionary<IValueConverter,

PipedConverterAttribute>();

#endregion // Data

#region Properties (Converters)

/// <summary>

/// Returns the list of IValueConverters contained

/// in this converter.

/// </summary>

public ObservableCollection<IValueConverter> Converters

{

get { return this._converters; }

}

#endregion // Converters

#region Constructor

public PipedConverter()

{

this._converters.CollectionChanged +=

this.OnConvertersCollectionChanged;

}

#endregion // Constructor

#region IValueConverter Members

object IValueConverter.Convert(object value, Type targetType,

object parameter, System.Globalization.CultureInfo culture)

{

object output = value;

for (int i = 0; i < this.Converters.Count; ++i)

{

IValueConverter converter = this.Converters[i];

Type currentTargetType =

this.GetTargetType(i, targetType, true);

output = converter.Convert(output,

currentTargetType, parameter, culture);

// If the converter didnt convert as expected then

// the binding operation should terminate.

if (output == DependencyProperty.UnsetValue)

break;

}

return output;

}

object IValueConverter.ConvertBack(object value,

Type targetType, object parameter,

System.Globalization.CultureInfo culture)

{

object output = value;

for (int i = this.Converters.Count - 1; i > -1; --i)

{

IValueConverter converter = this.Converters[i];

Type currentTargetType = this.GetTargetType(i,

targetType, false);

output = converter.ConvertBack(output,

currentTargetType, parameter, culture);

// If the converter didn’t convert as expected

// then the binding operation should terminate.

if (output == DependencyProperty.UnsetValue)

break;

}

return output;

}

#endregion

#region GetTargetType

/// <summary>

/// Returns the target type for a conversion operation.

/// </summary>

/// <param name="converterIndex">The index of the

/// current converter about to be executed.</param>

/// <param name="finalTargetType">The 'targetType'

/// argument passed into the conversion method.</param>

/// <param name="convert">Pass true if calling from the Convert

/// method, or false if calling from ConvertBack.</param>

protected virtual Type GetTargetType(int converterIndex,

Type finalTargetType, bool convert)

{

// If the current converter is not the last/first in the

// list, get a reference to the next/previous converter.

IValueConverter nextConverter = null;

if (convert) // Always forward until last item

{

if (converterIndex < this.Converters.Count - 1)

{

nextConverter =

this.Converters[converterIndex + 1];

if (nextConverter == null)

throw new InvalidOperationException();

}

}

else // Always going backwards until first item

{

if (converterIndex > 0)

{

nextConverter =

this.Converters[converterIndex - 1];

if (nextConverter == null)

throw new InvalidOperationException();

}

}

if (nextConverter != null)

{

// Get the attributes of the next converter

// and return the type

PipedConverterAttribute conversionAttribute =

_cachedAttributes[nextConverter];

// If the Convert method is going to be called,

// we need to use the SourceType of the next

// converter in the list. If ConvertBack is called,

// use the TargetType.

return convert ? conversionAttribute.SourceType :

conversionAttribute.TargetType;

}

// If the current converter is the last one to be executed

// return the target type passed into the conversion method.

return finalTargetType;

}

#endregion // GetTargetType

#region OnConvertersCollectionChanged

void OnConvertersCollectionChanged(object sender,

NotifyCollectionChangedEventArgs e)

{

// The 'Converters' collection has been modified,

// so validate that each value converter it now

// contains is decorated with ConverterAttribute and

// then cache the attribute value.

IList convertersToProcess = null;

if (e.Action == NotifyCollectionChangedAction.Add ||

e.Action == NotifyCollectionChangedAction.Replace)

{

convertersToProcess = e.NewItems;

}

else if (e.Action == NotifyCollectionChangedAction.Remove)

{

foreach (IValueConverter converter in e.OldItems)

this._cachedAttributes.Remove(converter);

}

else if (e.Action == NotifyCollectionChangedAction.Reset)

{

this._cachedAttributes.Clear();

convertersToProcess = this._converters;

}

if (convertersToProcess != null

&& convertersToProcess.Count > 0)

{

foreach (IValueConverter converter in convertersToProcess)

{

object[] attributes = converter.GetType()

.GetCustomAttributes(

typeof(PipedConverterAttribute), false);

if (attributes.Length != 1)

throw new InvalidOperationException();

this._cachedAttributes.Add(converter,

attributes[0]

as PipedConverterAttribute);

}

}

}

#endregion

}

}

Use it as such in your XAML resource file: (converter is the namespace of the PipedConverter)

<converter:PipedConverter x:Key="pipedConverter">
<converter:ConverterA />
<converter:ConverterB />
</converter:PipedConverter >
Also do decorate your converters like so: 

[PipedConverterAttribute(typeof(string), typeof(int))]

public class ConverterA : IValueConverter

Where string is the input type, and integer is the output type of the converter.