<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://bloggingabout.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Nathan J Pledger</title><subtitle type="html">Program.X musings from the Isle of Man concerning ASP.NET, in particular accessibility, web standards and neat ideas. </subtitle><id>http://bloggingabout.net/blogs/program.x/atom.aspx</id><link rel="alternate" type="text/html" href="http://bloggingabout.net/blogs/program.x/default.aspx" /><link rel="self" type="application/atom+xml" href="http://bloggingabout.net/blogs/program.x/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.40407.4157">Community Server</generator><updated>2008-05-24T10:59:54Z</updated><entry><title>Kendo UI: Managing data changes on the client and sending it back to ASP.NET MVC</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2011/12/14/kendo-ui-managing-data-changes-on-the-client-and-sending-it-back-to-asp-net-mvc.aspx" /><id>/blogs/program.x/archive/2011/12/14/kendo-ui-managing-data-changes-on-the-client-and-sending-it-back-to-asp-net-mvc.aspx</id><published>2011-12-14T15:48:36Z</published><updated>2011-12-14T15:48:36Z</updated><content type="html">&lt;p&gt;My few regular readers will know that I’m a big fan of &lt;a title="Telerik (external link)" href="http://telerik.com"&gt;Telerik&lt;/a&gt; and their products. Their product range is comprehensive, the support top-notch and their evangelism and engagement is second to none. Whilst usually involved in the .NET space from ASP.NET UI components through to testing platforms, they have recently branched out into an HTML5/JavaScript UI suite, called &lt;a title="Kendo UI (external link)" href="http://kendoui.com"&gt;Kendo UI&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The more time I spend with ASP.NET MVC, the more I learn about everything that is actually going on in a web request, which is no bad thing and highlights a fault of my own professional development; depending on ASP.NET WebForms to hide the guts of the HTTP request away from me. In gaining this “missing knowledge”, I’ve developed my JavaScript skills tremendously and as such am able to think up some sweet user experiences. &lt;/p&gt;  &lt;p&gt;My current requirement is a simple master-&amp;gt;detail data structure and editing experience. Obviously this data-structure should not require the user’s knowledge or understanding but as anyone knows, effectively creating a seamless master-&amp;gt;detail scenario without some degree of complexity or unnecessary user steps can be challenging. In playing around with the ASP.NET MVC grid it quickly became apparent that the guts of the grid control was becoming a barrier to rapid understanding and deployment, again, this considering I’m relatively new to MVC and the powered-by-unicorns “convention over configuration” pattern. What if I could rule out all the complex data-structure parsing, AJAX and the like and have the entire editing experience occur on the client?&lt;/p&gt;  &lt;p&gt;The Kendo UI suite does provide integration with the server and therefore actual data, but only insofar as facilitating AJAX requests. This is fine, as I’m fairly well versed in AJAX, JavaScript and the MVC pattern now. However, I wanted to avoid having to return to the server for “mini edits” via a full POST or AJAX. So I did not want:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Two steps: one for editing master data, the other for editing individual child data &lt;/li&gt;    &lt;li&gt;AJAX updates: updating child data in lieu of a complete POST and onward persistence (this would require some session state of some form which I am keen to avoid as this project is being developed with future cloud installation in mind) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;What I needed was complete client-side editing and a single POST.&lt;/p&gt;  &lt;p&gt;And it turns out it’s all very simple.&lt;/p&gt;  &lt;p&gt;Given the data structure:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/6622.LookupSet_2D00_LookupValue_5F00_01BA85A4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="LookupSet-LookupValue" border="0" alt="LookupSet-LookupValue" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8304.LookupSet_2D00_LookupValue_5F00_thumb_5F00_1A4A22F4.png" width="380" height="92" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I created the view with the KendoUI grid in, the model containing a series of properties that would hold the modifications made on the client and the controller to tie it all together.&lt;/p&gt;  &lt;h2&gt;View&lt;/h2&gt;  &lt;p&gt;The grid is easily created, much like a jQuery UI widget:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;div id=&amp;quot;valuesGrid&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;I wanted to handle everything on the client, so in in initialising my grid, I needed to consider how I was going to do this. I decided to create a few properties in my Model, which would be rendered as hidden input elements in the form element. This would allow me to manipulate items on the client and post back the individual fields as a single POST, processing them on the server. &lt;/p&gt;

&lt;p&gt;My fields are below (in Razor syntax):&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
@Html.HiddenFor(model=&amp;gt;model.OriginalLookupValuesJson)
@Html.HiddenFor(model =&amp;gt; model.NewLookupValuesJson)
@Html.HiddenFor(model =&amp;gt; model.EditedLookupValuesJson)
@Html.HiddenFor(model =&amp;gt; model.DeletedLookupValuesJson)
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;On the GET, the controller populates the detail records by setting the OriginalLookupValuesJson field to the JSON representation of the data-structure.&lt;/p&gt;

&lt;p&gt;On the client-side, these are manipulated by “overriding” the built-in CRUD methods of the Kendo UI grid:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-javascript"&gt;
$(document).ready(function () {
    var json = $(&amp;#39;input#OriginalLookupValuesJson&amp;#39;).val();
    var data = eval(&amp;#39;(&amp;#39;+json+&amp;#39;)&amp;#39;);
    var dataSource = new kendo.data.DataSource({
        transport: {
            read: function (options) { 
                options.success(data);
            },
            create: function (options) {
                $(&amp;quot;input#NewLookupValuesJson&amp;quot;).val(kendo.stringify(options.data.models));
            },
            update: function (options) {
                $(&amp;quot;input#EditedLookupValuesJson&amp;quot;).val(kendo.stringify(options.data.models));
            },
            destroy: function (options) {
                $(&amp;quot;input#DeletedLookupValuesJson&amp;quot;).val(kendo.stringify(options.data.models));
            }
        }, //transport
        batch: true,
        pageSize: 4,
        schema: {
            model: {
                id: &amp;quot;ID&amp;quot;,
                fields: {
                    ID: {
                        editable: false,
                        nullable: true
                    },
                    LookupSetID: {
                        editable: false,
                        nullable: true
                    },
                    Value: {
                        editable: true,
                        validation: {
                            required: true
                        }
                    },
                    Description: {
                        editable: true
                    }
                } //fields
            }, //model
            data: &amp;quot;data&amp;quot;,
            total: function (result) {
                result = result.data || result;
                return result.length || 0;
            } //total
        } //schema
    });

    $(&amp;quot;#valuesGrid&amp;quot;).kendoGrid({
        dataSource: dataSource,
        editable: true,
        toolbar: [&amp;quot;create&amp;quot;],
        height: 250,
        scrollable: true,
        sortable: true,
        filterable: false,
        pageable: true,
        columns: [
            {
                field: &amp;quot;Value&amp;quot;,
                title: &amp;quot;Value&amp;quot;
            },
            {
                field: &amp;quot;Description&amp;quot;,
                title: &amp;quot;Description&amp;quot;
            },
            {
                command: &amp;quot;destroy&amp;quot;
            }
        ]
    });
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The script implements the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Localises the JSON from the OriginalLookupValuesJson field into a variable, which is then evaluated into a JavaScript object&lt;/li&gt;

  &lt;li&gt;A dataSource object is then configured that takes the evaluated JavaScript object as a source for the read implementation. The create, update and destroy implementations are overridden by setting their output as the previously mentioned hidden fields. The results of which will be passed back into my Controller within the Model.&lt;/li&gt;

  &lt;li&gt;Initialises and configures the grid with the dataSource variable and the user-interface aspects I require.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, when you submit the form in a POST, the hidden fields used to monitor modifications are exactly as they were when they were requested: blank. You need to synchronise the internal data structures of the grid with the hidden fields by intercepting the form POST by adding the following BLOCKED SCRIPT&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-javascript"&gt;
$(&amp;quot;form&amp;quot;).bind(&amp;quot;submit&amp;quot;, sync);
});

function sync() {
    alert(&amp;#39;sync&amp;#39;);
    $(&amp;quot;#valuesGrid&amp;quot;).data(&amp;quot;kendoGrid&amp;quot;).dataSource.sync();
}
&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;Model&lt;/h2&gt;

&lt;p&gt;The Model itself is supremely simple and contains the principle object of the Master object (LookupSet) and the four fields used to store the JSON and allow the manipulation of the LookupValues on the client-side and persistence of the changes on the server-side.&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
public class LookupModel : ModelBase
{
    public LookupSet LookupSet { get; set; }
    public IEnumerable&amp;lt;SelectListItem&amp;gt; DataTypes { get; set; }
    public string OriginalLookupValuesJson { get; set; }
    public string NewLookupValuesJson { get; set; }
    public string EditedLookupValuesJson { get; set; }
    public string DeletedLookupValuesJson { get; set; }

    public LookupModel()
    {
    }

}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;I create my models within a Factory class, ModelFactory, which has a method:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
public static LookupModel CreateLookupModel(int id)
    {
        LookupModel model = new LookupModel(); 
        using (CoreEntities coreEntities = CoreEntitiesFactory.Create(configuration))
        {
            model.LookupSet = coreEntities.LookupSets.Include(&amp;quot;LookupValues&amp;quot;).SingleOrDefault(q =&amp;gt; q.ID == id);
            JavaScriptSerializer javaScriptSerializer=new JavaScriptSerializer();
            model.OriginalLookupValuesJson = javaScriptSerializer.Serialize(new { data = GetLookupValueModels(model) });
        }
        return model;
    }
&lt;/code&gt;&lt;/pre&gt;









&lt;p&gt;The method creates a new LookupModel and interrogates the data-store for the requested data. This is implemented using Entity Framework but obviously can be replaced with your own framework.&lt;/p&gt;

&lt;p&gt;In order to have the detail data (LookupValues) processed at the client, it needs to be serialized into JSON format, using the JavaScriptSerializer class. This is called with the result of the method GetLookupValueModels(), which is shown below:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
private static List&amp;lt;LookupValueModel&amp;gt; GetLookupValueModels(LookupModel model)
    {
        List&amp;lt;LookupValueModel&amp;gt; lookupValueModels = new List&amp;lt;LookupValueModel&amp;gt;();
        foreach (LookupValue lookupValue in model.LookupSet.LookupValues)
        {
            LookupValueModel lookupValueModel = new LookupValueModel()
            {
                Description = lookupValue.Description ?? string.Empty,
                ID = lookupValue.ID,
                LookupSetID = lookupValue.LookupSetID
            };
            if (model.LookupSet.DotNetDataType == typeof(string).FullName)
                lookupValueModel.Value = lookupValue.System_String;
            if (model.LookupSet.DotNetDataType == typeof(int).FullName &amp;amp;&amp;amp; lookupValue.System_Int32.HasValue)
                lookupValueModel.Value = lookupValue.System_Int32.Value.ToString();
            if (model.LookupSet.DotNetDataType == typeof(decimal).FullName &amp;amp;&amp;amp; lookupValue.System_Decimal.HasValue)
                lookupValueModel.Value = lookupValue.System_Decimal.Value.ToString();
            lookupValueModels.Add(lookupValueModel);
        }
        return lookupValueModels;
    }
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This takes the Entity Framework objects and creates a LookupValueModel for each, returning the result. This is then wrapped up in an anonymous type, which assigns the result to the “data” property. The result of which would be typically:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-javascript"&gt;
{
    &amp;quot;data&amp;quot;: [
        {
            &amp;quot;ID&amp;quot;: 3,
            &amp;quot;LookupSetID&amp;quot;: 2,
            &amp;quot;Value&amp;quot;: &amp;quot;XXX&amp;quot;,
            &amp;quot;Description&amp;quot;: &amp;quot;Description for XXX&amp;quot;
        },
        {
            &amp;quot;ID&amp;quot;: 4,
            &amp;quot;LookupSetID&amp;quot;: 2,
            &amp;quot;Value&amp;quot;: &amp;quot;YYY&amp;quot;,
            &amp;quot;Description&amp;quot;: &amp;quot;Description for YYY&amp;quot;
        },
        {
            &amp;quot;ID&amp;quot;: 5,
            &amp;quot;LookupSetID&amp;quot;: 2,
            &amp;quot;Value&amp;quot;: &amp;quot;ZZZ&amp;quot;,
            &amp;quot;Description&amp;quot;: &amp;quot;Description for ZZZ&amp;quot;
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;As this is placed in the model property OriginalLookupValuesJson, this is sent to the client as part of the form, and correctly rendered by the Kendo UI grid component.&lt;/p&gt;

&lt;h2&gt;Controller&lt;/h2&gt;

&lt;p&gt;For completeness, the HTTP GET request is implemented by the controller as follows:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
public ActionResult EditLookup(int id)
    {
        ActionResult result;
        LookupModel model = ModelFactory.CreateLookupModel(id);
        if (model.LookupSet == null)
        {
            result = View(&amp;quot;InvalidLookup&amp;quot;, ModelFactory.Create&amp;lt;GenericPageModel&amp;gt;(&amp;quot;Invalid lookup&amp;quot;));
        }
        else
        {
            model.Title = string.Format(&amp;quot;Edit lookup &amp;#39;{0}&amp;#39;&amp;quot;, model.LookupSet.Name);
            result = View(&amp;quot;EditLookup&amp;quot;, model);
        }
        return result;
    }
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;But where we are interested in is the POST, which will take the modified values from the hidden form fields and implement the modifications on the data-store. The modifications arrive within the hidden fields as JSON, so it is a simple matter to rehydrate those to usable data that we can work with by deserializing the LookupValues back into CLR objects. I use the Deserialize&amp;lt;T&amp;gt;() method from this &lt;a title="Deserialize&amp;lt;T&amp;gt; StackOverflow post (external link)" href="http://stackoverflow.com/questions/2246694/how-to-convert-json-object-to-custom-c-sharp-object"&gt; StackOverflow post (external link)&amp;quot; href=&amp;quot;http://stackoverflow.com/questions/2246694/how-to-convert-json-object-to-custom-c-sharp-object&amp;quot;&amp;gt;StackOverflow&lt;/a&gt; post:&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
private static T Deserialize&amp;lt;T&amp;gt;(string json)
    {
        T obj = Activator.CreateInstance&amp;lt;T&amp;gt;();
        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        obj = (T)serializer.ReadObject(ms);
        ms.Close();
        return obj;
    }
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Then I call that for each of the modification types in the HTTP POST handler of my Controller (excluding the wider persistence code):&lt;/p&gt;



&lt;pre&gt;&lt;code class="language-csharp"&gt;
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditLookup(LookupModel model)
{
    ActionResult result = View(model);
    if (ModelState.IsValid)
    {
                    List&amp;lt;LookupValueModel&amp;gt; modifiedLookupValues = Deserialize&amp;lt;List&amp;lt;LookupValueModel&amp;gt;&amp;gt;(model.EditedLookupValuesJson);
                    List&amp;lt;LookupValueModel&amp;gt; createdLookupValues = Deserialize&amp;lt;List&amp;lt;LookupValueModel&amp;gt;&amp;gt;(model.NewLookupValuesJson);
                    List&amp;lt;LookupValueModel&amp;gt; deletedLookupValues = Deserialize&amp;lt;List&amp;lt;LookupValueModel&amp;gt;&amp;gt;(model.DeletedLookupValuesJson);
    }

    return result;
}
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;How you handle the individual CUD methods is dependent on your persistence layer.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=577008" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author></entry><entry><title>Silverlight and ASP.NET compatible WCF over SSL using custom username/password authentication</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2011/01/20/silverlight-and-asp-net-compatible-wcf-over-ssl.aspx" /><id>/blogs/program.x/archive/2011/01/20/silverlight-and-asp-net-compatible-wcf-over-ssl.aspx</id><published>2011-01-20T21:12:00Z</published><updated>2011-01-20T21:12:00Z</updated><content type="html">&lt;p&gt;WCF, as you probably know, can be a hugely flexible, but equally complicated beast. The domain knowledge stretches from the .NET stack to identity management, encryption and transport. &amp;ldquo;Out of the box&amp;rdquo;, it&amp;rsquo;s pretty straight forward, but the demos and examples often presented by Microsoft are often far from what is needed in real life. Bloggers and authors present excellent examples, but these often fail at the last hurdle where Silverlight compatibility or specific authentication is required. Hopefully, this solution will be a &amp;ldquo;one-stop shop&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;We needed to be able to deploy software that was loosely coupled via web services, with multiple client platforms. Therefore, we needed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Secure communications, even though most our work is intranet based, securing the transport of the data was a must so we can scale up onto the internet as required. &lt;/li&gt;
&lt;li&gt;Low maintenance, I approach everything pragmatically. If it is over-complicated for us to produce, it will be over-complicated for the user to maintain. Simplicity is king. &lt;/li&gt;
&lt;li&gt;Ability to work over internet as well as internet, according to application and scalability. &lt;/li&gt;
&lt;li&gt;ASP.NET and Silverlight compatibility, the latter already being stymied due to lack of support of the altogether simpler wsHttpBinding. (Most of the SSL examples being internet-based using wsHttpBinding) &lt;/li&gt;
&lt;li&gt;Allow transmission of credentials in each transaction and have those credentials (which are not Windows-based) verified each time. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What seemed like an impossible combination has at last been been achieved (by myself, anyway). After trawling through countless blogs, questions and white-papers, I&amp;rsquo;m going to share with you how to create a reliable, secure WCF service that may be redeployed across projects, even with the limited capabilities of Silverlight.&lt;/p&gt;
&lt;h2&gt;Generation of SSL Certificate&lt;/h2&gt;
&lt;p&gt;If we&amp;rsquo;re transmitting sensitive data, it should be secure. Sensitive data includes the username and password and WCF reinforces this by requiring you to use security over transport if using username/password authentication. &lt;/p&gt;
&lt;p&gt;To create or assign the certificate, you need to use the IIS Server Certificates administration module within the Server tree:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/6318.20_2D00_01_2D00_2011_2D00_18_2D00_39_2D00_07_2D00_small_5F00_0E9DFA26.png"&gt;&lt;img height="292" width="454" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4213.20_2D00_01_2D00_2011_2D00_18_2D00_39_2D00_07_2D00_small_5F00_thumb_5F00_209A17E6.png" alt="20-01-2011 18-39-07-small" border="0" title="20-01-2011 18-39-07-small" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can then choose to import an existing certificate, or create a self-signed certificate. If you create a self-signed certificate, it is only of use during the development phase and will introduce problems for you (which we can overcome).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1256.20_2D00_01_2D00_2011_2D00_18_2D00_39_2D00_37_2D00_small_5F00_65663C1A.png"&gt;&lt;img height="291" width="454" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7585.20_2D00_01_2D00_2011_2D00_18_2D00_39_2D00_37_2D00_small_5F00_thumb_5F00_4AB9A001.png" alt="20-01-2011 18-39-37-small" border="0" title="20-01-2011 18-39-37-small" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I created a self-signed certificate to show you the difficulties and how to get round them.&lt;/p&gt;
&lt;h2&gt;Creation of the Service&lt;/h2&gt;
&lt;p&gt;The service code is straight forward. I like to separate the interface from the implementation.&lt;/p&gt;
&lt;h6&gt;IClientService&lt;/h6&gt;


&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Runtime.Serialization; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel.Web; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Text; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&lt;/span&gt;
&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; Services.Api.Wcf &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[ServiceContract]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IClientService &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[OperationContract] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetAllClientIDs(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; } &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;The implementation class includes the requirement for ASP.NET Compatibility mode. &lt;/p&gt;
&lt;h6&gt;ClientService.svc&lt;/h6&gt;


&lt;span style="color:#000000;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#000000;"&gt;@ ServiceHost Language&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;C#&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Debug&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;true&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Service&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Services.Api.Wcf.ClientService&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; CodeBehind&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ClientService.svc.cs&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;%&amp;gt;&lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;h6&gt;ClientService.svc.cs&lt;/h6&gt;


&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Runtime.Serialization; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel.Web; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Text; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel.Activation; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Web; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; Services.Api.Wcf &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [AspNetCompatibilityRequirements(RequirementsMode &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; AspNetCompatibilityRequirementsMode.Allowed)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; ClientService : ServiceBase, IClientService &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;#region&lt;/span&gt;&lt;span style="color:#000000;"&gt; ~ from IClientService ~&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; GetAllClientIDs() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClientRepository clientRepository &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; ClientRepositoryFactory.CreateForUser(UserName); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(clientRepository.Clients.Select(q &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; q.IndexNo));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;#endregion&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;h6&gt;Web.config&lt;/h6&gt;
&lt;p&gt;The most challenging part of WCF is getting the configuration right. &lt;/p&gt;
&lt;p&gt;


&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;behaviors&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;behavior &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;sslBehaviour&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceMetadata &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;httpGetEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; httpsGetEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceDebug &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;includeExceptionDetailInFaults&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceCredentials&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;userNameAuthentication &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;userNamePasswordValidationMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Custom&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; customUserNamePasswordValidatorType&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Core.WcfUserNamePasswordValidator, Core&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceCredentials&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;behavior&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;behaviors&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;bindings&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;customBinding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;binding &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;sslCustomBinding&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;security &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;authenticationMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;UserNameOverTransport&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;binaryMessageEncoding &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;httpsTransport &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;
&lt;span style="color:#000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;binding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;customBinding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;bindings&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;services&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;service &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Services.Api.Wcf.ClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; behaviorConfiguration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;sslBehaviour&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;baseAddresses&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;add &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;baseAddress&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;https://mymachine.domain.local/&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;baseAddresses&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;endpoint &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; binding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;customBinding&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; bindingConfiguration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;sslCustomBinding&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; contract&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Services.Api.Wcf.IClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;endpoint&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;endpoint &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;mex&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; binding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;mexHttpBinding&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; contract&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;IMetadataExchange&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;service&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;services&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;serviceHostingEnvironment &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;multipleSiteBindingsEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;/p&gt;
&lt;p&gt;The first element, behavior, defines the SSL configuration of the services that may be attached to it. The important point is the serviceCredentials/userNameAuthentication, which defines the class that will perform the authentication.&lt;/p&gt;
&lt;p&gt;Silverlight can only support basicHttpbinding, so it is necessary to define a customBinding. This is defined in the customBinding/binding element, and is set to use the UserNameOverTransport authenticationMode (which requires secure transport) and defines the transport as secure by using httpsTransport.&lt;/p&gt;
&lt;p&gt;The service itself is defined in the service element, which ties together the bindingConfiguration and behaviorConfiguration. Additionally, the baseAddresses element defines the address that the service will respond to. Note that this is HTTPS. This will obviously need to be changed when deployed. We use the &lt;a href="http://msdn.microsoft.com/en-us/library/dd465326.aspx" title="Web.config transformations at MSDN (external link)"&gt;Web.config transformation&lt;/a&gt; feature to achieve this.&lt;/p&gt;
&lt;p&gt;The authentication class is shown below and may be as simple or as advanced as you need. Obviously, this is where you verify the authentication against your custom provider.&lt;/p&gt;
&lt;h6&gt;WcfUserNamePasswordValidator.cs&lt;/h6&gt;


&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Text; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.IdentityModel.Selectors; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; Core &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; WcfUserNamePasswordValidator : UserNamePasswordValidator&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Validate(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; userName, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; password) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (userName&lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;username&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#000000;"&gt; password&lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;password&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;) &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FaultException(&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Invalid username/password&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; } &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;This service may be deployed on the web server and tested using the HTTPS address. As we created our own self-signed certificate, there will be a Certificate Warning, which we&amp;rsquo;ll ignore for now.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2744.20_2D00_01_2D00_2011_2D00_20_2D00_29_2D00_01_2D00_small_5F00_2CF81542.png"&gt;&lt;img height="406" width="554" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/6560.20_2D00_01_2D00_2011_2D00_20_2D00_29_2D00_01_2D00_small_5F00_thumb_5F00_6053D89E.png" alt="20-01-2011 20-29-01-small" border="0" title="20-01-2011 20-29-01-small" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Creation of the Client&lt;/h2&gt;
&lt;p&gt;First step when working with the client-side code is to point to the service web-site. Clicking on Add Service Reference and enter the HTTPS address. Again, if you are using a self-signed certificate, you will be warned of this.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0827.20_2D00_01_2D00_2011_2D00_20_2D00_38_2D00_57_2D00_small_5F00_49B18A57.png"&gt;&lt;img height="358" width="404" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/3580.20_2D00_01_2D00_2011_2D00_20_2D00_38_2D00_57_2D00_small_5F00_thumb_5F00_167550EE.png" alt="20-01-2011 20-38-57-small" border="0" title="20-01-2011 20-38-57-small" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click &amp;ldquo;Yes&amp;rdquo;, then &amp;ldquo;OK&amp;rdquo; to generate the proxy code. Once generated, you&amp;rsquo;re ready to use it. This adds a configuration such as the section below:&lt;/p&gt;


&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;bindings&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;customBinding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;binding &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;CustomBinding_IClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;security &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;defaultAlgorithmSuite&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Default&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; authenticationMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;UserNameOverTransport&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; requireDerivedKeys&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; securityHeaderLayout&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Strict&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; includeTimestamp&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; keyEntropyMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;CombinedEntropy&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; messageSecurityVersion&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;localClientSettings &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;cacheCookies&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; detectReplays&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; replayCacheSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;900000&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxClockSkew&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxCookieCachingTime&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Infinite&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; replayWindow&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; sessionKeyRenewalInterval&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;10:00:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; sessionKeyRolloverInterval&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; reconnectTransportOnFailure&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; timestampValidityDuration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; cookieRenewalThresholdPercentage&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;60&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;localServiceSettings &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;detectReplays&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; issuedCookieLifetime&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;10:00:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxStatefulNegotiations&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;128&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; replayCacheSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;900000&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxClockSkew&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; negotiationTimeout&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:01:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; replayWindow&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; inactivityTimeout&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:02:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; sessionKeyRenewalInterval&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;15:00:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; sessionKeyRolloverInterval&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; reconnectTransportOnFailure&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxPendingSessions&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;128&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxCachedCookies&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;1000&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; timestampValidityDuration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;00:05:00&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;secureConversationBootstrap &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;security&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;binaryMessageEncoding &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;maxReadPoolSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;64&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxWritePoolSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;16&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxSessionSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;2048&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;readerQuotas &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;maxDepth&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;32&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxStringContentLength&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;8192&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxArrayLength&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;16384&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxBytesPerRead&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;4096&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxNameTableCharCount&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;16384&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;binaryMessageEncoding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;httpsTransport &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;manualAddressing&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxBufferPoolSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;524288&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxReceivedMessageSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;65536&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; allowCookies&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; authenticationScheme&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Anonymous&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; bypassProxyOnLocal&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; decompressionEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; hostNameComparisonMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;StrongWildcard&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; keepAliveEnabled&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; maxBufferSize&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;65536&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; proxyAuthenticationScheme&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Anonymous&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; realm&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; transferMode&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Buffered&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; unsafeConnectionNtlmAuthentication&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; useDefaultWebProxy&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; requireClientCertificate&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;binding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;customBinding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;bindings&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;client&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;endpoint &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;https://api1test.mydomain.local/api/wcf/ClientService.svc&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; binding&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;customBinding&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; bindingConfiguration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;CustomBinding_IClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; contract&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ClientEndpoints.Clients.IClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;CustomBinding_IClientService&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;client&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Before we do, I would recommend you use this segment of code originally developed by &lt;a href="http://nimtug.org/blogs/damien-mcgivern/archive/2009/05/26/wcf-communicationobjectfaultedexception-quot-cannot-be-used-for-communication-because-it-is-in-the-faulted-state-quot-messagesecurityexception-quot-an-error-occurred-when-verifying-security-for-the-message-quot.aspx" title="Damien McGivern&amp;#39;s site (external link)"&gt;Damien McGivern&lt;/a&gt;, which will aid in the catching of exceptions. As Damien mentions on his site, the WCF stack doesn&amp;rsquo;t &amp;ldquo;break&amp;rdquo; where you&amp;rsquo;d expect, making diagnosis difficult.&lt;/p&gt;
&lt;p&gt;The ServiceHelper class acts as a Factory for generation of proxy objects.&lt;/p&gt;
&lt;h6&gt;ServiceHelper.cs&lt;/h6&gt;


&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Text; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.ServiceModel; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AspNet &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; ServiceHelper&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;
&lt;span style="color:#008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; WCF proxys do not clean up properly if they throw an exception. This method ensures that the service proxy is handeled correctly. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; Do not call TService.Close() or TService.Abort() within the action lambda.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;typeparam name=&amp;quot;TService&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;The type of the service to use&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/typeparam&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#808080;"&gt;///&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;param name=&amp;quot;action&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000;"&gt;Lambda of the action to performwith the service&lt;/span&gt;&lt;span style="color:#808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color:#808080;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Using&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;TService&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(Action&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;TService&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; action) &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;where&lt;/span&gt;&lt;span style="color:#000000;"&gt; TService : ICommunicationObject, IDisposable, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt;() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var service &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; TService();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; success &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;false&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;try&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; action(service);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (service.State &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; CommunicationState.Faulted)&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; service.Close(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; success &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;finally&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#000000;"&gt;!&lt;/span&gt;&lt;span style="color:#000000;"&gt;success) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;service.Abort();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt; } &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;So you can create the reference to the client proxy and use the service using code such as:&lt;/p&gt;
&lt;h6&gt;Default.aspx.cs&lt;/h6&gt;


&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Linq; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Web;&lt;br /&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Web.UI; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Web.UI.WebControls; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Configuration; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Net; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Net.Security; &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Web.Security; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; Web.Client &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;partial&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; _Default : System.Web.UI.Page&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Page_Load(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; sender, EventArgs e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; this delegate may be used to ignore SSL/TLS errors&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; it disables SSL certificate path verification for the AppDomain &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; Make sure you remove it before production!&lt;/span&gt;&lt;span style="color:#008000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;ServicePointManager.ServerCertificateValidationCallback &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; RemoteCertificateValidationCallback( &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;delegate&lt;/span&gt;&lt;span style="color:#000000;"&gt; { &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ServiceHelper.Using&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;ClientServiceClient&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(client &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;client.ClientCredentials.UserName.UserName &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;username&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client.ClientCredentials.UserName.Password &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#800000;"&gt;password&lt;/span&gt;&lt;span style="color:#800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] clientIDs&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;client.GetClientIDs();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp; } &lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Note the delegate that I have highlighted. Without this delegate, a self-signed certificate will cause an exception, preventing communication with the server. This delegate is called during this verification and overrides the default behaviour. As this essentially skips the verification of certificates, it shouldn&amp;rsquo;t make it to a production deployment. (See &lt;a href="http://www.thejoyofcode.com/WCF_Could_not_establish_trust_relationship_for_the_SSL_TLS_secure_channel_with_authority.aspx" title="The Joy of Code (external link)"&gt;The Joy of Code&lt;/a&gt; for the source of this information)&lt;/p&gt;
&lt;p&gt;This configuration should now work. One piece of the puzzle remains; how to identify which user is accessing the web methods. This may be achieved using the following code segment, which can be added to the service methods:&lt;/p&gt;


&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; userName&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;OperationContext.Current.IncomingMessageProperties.Security.ServiceSecurityContext.PrimaryIdentity.Name;&lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;There are a few gotchas and tips I learnt during this work which you might find helpful.&lt;/p&gt;
&lt;h2&gt;Useful bits&lt;/h2&gt;
&lt;p&gt;Make sure that the server and client times are within the time span specified in the maxClockSkew attribute. If the time difference between the machines is greater than this time span, verification will fail. Frustratingly, Googling/Binging for the exception returned by WCF returns 99.9% related to this issue &amp;ndash; you&amp;rsquo;ll probably need to look deeper to find out what actually causes your issue if your clocks marry up. Of course, if you&amp;rsquo;re deploying an intranet application, you lose control here.&lt;/p&gt;
&lt;p&gt;WCF rarely provides useful exceptions. Remember to add the following configuration segment to your server configuration and use the WcfTraceViewer tool within the Windows SDK to diagnose issues. It is invaluable!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;


&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;sources&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;source &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;System.ServiceModel&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; switchValue&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Information, ActivityTracing&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; propagateActivity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;listeners&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;add &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;traceListener&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;System.Diagnostics.XmlWriterTraceListener&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; initializeData&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;= &amp;quot;D:\dev\Services\App_Data\Logging\Wcf\log.svclog&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;listeners&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;source&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;sources&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;/p&gt;
&lt;p&gt;Remember that Silverlight won&amp;rsquo;t communicate across domains to your web service, so you may need a &lt;a href="http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx" title="Making a Service Available Across Domain Boundaries (external link)"&gt;clientaccesspolicy.xml or crossdomain.xml policy&lt;/a&gt; on your web site.&lt;/p&gt;
&lt;h2&gt;Recommended Reading&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve trawled through a number of books to help in cracking this, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Silverlight 4 Data and Services Cookbook&lt;/strong&gt;, Cleeron and Dockx, Packt Publishing ISBN 9781847199843 (Chapter 7) &amp;ndash; invaluable as the examples are inevitably pragmatic and therefore more useful.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Programming WCF Services&lt;/strong&gt;, L&amp;ouml;wy, O&amp;rsquo;Reilly ISBN 9780596521301 &amp;ndash; a great book for background reading, if only to find out what I couldn&amp;rsquo;t or shouldn&amp;rsquo;t use due to my Silverlight requirement. Essential reading if you want to get deeper into authentication over WCF such as using the certificates as authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;d be interested in improvements you may think of.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=484654" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="WCF" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/WCF/default.aspx" /><category term="Silverlight" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Silverlight/default.aspx" /></entry><entry><title>Testing Entity Framework 4</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2010/06/12/testing-entity-framework-4.aspx" /><id>/blogs/program.x/archive/2010/06/12/testing-entity-framework-4.aspx</id><published>2010-06-12T10:30:00Z</published><updated>2010-06-12T10:30:00Z</updated><content type="html">&lt;p&gt;Entity Framework has previously been a real pain in the backside to unit test and this slowed my own development of unit testing skills. It&amp;rsquo;s so much quicker to &amp;ldquo;just get it done&amp;rdquo; when deadlines loom. The new Entity Framework 4 promised POCO (Plain-old-CLR-objects) support which allows us to separate our concerns from the underlying database, just what you need to &amp;ldquo;mock out&amp;rdquo; the database.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve spent hours trawling through Microsoft&amp;rsquo;s own recommendations and others&amp;rsquo;, but I just couldn&amp;rsquo;t find a model that was actually usable or reasonable. That said, I have drawn heavily from Microsoft&amp;rsquo;s own solutions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/ff714955.aspx" title="Testability and Entity Framework 4 (external link)"&gt;Testability and Entity Framework 4&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx" title="Walkthrough: POCO Template for Entity Framework (external link)"&gt;Walkthrough: POCO Template for Entity Framework&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My complaints for the above solutions were two fold. Firstly, they (and indeed the practicalities of implementing an abstracted Repository pattern) seem to push you towards strongly typing your Repository to a particular class within your domain. So, you would have a CustomerRepository, an InvoiceRepository, etc. These would be either strongly typed or implemented through Generics, such as Repository&amp;lt;TEntity&amp;gt;. Patterns often don&amp;rsquo;t map well to &amp;ldquo;real life&amp;rdquo;, and I&amp;rsquo;m a great fan of real life. In real life, objects interact with other objects and restricting Repositories by Types isn&amp;rsquo;t going to help this interaction. Secondly, the UnitOfWork pattern seemed superfluous and it just ended up with added levels of abstraction that I don&amp;rsquo;t feel were worth the lines of code.&lt;/p&gt;
&lt;p&gt;This post will detail how I have implemented a common pattern that is easily unit testable/mockable. It is not a panacea for all, though. Deadlines and commercial constraints enforce a degree of the &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html" title="Duct-tape programmer - Joel on Software (external link)"&gt;Duct-tape programmer&lt;/a&gt; in my work and I have had to make compromises. While I would have liked to mock the concrete data objects themselves and handle through interfaces (eg. ICustomer), this was not possible due to casting through IObjectSet&amp;lt;T&amp;gt;, so I&amp;rsquo;ve settled on using the generated concrete data objects instead. Therefore, the references to the Entity Framework DLLs (and therefore database reliant code) is required &amp;ndash; though not used for database access.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I did it, do let me know if you have any comments on my implementation &amp;hellip;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve prepared a diagram to try and illustrate the method:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/3858.Schematic_5F00_56294C76.png"&gt;&lt;img height="324" width="520" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2656.Schematic_5F00_thumb_5F00_0DFB909A.png" alt="Schematic" border="0" title="Schematic" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The Concrete Entity Framework is a standard configuration, and is abstracted away by the IRepositoryObjectContext interface. This allows the development of a side-by-side Testing Context, using Entity Framework-generated POCO classes, but using the same concrete generated classes as the standard Entity Framework. Client applications (including Test harnesses, etc.) access the appropriate context via the Repository, which is injected with the appropriate instance of IRepositoryObjectContext. The Business/ORM objects are implemented as interfaces and presented to the client application as interfaces, not as the original classes. This does pose problems in hydration of objects through WCF, etc. but Entity Framework doesn&amp;rsquo;t deal well with that anyway, so DTOs are still the order of the day.&lt;/p&gt;
&lt;p&gt;First, I created a new Solution. This would represent the end application in reality, but just to test this, it&amp;rsquo;s just for the purpose of illustrating/testing the methodology. The Solution contains the &amp;ldquo;business&amp;rdquo; layer (&amp;ldquo;PatternsAndPractises.TestableEntityFramework&amp;rdquo;), the client application (&amp;ldquo;PatternsAndPractises.TestableEntityFramework4.Web.Client&amp;rdquo; &amp;ndash; in this case an ASP.NET Web Application) and the Test project (&amp;ldquo;PatternsAndPractises.TestableEntityFramework4.Tests&amp;rdquo; &amp;ndash; using the Test Project template).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/3438.12062010113340_5F00_0BA6E442.png"&gt;&lt;img height="155" width="412" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4861.12062010113340_5F00_thumb_5F00_3FDB0D88.png" alt="Solution screenshot" border="0" title="Solution screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The database is stored within the App_Data folder of the web application, which is fairly typical. I&amp;rsquo;ve created a single Customers table in it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7762.12062010114156_5F00_1834915E.png"&gt;&lt;img height="484" width="332" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/3056.12062010114156_5F00_thumb_5F00_0EF8561D.png" alt="Database in Solution screenshot" border="0" title="Database in Solution screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The Customers table has a primary key of integer set to identity increment and a string (VARCHAR/NVARCHAR) field CustomerName.&lt;/p&gt;
&lt;p&gt;The next step is to integrate Entity Framework into the project. I created a Data folder (and therefore namespace for new files) that will contain the persistence-layer objects and contexts. Inside here, I created the Entity Model by using &amp;ldquo;Add New Item&amp;rdquo; and selecting &amp;ldquo;ADO.NET Entity Data Model&amp;rdquo;, and following the wizard to extract the schema from the database, select the database created earlier and add the tables. I&amp;rsquo;ve now got a [simplistic] model. Opening the generated &amp;ldquo;code-behind&amp;rdquo; within the Model.Designer.cs file reveals the class used to manage the entities, TestDatabaseEntities (which will be derived from the settings you chose while you were configuring the wizard).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8154.12062010115147_5F00_0C6F245F.png"&gt;&lt;img height="484" width="635" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0488.12062010115147_5F00_thumb_5F00_17B8389C.png" alt="Data Model generated context class" border="0" title="Data Model generated context class" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This generated class is important as it provides the means by which we can extend the basic generated implementation to abstract away the database-code. To achieve this, we create a new class, make it partial and apply the same class name. &lt;/p&gt;
&lt;p&gt;In addition, we make it implement the interface IRepositoryObjectContext. The interface doesn&amp;rsquo;t exist yet, but this will give us the abstraction layer we need to present different entity contexts to our repository later. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4405.12062010115919_5F00_499FB359.png"&gt;&lt;img height="281" width="454" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4113.12062010115919_5F00_thumb_5F00_5CE069F8.png" alt="TestDatabaseEntities partial class screenshot" border="0" title="TestDatabaseEntities partial class screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;To create the interface, IRepositoryObjectContext, we&amp;rsquo;ll add a new interface at the project level (ie. above the Data folder/namespace) and define the implementation:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7674.12062010120232_5F00_2DAE7E61.png"&gt;&lt;img height="371" width="618" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2262.12062010120232_5F00_thumb_5F00_7EE8C5BE.png" alt="IRepositoryObjectContext screenshot" border="0" title="IRepositoryObjectContext screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This interface needs to expose the bare minimum required for the Repository to be able to interact with the data-store (physical or otherwise). The CustomersSet is used to abstract away the implementation of the set used by the Entity Data Context class (but not the generated concrete data class). This provides all the services a Repository would expect from an Entity Framework API. The SaveChanges method provides persistence of changes to objects. This interface also implements IDisposable, which allows the use of the using() {} block for automatic resource clean-up even though we&amp;rsquo;re abstracting away the Entity Framework API. We don&amp;rsquo;t need to implement the IDisposable interface, the generated code from Entity Framework does this for us.&lt;/p&gt;
&lt;p&gt;This abstracts-away the implementation detail of Entity Framework, but it still relies on the concrete generated data classes (for example, Customer) and some awareness that the application is using Entity Framework. This is where the Repository class comes in.&lt;/p&gt;
&lt;pre&gt;using System;
using System.Collections.Generic;
using System.Linq; 
using System.Text;
using System.Data.Objects;
using PatternsAndPractises.TestableEntityFramework4.Data;

namespace PatternsAndPractises.TestableEntityFramework4 
{
    public class Repository : IDisposable
    {
        protected IRepositoryObjectContext RepositoryObjectContext 
		{ get; private set; }

	#region ~ Constructors ~

	public Repository(
		IRepositoryObjectContext repositoryObjectContext)
        {
            RepositoryObjectContext = repositoryObjectContext;
        }

	#endregion

	public ICustomer CreateCustomer()
        {
            ICustomer newCustomer = new Customer();
            newCustomer.CustomerName = &amp;quot;New Customer&amp;quot;;
            return newCustomer;
        }

	public void AddCustomer(ICustomer customer)
        {
            RepositoryObjectContext
		.CustomersSet.AddObject((Customer)customer); 
        }

	public void SaveChanges()
        {
            RepositoryObjectContext.SaveChanges();
        }
	
	public IQueryable&amp;lt;ICustomer&amp;gt; Customers
        {
            get
            {
                return 
			(IQueryable&amp;lt;Customer&amp;gt;)
			RepositoryObjectContext.CustomersSet;
            }
        }

	#region ~ from IDisposable ~

	public void Dispose()
        {
            RepositoryObjectContext.Dispose();
        }

	#endregion
    }
}&lt;/pre&gt;
&lt;p&gt;This class is the point at which the abstraction of the Entity Framework is implemented, by virtue of injecting the IRepositoryObjectContext implementing class into the constructor. We&amp;rsquo;ve only got one of these at the moment, being the actual Entity Framework generated class, coupled with our partial extension and implementation of IRepositoryObjectContext.&lt;/p&gt;
&lt;p&gt;The Repository uses the IRepositoryObjectContext to implement the standard CRUD functionality of adding, saving and querying data. The CreateCustomer() method simply creates an object, and does not persist it. I like the idea of &amp;ldquo;default objects&amp;rdquo; to be creatable then sent to the user interface which can then provide additional logic such as undo-steps, etc. The class provides the Customers of the underlying Entity Framework via the CustomersSet property, but cast to an IQueryable&amp;lt;ICustomer&amp;gt; set. This removes the additional functionality provided by the Entity Framework 4 IObjectSet&amp;lt;T&amp;gt; class and casts it to the ICustomer interface, effectively making the set read-only. The ICustomer interface will abstract away the concrete data class, Customer. Finally, we implement IDisposable, which propagates the disposal upto the repository and finally, the Entity Data Context.&lt;/p&gt;
&lt;p&gt;To complete the circle, the ICustomer class means that when the client application works with Customers, it always works with ICustomer and therefore doesn&amp;rsquo;t need to involve itself with the concrete generated data classes. The ICustomer interface defines the properties and access permissions for individual fields, you wouldn&amp;rsquo;t want the primary key to be set, for example:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0755.12062010122948_5F00_5EFF1CEA.png"&gt;&lt;img height="270" width="644" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8308.12062010122948_5F00_thumb_5F00_3D9F774E.png" alt="ICustomer screenshot" border="0" title="ICustomer screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In order that the generated Customer concrete class implements the ICustomer interface, we create a partial class, Customer:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0181.12062010130803_5F00_58F27A04.png"&gt;&lt;img height="188" width="439" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1856.12062010130803_5F00_thumb_5F00_18502D95.png" alt="12-06-2010 13-08-03" border="0" title="12-06-2010 13-08-03" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This essentially completes the business object layer, which is immediately usable by a client application. The project would look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8080.12062010123129_5F00_430DE7F2.png"&gt;&lt;img height="241" width="292" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0777.12062010123129_5F00_thumb_5F00_026B9B83.png" alt="Completed business-layer project screenshot" border="0" title="Completed business-layer project screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Notice the RepositoryFactory class. This simple creates an instance of the Repository class, injecting the appropriate data context as an implementation of the IRepositoryObjectContext interface:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/6443.12062010123257_5F00_73C0EF9D.png"&gt;&lt;img height="293" width="537" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8540.12062010123257_5F00_thumb_5F00_63D1AAD9.png" alt="RepositoryFactory screenshot" border="0" title="RepositoryFactory screenshot" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;Adding Testability&lt;/h2&gt;
&lt;p&gt;The testing portions of the solution will be added to the PatternsAndPractises.TestableEntityFramework4.Tests project, which will attempt to mirror&amp;nbsp; the business layer in all respects except for the persistence of data.&lt;/p&gt;
&lt;p&gt;In the same way as the business layer, we shall separate our classes into persistence and logical layers by adding the Data folder/namespace.&lt;/p&gt;
&lt;p&gt;Within this folder we need to mimic the Entity Framework API, which is made possible by the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/en-us/23df0450-5677-4926-96cc-173d02752313" title="POCO Template for Entity Framework (external link)"&gt;POCO Template for Entity Framework&lt;/a&gt;. Downloading this and installing into Visual Studio allows the creation of &lt;a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" title="Text Transformation Toolkit (external link)"&gt;T4&lt;/a&gt; templates according to the schema already defined in the Entity Model we created earlier, and it&amp;rsquo;s easily done.&lt;/p&gt;
&lt;p&gt;Going back to the Entity Model defined earlier, right-click on the design surface (not on an object) and select &amp;ldquo;Add Code Generation Item&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0268.12062010124838_5F00_25B6409B.png"&gt;&lt;img height="220" width="244" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/5850.12062010124838_5F00_thumb_5F00_0BE20A6C.png" alt="12-06-2010 12-48-38" border="0" title="12-06-2010 12-48-38" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Once prompted, select &amp;rdquo;ADO.NET POCO Entity Generator&amp;rdquo; and name the item, for example &amp;ldquo;MockableModel&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1884.12062010124942_5F00_51F2C77F.png"&gt;&lt;img height="304" width="440" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7028.12062010124942_5F00_thumb_5F00_4FD5C8B6.png" alt="12-06-2010 12-49-42" border="0" title="12-06-2010 12-49-42" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The T4 templates will be created, which in turn auto-generates the concrete classes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1663.12062010125358_5F00_606DC3A4.png"&gt;&lt;img height="331" width="302" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/6406.12062010125358_5F00_thumb_5F00_51C317BF.png" alt="12-06-2010 12-53-58" border="0" title="12-06-2010 12-53-58" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;You won&amp;rsquo;t need the Model templates or classes, so you can remove these from the project (highlighted in red).&lt;/p&gt;
&lt;p&gt;Before going any further, the action of generating these POCO classes disables the default code generation of Entity Framework, which needs to be re-enabled. (Opening the generated .designer.cs file illustrates this by a comment.) This may be re-enabled by opening the Model, clicking on the design surface and using the Properties pane to set the Code Generation Strategy back to &amp;ldquo;Default&amp;rdquo;. Saving the model will regenerate the underlying classes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8562.12062010130525_5F00_4CE06403.png"&gt;&lt;img height="336" width="473" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7651.12062010130525_5F00_thumb_5F00_6C230AD6.png" alt="12-06-2010 13-05-25" border="0" title="12-06-2010 13-05-25" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Clearly, the mock templates/code are related to the mocking/testing of the solution so would be more appropriately placed within the PatternsAndPractises.TestableEntityFramework4.Tests project so can be moved to live within the Data folder within the test project.&lt;/p&gt;
&lt;p&gt;This will create a problem in that the T4 template needs to locate the source schema provided by the Entity Model, which is now unavailable. This can be corrected by opening the MockableModel.Context.tt file (or whatever you have called yours) and locating the line where the inputFile is set and changing it to the relative location of the .edmx file.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4201.12062010130006_5F00_6B4AA4EC.png"&gt;&lt;img height="214" width="641" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8877.12062010130006_5F00_thumb_5F00_2EB2A64F.png" alt="12-06-2010 13-00-06" border="0" title="12-06-2010 13-00-06" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;(If your editor doesn&amp;rsquo;t display with the helpful colouring, download the &lt;a href="http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html" title="Tangible T4 Editor (external link)"&gt;Tangible T4 Editor&lt;/a&gt; &amp;ndash; it makes it a lot easier)&lt;/p&gt;
&lt;p&gt;Saving the file will cause the MockableModel.Context.cs file to be re-generated with the concrete classes defining ObjectSet accessors for each class/table. These will be referencing the concrete generated classes defined in the data-layer &amp;ndash; a weakness in this model.&lt;/p&gt;
&lt;p&gt;A further change that needs to be made to the template is to weaken the ObjectSet references to the IObjectSet&amp;lt;T&amp;gt; type to allow abstraction. In order to add the IObjectSet&amp;lt;T&amp;gt; type, the System.Data.EntityClient namespace needs to be added. The changes are highlighted in the screenshot below, in green and indicated by arrows as the template colouring reduces identification.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8308.15062010224406_5F00_1C588DF2.png"&gt;&lt;img height="454" width="644" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1731.15062010224406_5F00_thumb_5F00_39120307.png" alt="Changes to MockableModel.Context.tt template screenshot" border="0" title="Changes to MockableModel.Context.tt template screenshot" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In the same way that we extended the functionality of the original Model context, we create a similar partial class for the MockableModel class (which actually refers to the local TestDatabaseEntities class). Notice that this is also implementing the IRepositoryObjectContext interface defined earlier. This is the testable/mockable object context. We have to create this within a separate folder, to prevent the generated file from being overwritten. I created a &amp;ldquo;Partial&amp;rdquo; folder within Data, making sure that &amp;ldquo;Partial&amp;rdquo; did not become part of the namespace &amp;ndash; which would prevent the partial compilation from working.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2656.12062010131657_5F00_0468B90A.png"&gt;&lt;img height="484" width="618" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1172.12062010131657_5F00_thumb_5F00_4281D3BB.png" alt="12-06-2010 13-16-57" border="0" title="12-06-2010 13-16-57" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;While this essentially completes our obligations in terms of implementing the IRepositoryObjectContext interface, it doesn&amp;rsquo;t yet work. The CustomersSet is created on demand by the generated code, as shown in the snippet below, from MockabelModel.Context.cs:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/5125.12062010131934_5F00_074DF7F0.png"&gt;&lt;img height="82" width="529" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2480.12062010131934_5F00_thumb_5F00_1F71624B.png" alt="12-06-2010 13-19-34" border="0" title="12-06-2010 13-19-34" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;However, the ObjectSet doesn&amp;rsquo;t actually retain any objects added to it, so we need to create an in-memory persistence layer that will essentially perform the same as the database persistence layer of the original Entity Framework. The article &lt;a href="http://msdn.microsoft.com/en-us/ff714955.aspx" title="Testability and Entity Framework 4 (external link)"&gt;Testability and Entity Framework 4&lt;/a&gt; defines the InMemoryObjectSet class:&lt;/p&gt;
&lt;pre&gt;using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System;
using System.Data.Objects;

public class InMemoryObjectSet : IObjectSet where T : class
{
	private readonly HashSet _set;
    private readonly IQueryable _queryableSet;

	public string Name { get; set; }

	#region ~ Constructors ~

	public InMemoryObjectSet()
		: this(Enumerable.Empty())
	{
	}

	public InMemoryObjectSet(IEnumerable entities)
	{
		_set = new HashSet();
		foreach (var entity in entities)
		{
			_set.Add(entity);
		}
		_queryableSet = _set.AsQueryable();
	}

	public InMemoryObjectSet(string name)
		: this()
	{
		Name = name;
	}

	public InMemoryObjectSet(string name, IEnumerable entities)
		: this(entities)
	{
		Name = name;
	}

	#endregion


	#region ~ from IObjectSet ~

	public void AddObject(T entity)
	{
		_set.Add(entity);
	}
	public void Attach(T entity)
	{
		_set.Add(entity);
	}
	public void DeleteObject(T entity)
	{
		_set.Remove(entity);
	}
	public void Detach(T entity)
	{
		_set.Remove(entity);
	}
	public Type ElementType
	{
		get { return _queryableSet.ElementType; }
	}
	public Expression Expression
	{
		get { return _queryableSet.Expression; }
	}
	public IQueryProvider Provider
	{
		get { return _queryableSet.Provider; }
	}
	public IEnumerator GetEnumerator()
	{
		return _set.GetEnumerator();
	}
	IEnumerator IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}

	#endregion

}&lt;/pre&gt;
&lt;p&gt;This class uses an instance of a HashSet&amp;lt;T&amp;gt; to persist data, which produces contextless and fast storage without dependency on state or implementation of a database.&lt;/p&gt;
&lt;p&gt;In order to implement the addition of items to the various sets, in this case Customers, I overrode the CreateObjectSet&amp;lt;T&amp;gt; method by using &amp;ldquo;new&amp;rdquo; within the TestDatabaseEntities class, which now looks like:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/0458.12062010132557_5F00_70ABA9A8.png"&gt;&lt;img height="484" width="619" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2235.12062010132557_5F00_thumb_5F00_1C7BFD98.png" alt="12-06-2010 13-25-57" border="0" title="12-06-2010 13-25-57" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This skips the original behaviour and instead creates an InMemoryObjectSet of T to ensure a container is actually created for storage of objects.&lt;/p&gt;
&lt;p&gt;As the actual Entity Framework code is called in the mocking of the Entity Framework API, there is a dependency on the connection string &amp;ndash; but only for configuration purposes, no connection is made. Therefore, we need to copy the App.config file from the business layer project &amp;ldquo;PatternsAndPractises.TestableEntityFramework4&amp;rdquo; to the Test project &amp;ldquo;PatternsAndPractises.TestableEnityFramework4.Tests&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The project now looks like:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8322.12062010133047_5F00_5867D9CD.png"&gt;&lt;img height="184" width="328" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/8168.12062010133047_5F00_thumb_5F00_3BEAE7ED.png" alt="12-06-2010 13-30-47" border="0" title="12-06-2010 13-30-47" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now would be a good point at which to confirm everything compiles.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re now ready to write our tests. As with the data layer, we need to be able to invoke the Repository class and inject our Entity Context, which implements IRepositoryObjectContext. I find creating a base class (&amp;ldquo;TestBase&amp;rdquo;) for tests works just as well as the Factory method used previously:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/7444.12062010133319_5F00_7B489B7D.png"&gt;&lt;img height="297" width="485" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/1220.12062010133319_5F00_thumb_5F00_75214EE2.png" alt="12-06-2010 13-33-19" border="0" title="12-06-2010 13-33-19" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The CreateRepository method creates the Repository, injecting the [local] instance of TestDatabaseEntities, or IRepositoryObjectContext.&lt;/p&gt;
&lt;p&gt;Finally, to write the tests, we&amp;rsquo;ll create a customer and save it, then check the persistence store to ensure it has been stored. Create a new Unit Test class and add the following tests:&lt;/p&gt;
&lt;pre&gt;		[TestMethod]
		public void CreateAndAddCustomer()
		{
			string expectedCustomerName = 
				string.Format(&amp;quot;New Customer ({0})&amp;quot;, Guid.NewGuid());
			using (Repository repository = CreateRepository())
			{
				ICustomer customer = repository.CreateCustomer();
				customer.CustomerName = expectedCustomerName;

				repository.AddCustomer(customer);
				repository.SaveChanges();

				ICustomer retainedCustomer = repository.
					Customers.
					Where(q =&amp;gt; q.CustomerName == expectedCustomerName).
					FirstOrDefault();
				Assert.IsNotNull(retainedCustomer);
			}	
		}&lt;/pre&gt;
&lt;p&gt;This test will create a customer (but not store it), add it to the persistence layer (in this case, an in-memory HashSet), save the changes and use the IQueryable&amp;lt;T&amp;gt; interface to verify the operation worked.&lt;/p&gt;
&lt;p&gt;The full Solution (exlcuding the Web UI) would look like:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/2311.12062010133927_5F00_65E90E69.png"&gt;&lt;img height="617" width="384" src="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x.metablogapi/4380.12062010133927_5F00_thumb_5F00_7CC7DFE5.png" alt="12-06-2010 13-39-27" border="0" title="12-06-2010 13-39-27" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Like I said, it&amp;rsquo;s not perfect, nor is it 100% isolated, but I think it strikes a healthy compromise between testability and the ability to concentrate on the job in hand, rather than worrying about minutia of patterns and practises. If you have any comments, do post them.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve added a sample project to download to provide a usable sample. &lt;a href="http://www.programx.co.uk/for_external/16062010/TestableMockableEntityFramework4.zip" title="Download the Visual Studio 2010 Solution as a ZIP file"&gt;Download the Visual Studio 2010 Solution as a ZIP file&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=483524" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Entity Framework" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Entity+Framework/default.aspx" /><category term="Testing" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Testing/default.aspx" /></entry><entry><title>Silverlight: Changing the synchronous mindset</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/11/25/silverlight-changing-the-synchronous-mindset.aspx" /><id>/blogs/program.x/archive/2009/11/25/silverlight-changing-the-synchronous-mindset.aspx</id><published>2009-11-25T17:09:00Z</published><updated>2009-11-25T17:09:00Z</updated><content type="html">&lt;p&gt;Working with web sites, web pages, web services and web clients has until recently been very much a synchronous operation, which is despite the very asynchronous nature of the web. Synchronous programming techniques are linear in operation in that process A cannot execute until process B has completed. The very nature of the internet is that not only do you not know when you&amp;#39;ll get a response from a server, you may not even get it at all, which can be particularly important when you don&amp;#39;t own the server as many mash-up web applications do not. If you adopt a synchronous model, such as basic JavaScript or relying solely on the brower&amp;#39;s threading model to load a page, you are likely to get freezes or missing portions of your web page. Asynchronous programming allows Process B to run alongside Process A. The two processes can run one after another, in any order, if at all. As a programmer, you need to work around the many headaches this can produce. Although, the experience for the end user is much improved as a result. Moving from a synchronous model to an asynchronous one can often be a challenge if you&amp;#39;ve never experienced this model previously.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m currently working in Silverlight, which forces users to use an asynchronous programming model, as per the &lt;a title="NPAPI at Wikipedia (external link)" href="http://en.wikipedia.org/wiki/NPAPI"&gt;NPAPI&lt;/a&gt; specification. This means that although a Silverlight component is very likely to need external data, it cannot rely on its timely execution or even a result. The traditional procedural programming pattern becomes redundant. If you have a complex and large data structure at your server, you certainly do not want to pull it all down to the client when you only need to use 5% of it. Likewise, you don&amp;#39;t want to have to rely on lots of &amp;quot;little calls&amp;quot; to get the 5% of data on an &amp;quot;as needed&amp;quot; approach as the user navigates through the application. &lt;/p&gt;  &lt;p&gt;The perfect example (which is a real example), is that of a Security Index. If you have a complex Security Index that identifies the permissions a user is has on actions and data, it would be tempting to have some code such as:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Permissions permissions=Security.GetPermissionsForUserOnItem(&lt;span class="kwrd"&gt;int&lt;/span&gt; itemID);&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In a desktop environment, you could certainly get away with having that call as a function, which can either dig into an in-memory data structure, consult a database or even a web service. You can be reasonably sure that you will get a timely result, particularly for an Intranet application. This is not entirely reliable, and is certainly not recommended for developing over the internet using a platform such as Silverlight or similar client/server applications. &lt;/p&gt;

&lt;p&gt;In a client/server environment, the GetPermissionsForUserOnItem() call would need to call back to a web service which may not respond as and when you expect. As Silverlight uses threading internally to generate calls to WCF web services, execution will fall out of the function almost immediately, without a result because the result will still be on its way back from the web server. Take the following code:&lt;/p&gt;

&lt;p&gt;(Based on the excellent article by David Betz at &lt;a title="Understanding WCF Services in Silverlight 2 (external link)" href="http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2"&gt;http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2&lt;/a&gt;)&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Permissions RequestPermissionsForItem(&lt;span class="kwrd"&gt;int&lt;/span&gt; itemId)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;     Permissions permissions=0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;     ISecurityBroker securityBroker = UIContext.CreateWcfInterface&amp;lt;ISecurityBroker&amp;gt;(&lt;span class="str"&gt;&amp;quot;Security/SecurityBroker.svc&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;     &lt;span class="rem"&gt;// Point A: call to the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;     securityBroker.BeginGetPermittedActionsForDataItemAndUser(clientId, dataTypeId, dataItemId, result =&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;          {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;               &lt;span class="rem"&gt;// Point B: This will only execute on response from the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;               permissions = ((ISecurityBroker)result.AsyncState).EndGetPermittedActionsForDataItemAndUser(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;           }, securityBroker);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;      }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;      &lt;span class="rem"&gt;// Point C: Execution will immediately follow Point A, skipping Point B&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; permissions;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This uses the following method, which in the example above in in the UIContext static class, which creates the web service (and represents my own code usage, you may have a more suitable mechanism):&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UIContext&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; TWcfApiEndPoint CreateWcfInterface&amp;lt;TWcfApiEndPoint&amp;gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; serviceUrl)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;          &lt;span class="rem"&gt;// create the binding elements&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;          BinaryMessageEncodingBindingElement binaryMessageEncoding = &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryMessageEncodingBindingElement();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;          HttpTransportBindingElement httpTransport = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpTransportBindingElement() { MaxBufferSize = &lt;span class="kwrd"&gt;int&lt;/span&gt;.MaxValue, MaxReceivedMessageSize = &lt;span class="kwrd"&gt;int&lt;/span&gt;.MaxValue };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;          &lt;span class="rem"&gt;// add the binding elements into a Custom Binding&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;          CustomBinding customBinding = &lt;span class="kwrd"&gt;new&lt;/span&gt; CustomBinding(binaryMessageEncoding, httpTransport);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;          &lt;span class="rem"&gt;// create the Endpoint URL &lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;          EndpointAddress endpointAddress = &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(serviceUrl);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;          &lt;span class="rem"&gt;// create an interface for the WCF service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;          ChannelFactory&amp;lt;TWcfApiEndPoint&amp;gt; channelFactory=&lt;span class="kwrd"&gt;new&lt;/span&gt; ChannelFactory&amp;lt;TWcfApiEndPoint&amp;gt;(customBinding, endpointAddress);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;          &lt;span class="rem"&gt;// channelFactory.Faulted += new EventHandler(channelFactory_Faulted); - not implemented in this example&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;          TWcfApiEndPoint client = channelFactory.CreateChannel();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;          &lt;span class="kwrd"&gt;return&lt;/span&gt; client;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;     }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;} &lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The comments illustrate that the web service call will be executed within its own thread (within the anonymous function), so Point B would not necessarily execute before point C. The result of permissions, therefore, will be 0. This rules out calls to functions as we&amp;#39;ve come to expect them to work.&lt;/p&gt;

&lt;p&gt;There are ways to simulate synchronous behaviour, but as mentioned in &lt;a title="OMG, Silverlight! Asynchronous is Evil! (or, Call me back when you got it) (external link)" href="http://petesbloggerama.blogspot.com/2008/07/omg-silverlight-asynchronous-is-evil.html"&gt;Peter Bomberg&amp;#39;s post from 2008&lt;/a&gt;, they are not at all a solution to an asynchronous problem. Classes such as ManualResetEvent and AutoResetEvent provide locking to prevent execution from a given point until a flag as been set on the object. The above code would become as follows:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Permissions RequestPermissionsForItem(&lt;span class="kwrd"&gt;int&lt;/span&gt; itemId)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;     Permissions permissions=0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;     ISecurityBroker securityBroker = UIContext.CreateWcfInterface&amp;lt;ISecurityBroker&amp;gt;(&lt;span class="str"&gt;&amp;quot;Security/SecurityBroker.svc&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;     &lt;span class="rem"&gt;// Point A: call to the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;     &lt;span class="kwrd"&gt;using&lt;/span&gt; (AutoResetEvent autoResetEvent=&lt;span class="kwrd"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span class="kwrd"&gt;false&lt;/span&gt;))&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;          securityBroker.BeginGetPermittedActionsForDataItemAndUser(clientId, dataTypeId, dataItemId, result =&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;          {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;               &lt;span class="rem"&gt;// Point B: This will only execute on response from the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;               permissions = ((ISecurityBroker)result.AsyncState).EndGetPermittedActionsForDataItemAndUser(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;               &lt;span class="rem"&gt;// Point C: Sets a flag to signal that the result is ready&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;               autoResetEvent.Set();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;          }, securityBroker);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;          &lt;span class="rem"&gt;// Point D: Execution waits until the Set() method executes, signalling the result is ready&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;          autoResetEvent.WaitOne();&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; permissions;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;


&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;This works - sort of. However, mixing this with user-interface based code, which runs inside its own thread, can soon result in threading deadlocks which will cause your application to stop ... dead. These are always difficult to resolve and fix in an elegant way. I often think, if it can&amp;#39;t be fixed elegantly, you&amp;#39;re probably doing it wrong.&lt;/div&gt;

&lt;p&gt;So the problem remains; how can we request small bits of information from a potentially huge data source held behind a web service from a Silverlight (or similar) application? The challenge in this is not how to simulate a synchronous pattern, but how to match an appropriate callback pattern to your code.&lt;/p&gt;

&lt;p&gt;Back to the example, we can provide an event, that is called when the result is ready. This will mean that the function will return void, and it causes added headaches at the consumer side of the function because the caller will need to wire-up an event handler, which synchronous patterns avoid. So we can change the code to:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PermissionsBroker&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{ &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;event&lt;/span&gt; EventHandler&amp;lt;RequestPermissionsForItemEventArgs&amp;gt; PermissionsForItemReady;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;     &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPermissionsForItemReady(RequestPermissionsForItemEventArgs e)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;          &lt;span class="kwrd"&gt;if&lt;/span&gt; (PermissionsForItemReady != &lt;span class="kwrd"&gt;null&lt;/span&gt;) PermissionsForItemReady(&lt;span class="kwrd"&gt;this&lt;/span&gt;, e);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;     }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RequestPermissionsForItem(&lt;span class="kwrd"&gt;int&lt;/span&gt; itemId)&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;          Permissions permissions=0;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;          ISecurityBroker securityBroker = UIContext.CreateWcfInterface&amp;lt;ISecurityBroker&amp;gt;(&lt;span class="str"&gt;&amp;quot;Security/SecurityBroker.svc&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;          &lt;span class="rem"&gt;// Point A: call to the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;          securityBroker.BeginGetPermittedActionsForDataItemAndUser(clientId, dataTypeId, dataItemId, result =&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;          {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;               &lt;span class="rem"&gt;// Point B: This will only execute on response from the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;              permissions = ((ISecurityBroker)result.AsyncState).EndGetPermittedActionsForDataItemAndUser(result);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;              OnPermissionsForItemReady(&lt;span class="kwrd"&gt;new&lt;/span&gt; RequestPermissionsForItemEventArgs() { ItemID = itemId, Permissions = permissions });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;          }, securityBroker);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here, I have created a class, RequestPermissionsForItemEventArgs (not shown, but the properties are simple enough) that represents a means of passing a message back to the caller, with the permissions, when ready.&lt;/p&gt;

&lt;p&gt;So the caller could:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;PermissionsBroker permissionsBroker=&lt;span class="kwrd"&gt;new&lt;/span&gt; PermissionsBroker();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;permissionsBroker.PermissionsForItemReady+=&lt;span class="kwrd"&gt;new&lt;/span&gt; EventHandler&amp;lt;RequestPermissionsForItemEventArgs&amp;gt;(SecurityCache_PermissionsForItemReady);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;permissionsBroker.RequestPermissionsForItem(500);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; SecurityCache_PermissionsForItemReady(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RequestPermissionsForItemEventArgs e)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;     &lt;span class="rem"&gt;// results, act on permission here&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That is a lot of lines just to check permissions. While this works, we need to reduce the headache for the consumer of the functionality by reducing the amount of plumbing they need to create just to get a simple value back from the server. By using an anonymous function, we can simplify this.&lt;/p&gt;

&lt;p&gt;First, we use a delegate to allow us to pass a function as a parameter to the function. This will represent the callback operation:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RequestPermissionsForItemDelegate(SecureDataActions secureDataActions);&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;We add this to our function:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RequestPermissionsForItem(&lt;span class="kwrd"&gt;int&lt;/span&gt; itemId, RequestPermissionsForItemDelegate requestPermissionsForItemDelegate)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;          Permissions permissions=0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;          ISecurityBroker securityBroker = UIContext.CreateWcfInterface&amp;lt;ISecurityBroker&amp;gt;(&lt;span class="str"&gt;&amp;quot;Security/SecurityBroker.svc&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;          &lt;span class="rem"&gt;// Point A: call to the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;          securityBroker.BeginGetPermittedActionsForDataItemAndUser(clientId, dataTypeId, dataItemId, result =&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;          {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;               &lt;span class="rem"&gt;// Point B: This will only execute on response from the web service&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;              permissions = ((ISecurityBroker)result.AsyncState).EndGetPermittedActionsForDataItemAndUser(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;              requestPermissionsForItemDelegate(permissions);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;          }, securityBroker);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And using an anonymous function (using a lambda), we can call it and get the result in just 5 lines of code:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;RequestPermissionsForItem(itemID, permissions =&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;     {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;             &lt;span class="kwrd"&gt;bool&lt;/span&gt; canWrite = permissions!=0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;     }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The important point to remember is that the code executing within the anonymous function is a in its own scope, and therefore cannot pass its result out of the anonymous function other than by setting a higher-scoped variable (but again you need to consider asynchronous behaviour) and that it will not be executing on the UI thread so will need to be invoked from the dispatcher accordingly.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=482503" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="WCF" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/WCF/default.aspx" /><category term="Silverlight" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Silverlight/default.aspx" /></entry><entry><title>The not-so-obvious benefits of Localising your Strings</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/08/03/the-not-so-obvious-benefits-of-localising-your-strings.aspx" /><id>/blogs/program.x/archive/2009/08/03/the-not-so-obvious-benefits-of-localising-your-strings.aspx</id><published>2009-08-03T10:27:00Z</published><updated>2009-08-03T10:27:00Z</updated><content type="html">&lt;p&gt;In developing the next major version of our major product line, I made sure we re-visited every aspect of the application. In a sense, the existing team had to make a valid argument for every feature to be included in the product. One aspect that was not previously considered was internationalisation. Being able to localise your strings to &amp;quot;foreign&amp;quot; languages and format your numbers to an international audience is a key benefit and opens our product up to a massive user-base in the future. Aside from the obvious features that .NET localisation offers, such as multi-lingual and culture-specific formatting, working through your product and using localisation features offers many other benefits which are useful even if you want to stick to &amp;quot;International English&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reduce language clutter&lt;/strong&gt; - by focussing on identifying the labels to apply to controls, you minimise your language clutter. When talking about writing files to disk, a Save Filename label could appear as &amp;quot;Save File as:&amp;quot;, &amp;quot;Save Filename:&amp;quot;, Save as:&amp;quot; or even &amp;quot;Save FileName&amp;quot;. This provides an extra level of discipline to ensure terms of reference are consistent, particularly across a team of developers.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/3175.localisedStrings.png"&gt;&lt;img border="0" src="http://bloggingabout.net/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/3175.localisedStrings.png" style="border:0;" alt="Resource strings screenshot" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DRY (Don&amp;#39;t Repeat Yourself) Principle&lt;/strong&gt; - If a section of code ends up being &amp;quot;duplicated&amp;quot;, we extract it into a searate function according to the DRY principle, but this can also apply to text. By re-using your term definitions you make updating your terms simpler. An example is when working around a particular product feature which ma be codenamed while in development, but will be rebranded when Marketing decide how to push the feature to the user-audience. Re-branding across the site in this way becomes much easier than a Search/Replace. This is also very useful for spelling mistakes!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reduce security threats&lt;/strong&gt; - Using the asp:Localize control&amp;nbsp;in ASP.NET&amp;nbsp;to display the localised text can provide an additional layer of security protection by using the Mode=&amp;quot;Encode&amp;quot; attribute, which reduces the risk of script injection and therefore, cross-site scripting attacks for a site. Even if not referencing a localised term, the asp:Localise control is a must for displaying content from the user or the database. Make it discipline and you can delegate your protection of script injection - to a point.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/3326.localizeControl.png"&gt;&lt;img border="0" src="http://bloggingabout.net/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/3326.localizeControl.png" style="border:0;" alt="Localise control screenshot" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Lower the technical barrier&lt;/b&gt; - by franchising out your strings to what is essentially a text file, you can have your Marketing team or translators modify the file. This is known, but it also allows you to modify the file seperately from the code itself, while potentially keeping the file within source control.&lt;/p&gt;
&lt;p&gt;These are all pretty obvious when you think about it, so much so that I&amp;#39;ll probably work towards localising all my applications in the future. For the sake of a slight change in how you do things, it&amp;#39;s worth the effort in consistency, maintainability and safety.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=481996" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Localisation" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Localisation/default.aspx" /></entry><entry><title>WCF -&gt; JSON Serialization woes and a solution</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/03/18/wcf-json-serialization-woes.aspx" /><id>/blogs/program.x/archive/2009/03/18/wcf-json-serialization-woes.aspx</id><published>2009-03-18T10:13:00Z</published><updated>2009-03-18T10:13:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;m working on improving the performance of my current web application project at various points. As I had already planned for a WCF interface for third-party use, I thought I&amp;#39;d utilise that, exposing objects as JSON-serialized strings usable by jQuery/ASP.NET AJAX.&lt;/p&gt;
&lt;p&gt;Little did I realise that when I was coming up with my Data Framework (I chose Entity Framework) I should have thought about aspects at the other side of my project such as the User Interface as well as the more obvious aspects of scalability, performance in relation to a pragmatist view of what is needed in the &amp;quot;real world&amp;quot; (therefore, nHibernate is out).&lt;/p&gt;
&lt;p&gt;My WCF service had an exposed service that would return a Client object (actually, an interface IClient) and return it as JSON. Simple.&lt;/p&gt;
&lt;p&gt;No, I hit a number of issues with this.&lt;/p&gt;
&lt;p&gt;1/ Investigations at &lt;a href="http://stackoverflow.com/questions/655400/jquery-wcf-without-asp-net-ajax" title="StackOverflow question (external link)"&gt;StackOverflow&lt;/a&gt; indicated that Interfaces cannot be exposed through serialization. Makes sense, really, but dents my idealistic view of presenting interfaces and no conncrete objects to third-parties via my API. So I was going to have to either return my concrete object or reduce my return value to a JSON string, thereby bringing serialization &amp;quot;in house&amp;quot; and not relying on WCF to serialize it for me.&lt;/p&gt;
&lt;p&gt;From:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[OperationContract]&lt;br /&gt;[WebInvoke(Method=&amp;quot;POST&amp;quot;,BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]&lt;br /&gt;IClient GetClientJson(int clientId);&lt;/p&gt;
&lt;div&gt;I went to:&lt;/div&gt;
&lt;div&gt;
&lt;p style="padding-left:30px;"&gt;[OperationContract]&lt;br /&gt;[WebInvoke(Method=&amp;quot;POST&amp;quot;,BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]&lt;br /&gt;string GetClientJson(int clientId);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;2/ This actually dodged the issue of the attribute configuration on the service itself, which was becoming a nightmare. Tweak it at the server and it breaks at the client, and vice versa. What was:&lt;/p&gt;
&lt;p&gt;From:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[OperationContract]&lt;br /&gt;[WebInvoke(Method=&amp;quot;POST&amp;quot;,BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]&lt;br /&gt;string GetClientJson(int clientId);&lt;/p&gt;
&lt;div&gt;I went to:&lt;/div&gt;
&lt;div&gt;
&lt;p style="padding-left:30px;"&gt;[OperationContract]&lt;br /&gt;[WebInvoke(Method=&amp;quot;POST&amp;quot;,BodyStyle=WebMessageBodyStyle.Bare,ResponseFormat=WebMessageFormat.Json)]&lt;br /&gt;string GetClientJson(int clientId);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;3/ Next was serializing the object into JSON. I was getting the &amp;quot;The type &amp;#39;xxx&amp;#39; cannot be serialized to JSON because its IsReference setting is &amp;#39;True&amp;#39;. The JSON format does not support references because there is no standardized format for representing references. To enable serialization, disable the IsReference setting on the type or an appropriate parent class of the type.&amp;quot; exception. As I was essentially getting this at the client, it suggested my WCF endpoint configuration was wrong. Looking deeper, it turns out that Entity Framework objects are marked with IsReference=True, meaning the native&amp;nbsp;DataContractJsonSerializer of WCF cannot serialize Entity Framework objects. I proved this by doing a manual serialization:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;string jsonClient;&lt;br /&gt;IClient client = GetClient(7);&lt;br /&gt;DataContractJsonSerializer ser = new DataContractJsonSerializer(client.GetType());&lt;br /&gt;using (MemoryStream ms = new MemoryStream())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ser.WriteObject(ms, client);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;jsonClient = Encoding.Default.GetString(ms.ToArray());&lt;br /&gt;}&lt;br /&gt;return jsonClient;&lt;/p&gt;
&lt;p&gt;4/ I needed to serialize using a different serializer, so thought I&amp;#39;d use the &lt;a href="http://magmainteractive.net/tutorials/post/ASPNET-AJAX-JSON-Serialization-Process.aspx" title="ASP.NET AJAX JSON Serialization Process (external link)"&gt;ASP.NET AJAX Serializer&lt;/a&gt;, which also didn&amp;#39;t work, this time falling over the exception &amp;quot;A circular reference was detected while serializing an object of type xxx&amp;#39;.&amp;quot; The type it was complaining about wasn&amp;#39;t in the object so it was clearly navigating deeper into other objects to find that particular Type anyway.&lt;/p&gt;
&lt;p&gt;5/ So now I am left with no other option but to either do it myself or use a third-party library. I&amp;#39;m using &lt;a title="JSon.NET (external link)" href="http://james.newtonking.com/projects/json-net.aspx"&gt;Json.NET&lt;/a&gt;, which I spotted on &lt;a href="http://www.hanselman.com/blog/SerializingObjectsAsJavaScriptUsingAtlasJSONNETAndAjaxPro.aspx" title="Scott Hanselman&amp;#39;s Blog"&gt;Scott Hanselman&amp;#39;s&lt;/a&gt; blog and seems to be robust enough and simple enough for most purposes. So my code now looks like:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;			&lt;/span&gt;string jsonClient=null;&lt;br /&gt;IClient client=GetClient(1);&lt;br /&gt;JsonSerializer jsonSerializer = new JsonSerializer();&lt;br /&gt;jsonSerializer.Converters.Add(new JavaScriptDateTimeConverter());&lt;br /&gt;jsonSerializer.NullValueHandling = NullValueHandling.Ignore;&lt;br /&gt;jsonSerializer.MissingMemberHandling = MissingMemberHandling.Error;&lt;br /&gt;jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Error;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; using (StringWriter sw = new StringWriter())&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;using (JsonTextWriter jtw = new JsonTextWriter(sw))&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jsonSerializer.Serialize(jtw, client);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;catch (Exception ex)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; ex = ex; // have a breakpoint here so can inspect exception&lt;br /&gt;}&lt;br /&gt;return jsonClient;&lt;/p&gt;
&lt;p&gt;Notice I have set ReferenceLoopHandling to ReferenceLoopHandler.Error. This is to try and catch the same Reference Count issue that ASP.NET AJAX JSON Serialization catches. (Actually this was added after realising I had StackOverflows occurring). Sure enough, I have another Reference Count issue as the Exception does get caught and the error is related to possible infinite recursion.&lt;/p&gt;
&lt;p&gt;The JSON.NET Framework allows me to disable serializing potentially problematic objects, but this would require applying these changes to elements of code &amp;quot;Bhind the wall&amp;quot; of my API - and essentially add Web-specific functionality into a domain that is supposed to be platform agnostic. This is not an option for me.&lt;/p&gt;
&lt;p&gt;So I appear to be stuck. Other than rendering the JSON myself through a StringBuilder, I&amp;#39;m pretty much stuck on this now. Maybe something will hit me in a flash of inspiration. Until then, it&amp;#39;s good ol&amp;#39; StringBuilder for me.&lt;/p&gt;
&lt;h3&gt;Update: The Solution:&lt;/h3&gt;
&lt;p&gt;Thanks again due to &lt;a title="StackOverflow question (external link)" href="http://stackoverflow.com/questions/657939/serialize-entity-framework-objects-into-json"&gt;StackOverflow&lt;/a&gt;, (&lt;a title="John Saunders (external link)" href="https://mvp.support.microsoft.com/profile/John.Saunders"&gt;John Saunders&lt;/a&gt; and &lt;a title="Craig Stuntz&amp;#39; Blog (external link)" href="http://blogs.teamb.com/craigstuntz/"&gt;Craig Stuntz&lt;/a&gt;) I&amp;#39;ve figured out how I&amp;#39;m going to do it. It&amp;#39;s not as pretty as I would have liked, but pragmatism wins out again.&lt;/p&gt;
&lt;p&gt;Here it is from start to finish. My UI generates an event that is picked up by some JavaScript. This runs:&lt;/p&gt;
&lt;p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;						&lt;/span&gt;var wcfProxy = new serviceProxy(&amp;quot;../api/wcf/ClientBroker.svc/&amp;quot;);&lt;br /&gt;wcfProxy.invoke(&amp;quot;GetClientJson&amp;quot;, { clientId: 7 }, updateClient, updateClientError);&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;serviceProxy is &lt;a title="Rick Strahl&amp;#39;s Blog Post about wrapping WCF (external link)" href="http://www.west-wind.com/weblog/posts/324917.aspx"&gt;RickStrahl&amp;#39;s WCF wrapper&lt;/a&gt;, which has two callbacks, success and error (the last two parameters, respectively). The Invoke method invokes the WCF service and obtains the result. The WCF service is exposed via the Interface:&lt;/p&gt;
&lt;p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;	&lt;/span&gt;[ServiceContract(Namespace = &amp;quot;xxxWCF&amp;quot;)]&lt;br /&gt;public interface IClientBroker&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; [OperationContract]&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; [WebInvoke(Method=&amp;quot;POST&amp;quot;,BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; string GetClientJson(int clientId);&lt;br /&gt;}&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Note that the Body STyle is Wrapped. I couldn&amp;#39;t get it working in Bare mode at all. (Despite telling me it had logged messages in the Windows Event Log, no events were to be found).&lt;/p&gt;
&lt;p&gt;
&lt;p style="padding-left:30px;"&gt;[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;public class ClientBroker : IClientBroker&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public string GetClientJson(int clientId)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;string jsonClient=null;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IClient client = GetClient(clientId);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var j = new { ID=client.ID, BusinessName=client.BusinessName };&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;JavaScriptSerializer s = new JavaScriptSerializer();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jsonClient=s.Serialize(j);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return jsonClient;&lt;br /&gt;}&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notice I am using Anonymous Types to create a new type which is free of Entity Framework idiosyncracies.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;This generates a wrapped JSON string:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&amp;quot;GetClientJsonResult&amp;quot;:&amp;quot;{\&amp;quot;ID\&amp;quot;:7,\&amp;quot;BusinessName\&amp;quot;:\&amp;quot;XYZ Ltd\&amp;quot;}&amp;quot;}&lt;/p&gt;
&lt;p&gt;When returned to the client, the success callback is called:&lt;/p&gt;
&lt;p&gt;
&lt;p style="padding-left:30px;"&gt;function updateClient(o) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; eval(&amp;#39;var z=&amp;#39; + o&amp;#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; alert(&amp;#39;BusinessName=&amp;#39; + o.BusinessName);&lt;br /&gt;}&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;And the Business Name of the requested client is displayed.&lt;/p&gt;
&lt;p&gt;It just goes to show that Microsoft may put all the features they like into C#, and you might very well know they are there. But you&amp;#39;re not going to use them until you need to use them, and then you need to know that you need to use them! Variant types are, to me, an uncomfortable throwback of those bad VB days but sometimes they can prove useful when it comes to the crunch, I&amp;#39;m just keen on restricting my use of them to the absolute minimum so the very premise of a type-strong language is not lost.&lt;/p&gt;
&lt;p&gt;Another stone passed.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=481375" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="WCF" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/WCF/default.aspx" /><category term="JSON" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/JSON/default.aspx" /><category term="ASP.NET AJAX" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/ASP.NET+AJAX/default.aspx" /></entry><entry><title>WCF Exception: "There can be at most one address per scheme in this collection"</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/03/16/wcf-exception-quot-there-can-be-at-most-one-address-per-scheme-in-this-collection-quot.aspx" /><id>/blogs/program.x/archive/2009/03/16/wcf-exception-quot-there-can-be-at-most-one-address-per-scheme-in-this-collection-quot.aspx</id><published>2009-03-16T11:39:00Z</published><updated>2009-03-16T11:39:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;m beginning to see why people dislike WCF.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m working on using WCF to feed an AJAX TreeView, and demos of it are FAST. However, in my debugging on my dev server I bumped into the exception:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;There can be at most one address per scheme in this collection&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The posters at&amp;nbsp;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/9e248455-1c4d-4c5c-851c-79d9c1631e21/#page:1"&gt;http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/9e248455-1c4d-4c5c-851c-79d9c1631e21/#page:1&lt;/a&gt;&amp;nbsp;seem to be most vocal about the definiciencies of WCF in this respect - and they&amp;#39;d be right. What were Microsoft thinking? Most web applications need to respond to at least two domains to overcome the vagaries of user-inputted URLs, eg:&lt;/p&gt;
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;www.myapp.mysite.com&lt;/li&gt;
&lt;li&gt;mapp.mysite.com&lt;/li&gt;
&lt;li&gt;myapp&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;Are all potentially valid patterns for accessing an internal web application. We shouldn&amp;#39;t need workarounds to get this to work.&lt;/p&gt;
&lt;p&gt;Removing the extra host header record fixes the issue. Surely they weren&amp;#39;t expecting people to write their WCF services under a separate, discrete URL, like wcf.myapp.mysite.com?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=481359" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="WCF" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/WCF/default.aspx" /></entry><entry><title>Telerik: radControls: Resizable Splitter</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/02/24/telerik-radcontrols-resizable-splitter.aspx" /><id>/blogs/program.x/archive/2009/02/24/telerik-radcontrols-resizable-splitter.aspx</id><published>2009-02-24T13:11:00Z</published><updated>2009-02-24T13:11:00Z</updated><content type="html">&lt;p&gt;For my current &amp;nbsp;project, I am working on what is quite a complex user interface. I need to develop an interface that has splitter controls and can load one or more modules within each panel. Sort of like Microsoft Outlook three-panel interface. Sort of like the example below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/blog.jpg"&gt;&lt;img border="0" src="http://bloggingabout.net/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/blog.jpg" style="border:0;vertical-align:middle;" alt="Splitter Screenshot" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The screenshot shows how 3 &amp;quot;modules&amp;quot; have been loaded, one in each Pane.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am using Telerik&amp;#39;s &lt;a title="RadSplitter at Telerik (external link)" href="http://www.telerik.com/products/aspnet-ajax/splitter.aspx"&gt;RadSplitter&lt;/a&gt; control, which is part of their &lt;a title="http://www.telerik.com/products/aspnet-ajax.aspx" href="http://bloggingabout.net/controlpanel/blogs/posteditor.aspx/Telerik%20RadControls%20for%20ASP.NET%20AJAX"&gt;RadControls for ASP.NET AJAX&lt;/a&gt; and provide a great suite of components you can just drop into your project for rapidly prototyping and developing applications for the web.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Splitter control itself is able to resize itself intelligently, so expanding the left column will automatically resize the content in the two right-hand panes. But there are two things it does not do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It does not (by default) operate within a &amp;quot;100% browser&amp;quot; environment - you need to encourage it to do so&lt;/li&gt;
&lt;li&gt;While resizing content within adjacent panes to a resized pane is pretty good, some intelligence may need to be applied when resizing richer controls such as Grids, where the data itself may be effected.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To solve the first problem, you just need to make sure your RadSplitter is set to use the full browser dimensions as such:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;	&lt;/span&gt;&amp;lt;telerik:RadSplitter ID=&amp;quot;MainSplitter&amp;quot; runat=&amp;quot;server&amp;quot; Height=&amp;quot;100%&amp;quot; Width=&amp;quot;100%&amp;quot; HeightOffset=&amp;quot;35&amp;quot;&amp;nbsp;Orientation=&amp;quot;Horizontal&amp;quot; Skin=&amp;quot;Outlook&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;!-- definition --&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;/telerik:RadSplitter&amp;gt;&lt;/p&gt;
&lt;p&gt;According to the established W3C guidelines, 100% is only 100% of a physically defined height of the calculated height of all containers of the item. The Splitter works exactly the same, so unless you are able to pixel-perfect resize your Splitter, you need to apply some hackery to get your Spliter to behave. Telerik &lt;a href="http://demos.telerik.com/aspnet-ajax/splitter/examples/resizewithwindow/defaultcs.aspx" title="How to set 100% Browser size of Splitter (external link)"&gt;show how to achieve&lt;/a&gt; this so I won&amp;#39;t repeat them, but if you are having problems, make sure that EVERY container is able to resolve to a pixel-defined height. I have found that across browsers, it isn&amp;#39;t always consistent. Therefore, I have the following jQuery to try and force the issue:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;		&lt;/span&gt;function stretchSplitter() {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; var newWindowHeight = $(window).height() - 110;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$(&amp;quot;#formPage&amp;quot;).css(&amp;quot;height&amp;quot;, newWindowHeight);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$(&amp;quot;#&amp;lt;%=radSplitter.ClientID %&amp;gt;&amp;quot;).css(&amp;quot;height&amp;quot;, newWindowHeight);&amp;nbsp;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$(document).ready(function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;$(window).bind(&amp;quot;resize&amp;quot;, resizeWindow);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;function resizeWindow(e) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;stretchSplitter();&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;br /&gt;stretchSplitter();&lt;/p&gt;
&lt;p&gt;This is using the standard jQuery onLoad trick to resize the splitter once the DOM is ready. I&amp;#39;m taking the 110 pixels off to adjust to the current offsets I need to take account of. This could be used to tweak designs across browsers.&lt;/p&gt;
&lt;p&gt;The next problem is how to have the contents of each pane resize according to the pane&amp;#39;s new size once resized. Mostly, this isn&amp;#39;t an issue. Designing your content around a liquid layout should allow content to resize using standard CSS flowing. If displaying data, or particularly complex designs within one of the pane areas, however, it becomes necassary to finely control positioning.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the screenshot above, I have a radGrid, which requires resizing to allow its &lt;a href="http://demos.telerik.com/aspnet-ajax/grid/examples/client/virtualscrollpaging/defaultcs.aspx" title="Virtual Scrolling at Telerik (external link)"&gt;VirtualScrolling&lt;/a&gt; to operate correctly. I&amp;#39;m actually trying to create a similar effect illustrated at the older &lt;a href="http://demos.telerik.com/aspnet/controls/examples/integration/gridandsplitterresizing/defaultvb.aspx?product=grid" title="Telerik radGrid sizing demo (external link)"&gt;radGrid demo&lt;/a&gt;. So resizing the pane will cause the grid to require resizing, which itself needs to go back to the server to rebind its rows. What I needed to do, however, was separate the functionality so that the usercontrol loaded into the pane doesn&amp;#39;t know of its position in the Splitter. It may be loaded once (or more) in any Pane/location in the Splitter. So I couldn&amp;#39;t &amp;quot;bind&amp;quot; myself to any events exposed by the host Splitter.&lt;/p&gt;
&lt;p&gt;Thanks to jQuery (and my understanding of it as opposed to pure JavaScript), this was possible, if a little hacky.&lt;/p&gt;
&lt;p&gt;I decided to use an &amp;lt;A&amp;gt; tag to act as an event proxy. This &amp;lt;A&amp;gt; tag would recieve a standard &amp;quot;onclick&amp;quot; event, and repeat it to any subscribers. I created a single &amp;lt;A&amp;gt; tag:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;a id=&amp;quot;eventProxy&amp;quot; class=&amp;quot;eventProxy&amp;quot; href=&amp;quot;#&amp;quot; title=&amp;quot;Event Proxy&amp;quot; style=&amp;quot;display: none&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;Then, I attached an event to the RadSplitters OnClientResized event:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function radSplitter_OnClientResized(sender, args) &amp;nbsp;{&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; var v=$(&amp;#39;a#eventProxy&amp;#39;).trigger(&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;em&gt;type&lt;/em&gt;:&amp;#39;click&amp;#39;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;subType:&amp;#39;splitterPaneResize&amp;#39;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;resizedPanelID:sender.get_id(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;oldWidth:args.get_oldWidth(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;oldHeight:args.get_oldHeight(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;newWidth:sender.get_width(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;newHeight:sender.get_height() &amp;nbsp;}&amp;nbsp;);&lt;/p&gt;
&lt;p&gt;&lt;span&gt;		&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When the RadSplitter pane is resized, this event is called, which creates an &amp;#39;event&amp;#39; object and &lt;a title="Triggering events at jQuery (external link)" href="http://docs.jquery.com/Events/trigger"&gt;Triggers&lt;/a&gt; the event with &lt;em&gt;type &lt;/em&gt;on the element found by the jQuery &amp;#39;a#eventProxy&amp;#39;. As type is &amp;#39;click&amp;#39;, it will essentially call any handlers attached to the onclick event of the &amp;lt;A&amp;gt; tag.&lt;/p&gt;
&lt;p&gt;Any handlers attaching to the onclick event would be dynamically built, so I couldn&amp;#39;t just add them to the onclick=&amp;quot;&amp;quot; attribute of the &amp;lt;A&amp;gt; tag. Again, I used jQuery to achieve this. In every Module that was interested or concerned with having to resize itself according to the new size of the content, I added the following jQuery:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$(document).ready(function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;$(&amp;#39;a#eventProxy&amp;#39;).click(&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;function(event) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;switch (event.subType)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case &amp;#39;windowClosed&amp;#39;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var ajaxMgr=$find(&amp;quot;&amp;lt;%=AjaxManager.ClientID %&amp;gt;&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (ajaxMgr) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ajaxMgr.ajaxRequest(&amp;quot;RebindUsersGrid&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case &amp;#39;splitterPaneResize&amp;#39;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (event.resizedPanelID==&amp;#39;&amp;lt;%=ParentRadPane.ClientID %&amp;gt;&amp;#39;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sizeUsersModule(event.newHeight);&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;br /&gt;});&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Again, I&amp;#39;m using the jQuery onLoad technique to ensuring my DOM is ready. Note that I have a switch, which shows that I can re-use the same &amp;lt;A&amp;gt; tag for multiple types of event. I have two cases here, one for closing windows and one for performing the resizing of the Users Module - determined by splitterPaneResize. Note that I am checking to ensure the pane I am going to resize is the one I am interested in - otherwise, your panes will interact with each other. The sizeUsersModule is shown below:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;		&lt;/span&gt;function sizeUsersModule(newHeight) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; var ajxMgr=&amp;lt;%=AjaxManager.ClientID %&amp;gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; if (ajxMgr!=null &amp;amp;&amp;amp; ajxMgr.ajaxRequest!=null)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ajxMgr.ajaxRequest(&amp;#39;resizegrid_Height=&amp;#39;+newHeight);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;div&gt;This simply takes the new height and calls the ajaxRequest client-side method of the RadAjaxManager. This causes a callback to the server, which runs the server-side C#:&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Hook up my event in Page_Load():&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;AjaxManager.AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(AjaxManager_AjaxRequest);&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;... and the event:&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style="padding-left:30px;"&gt;private void AjaxManager_AjaxRequest(object sender, AjaxRequestEventArgs e)&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;		&lt;/span&gt;{&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (e.Argument.StartsWith(&amp;quot;resizegrid_Height=&amp;quot;))&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; string newHeightAsString=e.Argument.Substring(&amp;quot;resizegrid_Height=&amp;quot;.Length);&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (newHeightAsString.EndsWith(&amp;quot;px&amp;quot;)) newHeightAsString = newHeightAsString.Substring(0, newHeightAsString.Length - &amp;quot;px&amp;quot;.Length);&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int newHeight=int.Parse(newHeightAsString);&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;radGridUsers.Height = newHeight- 65;&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;}&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;In this code, I am parsing out the value (removing the &amp;#39;px&amp;#39; which browsers such as Firefox include) and again using a known offset to be able to accurately size the grid. The grid is rebound and posted back.&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that you would need an AjaxManager on the page to be able to achieve the AJAX elements of this, which I define programmatically:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span&gt;			&lt;/span&gt;RadCodeBlock radCodeBlock = new RadCodeBlock();&lt;br /&gt;radCodeBlock.ID = &amp;quot;radAjaxManagerCodeBlock&amp;quot;;&lt;br /&gt;RadAjaxManager _radAjaxManager = BuildRadAjaxManager();&lt;br /&gt;radCodeBlock.Controls.Add(_radAjaxManager);&lt;br /&gt;Form.Controls.Add(radCodeBlock);&lt;/p&gt;
&lt;div&gt;It&amp;#39;s in a RadCodeBlock because it modifies the DOM so avoids the Exceptions associated with this.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;And in each Module that is interested in Resizing, I have to hook up some AJAX settings (AjaxManager below is the same as _radAjaxManager above):&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;AjaxManager.AjaxSettings.AddAjaxSetting(AjaxManager, radGridUsers);&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;AjaxManager.AjaxSettings.AddAjaxSetting(radGridUsers, radGridUsers);&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This just sets up the grid (radGridUsers) to use AJAX with the AJAX Manager and itself (as it tells itself to rebind).&lt;/p&gt;
&lt;p&gt;I&amp;#39;d be interested to know if I have gone way out on the wrong path on this one, but it seems to be hanging together very well across all the browsers. This is very much thanks to the cross-browser functionality of Telerik&amp;#39;s controls and jQuery.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=481220" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Telerik" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Telerik/default.aspx" /><category term="jQuery" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/jQuery/default.aspx" /></entry><entry><title>Isle of Man BCS: Test+Behaviour Driven Development</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2009/01/14/isle-of-man-bcs-test-behaviour-driven-development.aspx" /><id>/blogs/program.x/archive/2009/01/14/isle-of-man-bcs-test-behaviour-driven-development.aspx</id><published>2009-01-14T08:18:00Z</published><updated>2009-01-14T08:18:00Z</updated><content type="html">&lt;p&gt;
&lt;div&gt;
&lt;p&gt;Last night saw an impressive attendance at January&amp;#39;s BCS event, on&amp;nbsp;&lt;a href="http://www.bcs.org.im/index.php/2009/01/unit-testing-tdd-and-bdd/" title="Test Driven and Behaviour Driven Developmnt at BCS Isle of Man (external link)"&gt;Test Driven and Behaviour Driven Development&lt;/a&gt;. This is possibly an indication of what people want from their&amp;nbsp;&lt;a href="http://www.bcs.org.uk" title="British Computer Society (external link)"&gt;BCS&lt;/a&gt;in terms of subject and engagement with the content.&lt;/p&gt;
&lt;p&gt;The talk by&amp;nbsp;Zakir Hoosen, from&amp;nbsp;&lt;a href="http://www.fuzzelogicsolutions.com/" title="Fuzzelogic Solutions (external link)"&gt;Fuzzelogic Solutions&lt;/a&gt;&amp;nbsp;was very interesting, and proved to introduce the principles behind an increasingly widespread method of development to those who would otherwise not have had the opportunity to see it being used. This included myself. The concept of &amp;quot;Test Driven Development&amp;quot; was alien to my previous job, not because I didn&amp;#39;t want to write good code, but because the organisation failed to engender the opportunity to spend time on code improvement processes. After seeing that while most people in the room were developers, only 5 or so actually used these methodologies, it made me feel slightly better that while my career had suffered as a result of the rut I had found myself I certainly wasn&amp;#39;t on my own. In the &amp;quot;real world&amp;quot;, it isn&amp;#39;t always possible to find the time to look into design and test methodologies, let alone have the skills and time to implement them and surrounding processes.&lt;/p&gt;
&lt;p&gt;Testing aside, a couple of interesting design principles came out of the discussion (and it was a discussion), which align with my own thoughts around best practice:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep inheritance to a minimum, use Interfaces extensively. Whenever I expose any form of object (via an API or otherwise) to a public facing consumer, I always use an Interface. Not only does it provide benefits of abstraction, but it also helps in inversion of control, dependency injection, etc. It&amp;#39;s also a great way to clarify in your own mind the true purpose of a particular class. All classes have their helper methods, but those implementing an interface are seen to be the &amp;quot;meat&amp;quot; of the class.&lt;/li&gt;
&lt;li&gt;Name your classes around the pattern that it is using. As mentioned above, I use Interfaces extensively, and you can&amp;#39;t instantiate an interface (as such), so this is a great opportunity to implement Factory patterns and dependency injection. If you have a class that creates instances of an Interface, call it &amp;quot;Factory&amp;quot;. For example, in one project I am working on, I have a ClientFactory, which produces IClients. It does what it says on the tin. Other patterns which naturally lend themselves well to forming part of the class name are Mediation (&amp;quot;ClientSearchMediator&amp;quot; for managing searching for Clients), Wrapping (&amp;quot;OutlookWrapper&amp;quot; for wrapping a component you can&amp;#39;t necassarily change, for example, Microsoft Outlook) and Proxy (WCFProxy for when a class simply proxies calls between two objects or services, which may or may not include some form of translation). Unfortunately, some of the principles adopted within the .NET Framework and Visual Studio&amp;#39;s automatic code generation don&amp;#39;t always lend themselves to this style of naming, in particular, instead of having a ButtonObserver for the Observer pattern, you tend to get a button_Click method within your presentation class (be it a Windows Form or an ASP.NET Web Form).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The content of the talk was clearly welcomed by the group, much of whom were developers. As a developer, on an island, any opportunity I can get to see techniques I might not have been exposed to is welcome.&amp;nbsp;&lt;a href="http://www.u-g-h.com/" title="Owen&amp;#39;s Blog (external link)"&gt;Owen&lt;/a&gt;&amp;nbsp;asked if we would like to see not only more sessions of this type, but also small &amp;quot;code camp&amp;quot; sessions where a developers collect and work around a topic, hammering out code together. This is a great idea. As many schemes in the US, whereby programmers congregate from all over the country to attend intensive code-athons, this has many advantages. As an island resident, I get to meet my peers in other businesses, learn about methodologies I haven&amp;#39;t necessarily been involved in and be able to implement with guidance of someone who has already traversed the learning curve. While I was particularly pleased that my platform of choice (and language, I would sit there cringing if it was in VB.NET rather than C#!) was being used as the basis of the presentation of test/behaviour driven design techniques, this might not be so easy if we all &amp;quot;jump in&amp;quot; with our own preferences. We all have our own language, platform and coding conventions and standards so this may present a challenge, but also an opportunity to improve our platforms/coding conventions in the workplace as a result of seeing how others do it.&lt;/p&gt;
&lt;p&gt;While this technical content was a welcome change, I do not want to see a 100% technical syllabus. I would still like to see &amp;quot;softer&amp;quot; subjects, such as the previous talks we have had on Search Engine Optimisation, social knowledge using Wikis, etc. This presents an opportunity to maybe create an additional technical channel to complement the softer content and encourage more technical professionals to attend, which can only be a good thing for the BCS as not only do members increase, but also professionalism is shared amongst peers which is what the BCS is all about.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=480571" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="BCS" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/BCS/default.aspx" /><category term="Test Driven Development" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Test+Driven+Development/default.aspx" /></entry><entry><title>Telerik OpenAccess ORM Mapper : Lessons Learnt</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/12/22/telerik-openaccess-orm-mapper-lessons-learnt.aspx" /><id>/blogs/program.x/archive/2008/12/22/telerik-openaccess-orm-mapper-lessons-learnt.aspx</id><published>2008-12-22T11:22:06Z</published><updated>2008-12-22T11:22:06Z</updated><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;When looking at developing new applications I always end up developing my own data layer. Largely because I do not like the dictatorial design principles spouted by the likes of ActiveRecord, nHibernate, et al. I write them according to real life situations where database design isn&amp;#39;t as clean as it perhaps should be and there is no opportunity to make key changes, etc. And you know what, rolling your own is so much easier and much less hassle.&lt;/p&gt; &lt;p&gt;For my current project, though, I thought I&amp;#39;d try something &amp;quot;new&amp;quot; ...&lt;/p&gt; &lt;p&gt;I have been looking at Telerik&amp;#39;s new &lt;a title="OpenAccess ORM at Telerik.com (external link)" href="http://www.telerik.com/products/orm.aspx"&gt;OpenAccess ORM&lt;/a&gt; application recently. Telerik acquired the software a while back and have introduced it into their excellent value Premium RadControls product suite. The Express version is a good way to investigate if it is for you, so long as you are using it on a &amp;quot;free&amp;quot; database server such as SQLExpress, SQLLite, etc.&lt;/p&gt; &lt;p&gt;I thought I&amp;#39;d jot down some quick lessons I have learnt along the way.&lt;/p&gt; &lt;h3&gt;Templates&lt;/h3&gt; &lt;p&gt;My coding style does not match Telerik&amp;#39;s code style as generated from the OpenAccess Reverse Engineering option. Whereas Telerik&amp;#39;s generated form of a private member is in the format:&lt;/p&gt; &lt;p&gt;private string siteName;&lt;/p&gt; &lt;p&gt;My preferred style is:&lt;/p&gt; &lt;p&gt;private string _siteName;&lt;/p&gt; &lt;p&gt;There are few things more frustrating than adopting someone elses coding style, so I set about investigating how to get around this.&lt;/p&gt; &lt;p&gt;There are a number of templates that define how the classes are built when you Reverse Engineer, which are stored in the C:\Program Files\Telerik\OpenAccess ORM\sdk\IDEIntegrations\templates\PCClassGeneration folder (or your equivalent).&lt;/p&gt; &lt;p&gt;To change the private member format, you need to open all the files and look for a reference to the &amp;quot;$fieldName&amp;quot; variable. I changed this to &amp;quot;_$fieldName&amp;quot; and it generated the correct code.&lt;/p&gt; &lt;p&gt;It did not, however, generate the correct mappings, which are stored in the reversemapping.config and App.config files, which I had to tweak manually. I still have a forum post outstanding on this one.&lt;/p&gt; &lt;h3&gt;Deferred Execution&lt;/h3&gt; &lt;p&gt;If you get an &amp;quot;IObjectScope is closed&amp;quot; exception, you&amp;#39;ll probably be doing something intelligent like creating a nice Factory Design Pattern, whereby you get your object within the IObjectScope and return it out for use by your BIZ objects. OpenAccess execution is deferred, however, which means if you access any of the properties outside of the IObjectScope context, you get the exception. So, for my factory method that Gets a Site object:  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="csharpcode" style="width:90%;height:261px;"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Get(Guid id)
        {
            Site site = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
            &lt;span class="kwrd"&gt;using&lt;/span&gt; (IObjectScope scope = Database.Get(_session.ConnectionId).GetObjectScope())
            {
                scope.Transaction.Begin();
                &lt;span class="kwrd"&gt;using&lt;/span&gt; (IQueryResult result = scope.GetOqlQuery(&lt;span class="str"&gt;&amp;quot;SELECT * FROM SiteExtent&amp;quot;&lt;/span&gt;).Execute())
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (result.Count &amp;gt; 0) site = (Site) result[0];
                    &lt;span class="kwrd"&gt;string&lt;/span&gt; s=site.SiteName;
                }
                scope.Transaction.Commit();
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; site;
        }&lt;/pre&gt;
&lt;p&gt;Note that I access the site.SiteName property and discard it. This just forces OpenAccess to perform the Get and put the Site object into memory so when I drop out of the method, I don&amp;#39;t lose the object.&lt;/p&gt;
&lt;h3&gt;Using LINQ&lt;/h3&gt;
&lt;p&gt;Telerik say their Open Access solution is a mid point between LINQ to SQL and Entity Framework. Seems good to me, but there are a few gotchas you need to know about.&lt;/p&gt;
&lt;p&gt;As with anything in the OpenAccess ORM (unless you are working with SQL directly), you don&amp;#39;t work with tables, you work with Extents. The non-LINQ way of doing things int he code sample above shows the OQL query &amp;quot;SELECT * FROM SectionExtent&amp;quot;. The table name is Section, but OpenAccess maps it into an Extent. The same model works when using LINQ. Before you can start using Extents in LINQ, you need to add the Telerik.OpenAccess.Query namespace.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re using of the Telerik products, you might want to follow &lt;a title="@telerikbuzz at Twitter (external link)" href="http://twitter.com/telerikbuzz"&gt;@telerikbuzz&lt;/a&gt; on Twitter for useful information and updates.&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=478386" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="OpenAccess ORM" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/OpenAccess+ORM/default.aspx" /><category term="Telerik" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Telerik/default.aspx" /></entry><entry><title>JavaScript Hall of Shame</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/12/16/javascript-hall-of-shame.aspx" /><id>/blogs/program.x/archive/2008/12/16/javascript-hall-of-shame.aspx</id><published>2008-12-16T17:00:00Z</published><updated>2008-12-16T17:00:00Z</updated><content type="html">&lt;p&gt;Here&amp;#39;s another pet hate in web bad-practice: Javascript. Javascript is a client-side scripting language that allows really useful interaction to occur with the page and the browser, thereby improving the end user experience when using a site. It&amp;#39;s very easy to insert Javascript in a page, not so easy to do it right.&lt;/p&gt;
&lt;p&gt;I despair when I look at many people&amp;#39;s sites, blogs and networks due to JavaScript errors. It really spoils the experience for me. If I follow a link to a site with the promise of interesting content, I do not want to be presented with a series of JavaScript errors in order to get to that content. I&amp;#39;ll just leave. Over the past couple of weeks, (since 1st December to be exact), I have been collecting some of the sites that have JavaScript errors on them (in Internet Explroer 7):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rik Talavera&amp;#39;s site &lt;a href="http://riktalavera.com/"&gt;http://riktalavera.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Reader &lt;a href="http://www.google.com/reader"&gt;http://www.google.com/reader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chris Brogan&amp;#39;s &lt;a title="Chris Brogan&amp;#39;s Newsletter Page" href="http://www.chrisbrogan.com/newsletters/"&gt;Newsletter Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Facebook (of course) &lt;a href="http://www.facebook.com"&gt;http://www.facebook.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TwitPic (on their &lt;a title="TwitPic (external link)" href="http://www.twitpic.com/"&gt;home page&lt;/a&gt;!)&lt;/li&gt;
&lt;li&gt;&lt;a title="TechCrunch (external link)" href="http://www.techcrunch.com/2008/07/15/confirmed-twitter-acquires-summize-search-engine/"&gt;TechCrunch&lt;/a&gt; (prepare to be annoyed)&lt;/li&gt;
&lt;li&gt;Bizarrely, a page on &lt;a title="JavaScript Exception Handling at DevShed (external link)" href="http://www.devshed.com/c/a/JavaScript/JavaScript-Exception-Handling/"&gt;Javascript Exception Handling&lt;/a&gt;&amp;nbsp;(see screenshot below)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://bloggingabout.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/javascriptError.jpg"&gt;&lt;img src="http://bloggingabout.net/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/program.x/javascriptError.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;JavaScript errors can occur due to a number of problems, which bloggers/webmasters aren&amp;#39;t always bothered about. From the most basic blog with a Twitter feed to advanced sites such as Facebook, the result of a Javascript error is the same: unwanted behaviour often accompanied by error messages that mean nothing to the end user.&lt;/p&gt;
&lt;p&gt;There are a number of excellent resources for getting JavaScript snippets to add to your own site, many of them contributed to by &amp;quot;real&amp;quot; Javascript programmers more capable of handling Javascript code than me. Unfortunately, however, differing scripting dialects and runtimes mean that sometimes these scripts haven&amp;#39;t been thoroughly tested on all browsers. &lt;/p&gt;
&lt;p&gt;The increase in social networking, &amp;quot;widgets&amp;quot; and advertising services such as Google Adwords results in external Javascript being injected into the page in order to facilitate a particular requirement. For example, on the home page of &lt;a href="http://www.programx.co.uk"&gt;my site&lt;/a&gt; is a &lt;a title="Twitter (external link)" href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; script that gets my Twitter status from Twitter and injects it into the Document Object Model (DOM) of my home page. It&amp;#39;s really neat. But if Twitter fails (as it regularly does) or the JavaScript doesn&amp;#39;t work with my browser for whatever reason, I will get a JavaScript error - and it will be beyond my control. If possible, it&amp;#39;s a good idea to pull the scripts off the remote servers and host them locally so you can react better in the case of an error.&lt;/p&gt;
&lt;p&gt;As JavaScript essentially runs in accordance with the page load cycle, it requires that the programmer has made resources available in the right place and in the right order for scripts to run flawlessly. If the page load is disrupted somehow, then errors may be caused which could remove functionality from the page. For example, if I load invoke a script in the HEAD of a page, which relies on a control in the BODY, the control would not be rendered when the script executes, thereby generating an error. A simple error, but one which is often forgotten about particularly as network speeds get faster. It becomes easier to assume the user&amp;#39;s page loads as fast as yours. If a script resource gets &amp;quot;held back&amp;quot; over the network for whatever reason, preceding scripts could easily fail. &lt;/p&gt;
&lt;p&gt;There is a definite trend to making the web browser work more like a desktop application with every new web application released. Google is particularly focused on the RIA (Rich Internet Application) which uses techniques such as AJAX to create the impression of a responsive and fully functional application within the web browser. Unfortunately, the script behind these applications is bound to be very complex and errors easily creep in. Take Google Reader, it doesn&amp;#39;t work on my copy of IE7. Take GMail, it regularly fails on IE7. The complexity of the applications is no excuse. Windows is a complex product but users will (rightly) criticise it and damn the product when it fails to work. The same should go for web sites that use faulty JavaScript. Users of Sitecore will know the powerful Content Editing environment that runs using extensive Javascript - it works fine. The only time I get JavaScript errors are when I cause them by fiddling with my browsing context (eg. Internet -&amp;gt; Intranet zones), etc.&lt;/p&gt;
&lt;p&gt;I can almost hear the cries, &amp;quot;use Firefox 3.1&amp;quot; and &amp;quot;use Google Chrome&amp;quot;, due to their JavaScript optimisation. Why should I? I use a browser that is easy to access and is on every machine&amp;nbsp;I touch - that is IE 7, which occupies the majority of the browser market. If you write an web/JavaScript application, it should work on ALL browsers, within reason. &lt;/p&gt;
&lt;p&gt;By &amp;quot;All Browsers&amp;quot;,&amp;nbsp;I mean:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Internet Explorer 7&lt;/li&gt;
&lt;li&gt;Internet Explorer 6&lt;/li&gt;
&lt;li&gt;Firefox 2&lt;/li&gt;
&lt;li&gt;Firefox 3&lt;/li&gt;
&lt;li&gt;Safari&lt;/li&gt;
&lt;li&gt;Google Chrome&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&amp;#39;ll notice that I have not included beta versions of browsers (although I do test my work on these when I believe it is relevant - ie. close to release) and I have gone back a version for the two main browsers, Internet Explorer and Firefox. If your Javascript doesn&amp;#39;t work in all these browsers, or degrade gracefully, you really shouldn&amp;#39;t release the code.&lt;/p&gt;
&lt;p&gt;The JavaScript error message is a jarring experience and spoils many a site. The most attractive site can be ruined by a JavaScript error or two.&amp;nbsp;Just because your browser places a little yellow triangle on the status bar indicating an error has occured in the page, doesn&amp;#39;t mean other users have adopted the same configuration. The average user, who has stumbled on a page with a scrpt error, would not understand why certain aspects of the page are unresponsive as a result of any errors that have occured.&lt;/p&gt;
&lt;p&gt;My view on JavaScript best practice is: not to use it. If you have to use it, make sure it is error checked and gracefully degrades functionality if required. Also, make sure that alternative functionality is available if the functionality it provides is important to the use of the site. I would struggle to find any reason for JavaScript to be on any &amp;quot;front-end&amp;quot; site, whether it is a blog, corporate site or e-Commerce outlet. Javascript should be a complement to a well designed site, which should add value to the user experience. Tickers, counters, advertisements, etc. are not essential to the content on a page.&lt;/p&gt;
&lt;p&gt;There are few things more satisfying in using a web page than when a subtle visual cue is provided to indicate an action has been actioned. Facebook has a number of scripts that allow you to click on text to edit it and then apply it, for example, when updating your status. It&amp;#39;s all happening client-side, with minimal AJAX. It works really well - when JavaScript is available and the script works. If for whatever reason JavaScript isn&amp;#39;t available (maybe the browsing platform doesn&amp;#39;t support it), there is the alternative of typing it in (in most cases) and clicking &amp;#39;Post&amp;#39;. &lt;/p&gt;
&lt;p&gt;Also, remember that search engines will ignore JavaScript. As I always say, your biggest user is deaf, dumb and blind, and that is the search engine. You have to treat the search engine as if it is a base-level browser as a first step of Search Engine Optimisation (SEO), then adding on additional optimisations both for SEO and user experience, which means JavaScript gets added last and does not prevent loading of the page by search engines. I have seen sites that load the next page in the navigation sequence using JavaScript and while it is all very clever in technique, it is not clever in practice. The search bots are getting cleverer all the time and there are rumours of automated JavaScript execution engines that attempt to mimic a user, but these cannot be gauranteed and therefore you should not wrap content only within JavaScript.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;If I can, I always look for tried and tested components, rather then develop my own Javascript. I know my limitations, and Javascript isn&amp;#39;t a strong point. But when I need it, I&amp;#39;ll make sure it works, or look for a component I know will work and will have support behind it. That is why I use Telerik&amp;#39;s &lt;a title="Telerik ASP.NET AJAX UI Controls (external link)" href="http://www.telerik.com/products/aspnet-ajax.aspx"&gt;RadControls for ASP.NET AJAX&lt;/a&gt; for situations where I need complex client-side functionality, possibly to create an RIA experience. I can pay for the components, know that the testing has already been done and assuming I do my work right, should just be able to &amp;quot;drop in&amp;quot; the components and tweak accordingly.&lt;/p&gt;
&lt;p&gt;If you are working with JavaScript, good practice is to turn on JavaScript errors in your browser. That way, no matter what rush there is to launch a site, a script error will always be important - because it will directly annoy you everytime it happens. I turn on script debugging and error messages as part of my web work as standard, and it pays off in my site quality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (23 December 2008):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This has been a popular post, and I&amp;#39;d like to thank Jim Connolly for his feedback. After reading this post, he checked the&amp;nbsp;page about&amp;nbsp;&lt;/strong&gt;&lt;a title="Advertising on Jim Connolly&amp;#39;s site (external link)" href="http://jimsmarketingblog.com/2008/12/13/no-advertising-or-sponsors/"&gt;&lt;strong&gt;Advertising on his site&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;and all seems well now. It&amp;#39;s good to see that we share the same views on web site quality, as he was very prompt about addressing the issue and contacting me about it.&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll keep this list up to date and will name and shame sites that fail to trap JavaScript issues. I encourage you to do the same, if you find a site you&amp;#39;re struggling to use, feel free to leave a comment and I&amp;#39;ll add it to my list.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=478034" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Best Practice" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Best+Practice/default.aspx" /><category term="JavaScript" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/JavaScript/default.aspx" /></entry><entry><title>All hail Google Chrome?</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/09/02/all-hail-google-chrome.aspx" /><id>/blogs/program.x/archive/2008/09/02/all-hail-google-chrome.aspx</id><published>2008-09-02T22:20:04Z</published><updated>2008-09-02T22:20:04Z</updated><content type="html">&lt;p&gt;All hail Google Chrome! Another venture from the megalopolis that is Google Corp. &lt;p&gt;&lt;a title="Google Chrome (external link)" href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt; is a new browser from Google. It has long been rumoured that they were getting closer to the browser space with each new service they offered, particularly with their alliance with Firefox. The thinking was that they&amp;#39;d re-badge Firefox, not bring out their own! But even Google didn&amp;#39;t expect to launch it so soon, as the release is actually earlier than they had wanted due to a ***-up in an email by one of their senior staff. &lt;p&gt;I worry about this browser release. I see it as another way to add to their increasingly threatening hold on the corporate desktop with their below standard, half-functional and eternally-in-beta product line-up published direct from below an as yet to be discovered volcano at Mountain View. Okay, maybe I&amp;#39;m a little too cynical. &lt;p&gt;I have a number of issues with this browser. &lt;p&gt;Privacy is key for me, and while they may have a mantra &amp;quot;do no evil&amp;quot;, that&amp;#39;s not to say no evil is done. While they may or may not be tracking my search behaviour &amp;quot;to optimise and improve&amp;quot; my results (thanks, but I do know how to use &lt;a title="Google operators guide (external link)" href="http://www.google.com/support/bin/static.py?page=searchguides.html&amp;amp;ctx=basics&amp;amp;hl=en"&gt;Google operators&lt;/a&gt; myself to refine my searches), I am not confident that they won&amp;#39;t be recording everything I do in their browser and aligning that with my Google Mail, my Google Search and my Google Docs to send me Google Adverts. My colleague quite rightly said that if it was open source, then such data &amp;quot;leaks&amp;quot; would be spotted by the community. But how &amp;quot;open source&amp;quot; is anything Google do? Certainly not their search engine algorithms, search appliances, etc. Android was billed as open source, but it turns out it has proprietary elements which will remain closed.  &lt;p&gt;The Google web experience is increasingly JavaScript-based and, to give them their due, this was largely a reliable system. Now, however, they seem to have either gone beyond where JavaScript was meant to go or are letting their QA standards drop. Their Google Mail service, which I now feel I am a prisoner of - because it is so good, is now slow and buggy in its latest release. Google have announced they will develop their own JavaScript virtual machine that will *compile* what is an &lt;a title="Interpreted vs Compiled code (external link)" href="http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html"&gt;interpreted language&lt;/a&gt;. This will improve the Optimisation for their own applications, certainly, but at what cost for others vendors&amp;#39; applications? Can we be sure they won&amp;#39;t do the old alleged Microsoft trick of putting in a few &amp;quot;undocumented&amp;quot; features? Will the &amp;quot;Google Experience&amp;quot; connected to the Google applications/GMail, etc. become limited to the Google browser, in isolation, or with a limited feature set in more popular browsers, which given their stranglehold of the &amp;#39;web desktop&amp;#39; or &amp;#39;cloud&amp;#39;, could be anti-competitive? Having tried it on the JavaScript elements of the new &lt;a title="DukeVideo.com Home Page (external link)" href="http://www.dukevideo.com"&gt;www.dukevideo.com&lt;/a&gt; site, it FLIES. I&amp;#39;m looking forward to seeing how Sitecore performs. &lt;p&gt;Chrome also adds to the browser fragmentation which I thought we were getting on top of. If the various browsers didn&amp;#39;t quite agree on things, at least the number of hacks and tweaks required for consistent operation across browsers is significantly reduced from those Netscape/IE 4 and 5 days. The key browsers today are Microsoft&amp;#39;s Internet Explorer, Mozilla&amp;#39;s Firefox and Apple&amp;#39;s Safari. Opera, Konquerer and a few others nibble at the edges but even Opera only accounts for less than 1% of browser users on any of the sites I manage. (Opera is very good on mobile phones, though) The top three browsers all sort of agree on things, though there is a lot of improvements that could be made to all three to bring them closer to web standards compliance. IE is probably beyond help as it is coded to deal with poorly written pages, so has now cornered itself to some extent for a good while to come. Firefox, by common consensus, is the closest of all three to web standards. Safari uses WebKit, which Chrome has also started to use. Is there any undertaking to leave the WebKit &amp;quot;as is&amp;quot; without tweaking for their own corporate behaviour, maybe to tweak how their applications work to the further cost of web standards compliance? &lt;p&gt;Firefox is getting too large, too corporate and too centralised to be truly open source, and is losing open source fans and followers due to their increasingly centrist and controlling attitude. Regular readers will know I&amp;#39;m no fan of open source in a commercial environment, where accountability and contracts are important when developing a reliable and maintainable platform from which to do business. Firefox, however, is a good example of where open source has succeeded. If Google&amp;#39;s Chrome is going to be open source, don&amp;#39;t they fall in to the same trap as Firefox finds itself with the increasingly centrist Mozilla Foundation? &lt;p&gt;Will Google respect XHTML in their browser (and finally in their code?) They certainly don&amp;#39;t in most of their on-line &amp;quot;applications&amp;quot;. On their home page at &lt;a title="Google Homa Page (external link)" href="http://www.google.com"&gt;www.google.com&lt;/a&gt;, they still use the &amp;lt;FONT&amp;gt; tag. Companies of any self-respecting web presence have now at least started deprecating their use of these tags in favour of the XHTML standard - it being more accessible and search-engine friendly. If they would have kept their horrid HTML3/4 markup on their own sites it would be okay, but they do insist on pushing it to respectable web sites via their IFRAME Google Ads. Hopefully, the &amp;quot;community&amp;quot; will encourage them to clean up their act. &lt;p&gt;What I &lt;strong&gt;do&lt;/strong&gt; like about it is that it will partition its tabs from each other. This is ideal for me, because as a web developer, I often end up with multiple IE windows open, with their own set of tabs and sometimes a Firefox or two open. As I run fairly demanding web applications through them (Google Mail, Facebook, Sitecore), they do tend to freeze or crash - which in the supposed on-line world where all my work is in the &amp;quot;cloud&amp;quot;, is intensely annoying - as I would lose any work I have been doing in those browsers when I have to forcibly quit. Seems an obvious idea, to me, to be honest. &lt;p&gt;The dragging of tabs outside of the browser area is very neat. I am disappointed in Microsoft not implementing this, to be honest. You can drag Internet Explorer&amp;#39;s tabs around, but not out of the browser to create a new window. &lt;p&gt;Chrome also comes with a neat little debugger, which every other browser lacks. You always have to install 3rd party add-ons or extensions on to others browsers. It&amp;#39;s &amp;quot;in the box&amp;quot; with Chrome and so far, I&amp;#39;m quite impressed with it. It is a lot more responsive than Firebug. &lt;p&gt;Having just tried my GMail in it, I have to say I like the more passive prompts for remembering passwords, etc. These appear at the top of the window, and don&amp;#39;t block your browsing experience as happens with IE and Firefox, which always annoys as I often move between machines and it takes me 5 minutes to configure my browsing profile (never remember passwords, don&amp;#39;t remind about redirects to secure sites, etc.). &lt;p&gt;Funnily enough, I thought this was quite satisfying when I wanted to find out about the Crash Control feature: &lt;p&gt;&lt;img src="http://www.programx.co.uk/for_external/bloggingaboutnet/02092008/chrome.jpg" alt="" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=474460" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author></entry><entry><title>Sitecore: Accessing Hierarchical Node structures from SQL</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/07/29/sitecore-accessing-hierarchical-node-structures-from-sql.aspx" /><id>/blogs/program.x/archive/2008/07/29/sitecore-accessing-hierarchical-node-structures-from-sql.aspx</id><published>2008-07-29T17:58:41Z</published><updated>2008-07-29T17:58:41Z</updated><content type="html">&lt;p&gt;I&amp;#39;m often presented with the need to process nodes in Sitecore, which as they are hierarchical, can prove difficult to do other than via the Sitecore API. While the Sitecore API is excellent, it is a little cumbersome to create the environment when you only want the API for a single purpose. (eg. configuration files, required resources in the VS project, etc.). It&amp;#39;s also quite slow when traversing down your node structure. &lt;p&gt;I&amp;#39;ve been working on a neat marketing channel to output the best selling products in a particular department within an e-Commerce site. So, in the &amp;quot;Bikes&amp;quot; department, I want to see the best sellers in that department, not any others and to do this I need to work from a particular node in Sitecore (representing the &amp;quot;Bikes&amp;quot; department) and work down on a JOIN from previously purchased items.  &lt;p&gt;SQL is intrinsically not recursive, but we found the following SQL which might be of use: &lt;blockquote&gt; &lt;p&gt;WITH nodes (id, parentID, name, masterID) AS&lt;br /&gt;(&lt;br /&gt;SELECT id, parentID, name, masterID FROM database_sc53_Web..items WHERE id = &amp;#39;110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9&amp;#39; -- root node&lt;br /&gt;UNION ALL&lt;br /&gt;SELECT r1.ID, r1.parentID, convert(nvarchar(256), r2.Name + &amp;#39;/&amp;#39; + R1.Name), r1.masterID&lt;br /&gt;FROM database_sc53_Web..items r1&lt;br /&gt;INNER JOIN nodes r2 ON R1.ParentID = R2.id&lt;br /&gt;WHERE r1.masterID IN &lt;br /&gt;(&amp;#39;E461EFA2-CAC8-4A14-93C2-6966E89AAB5B&amp;#39;,&lt;br /&gt;&amp;#39;34E5E086-6BE9-480A-9EE0-A9CD64F52A76&amp;#39;))&lt;br /&gt;select * from Nodes &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Basically, you create a SELECT to retrieve the root node (indicated by the comment on the fourth line), and then use the SQL 2005 WITH construct to recurse via a JOIN into itself. In the WHERE, we have also added a limit on what nodes are retrieved, by their Master ID, but this could be their TemplateID or some other field available within the Items table. &lt;p&gt;This produces output similar to: &lt;p&gt;&lt;img src="http://www.programx.co.uk/for_external/bloggingaboutnet/29072008/sql.jpg" alt="" /&gt;  &lt;p&gt;This is from the Home node, and runs through the entire site, which is over 10,000 pages. With the filter on the Master IDs, we return 9,057 rows within 1 second. (I know the above says 10 seconds, but the database server is a remote server so this screenshot is a little inaccurate). This runs fast enough and is efficient enough on SQL to allow us to run these queries &amp;quot;live&amp;quot; without a caching layer. &lt;p&gt;Obviously, I wouldn&amp;#39;t recommend putting this in the Sitecore databases themselves, rather a database alongside it and do a cross-database query. &lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:46bf4cb8-4360-4869-98ab-1b2688092dc6" style="padding-right:0px;display:inline;padding-left:0px;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Sitecore" rel="tag"&gt;Sitecore&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SQL%20Server" rel="tag"&gt;SQL Server&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=469839" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author></entry><entry><title>Sitecore: Overriding the style of the fields in the Content Editor</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/06/19/sitecore-overriding-the-style-of-the-fields-in-the-content-editor.aspx" /><id>/blogs/program.x/archive/2008/06/19/sitecore-overriding-the-style-of-the-fields-in-the-content-editor.aspx</id><published>2008-06-19T10:45:00Z</published><updated>2008-06-19T10:45:00Z</updated><content type="html">&lt;p&gt;This is something I figured out last year how to do, forgot, then struggled to figure out how I did it again! If I had blogged about it, I&amp;#39;d have known! Instead, the SDN Forum was kind enough to remind me.&lt;/p&gt;
&lt;p&gt;As a Custom Field Type for this particular aspect of my web page was too cumbersome to develop within my deadline, I opted for an IFRAME Field Type, which when given a URL simply exposes a web page via which you can edit the relavant page data. Unfortunately, the default height is a miniscule 80 pixels. You can override this height, however, by:&lt;/p&gt;
&lt;p&gt;Going to Template Manager&lt;/p&gt;
&lt;p&gt;Opening your Template and selecting Standard Fields on the View ribbon:&lt;/p&gt;
&lt;p&gt;&lt;img width="400" src="http://www.programx.co.uk/for_external/bloggingaboutnet/19062008/blogSc1.jpg" alt="View ribbon &amp;gt; Standard fields" height="77" /&gt;&lt;/p&gt;
&lt;p&gt;Expanding the individual field tree on the left and selecting the relavant field&lt;/p&gt;
&lt;p&gt;FInding the &amp;quot;style&amp;quot; field in the Appearance section and entering your own CSS, in my case &amp;quot;height: 200px&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;img width="400" src="http://www.programx.co.uk/for_external/bloggingaboutnet/19062008/blogSc2.jpg" alt="Appearance section &amp;gt; set CSS" height="264" /&gt;&lt;/p&gt;
&lt;p&gt;Then, when you navigate to the Item which implements the Template, you get a nicely increased height:&lt;/p&gt;
&lt;p&gt;&lt;img width="400" src="http://www.programx.co.uk/for_external/bloggingaboutnet/19062008/blogSc3.jpg" alt="Screenshot" height="200" /&gt;&lt;/p&gt;
&lt;p&gt;I should add that you must remember to deselect Standard Fields once you are done, otherwise Saving subsequent content will override any shared fields and therefore break the link between Template &amp;gt; Master &amp;gt; Item.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=460595" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Sitecore" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Sitecore/default.aspx" /></entry><entry><title>Flash - My view on best practice</title><link rel="alternate" type="text/html" href="/blogs/program.x/archive/2008/05/24/flash-my-view-on-best-practice.aspx" /><id>/blogs/program.x/archive/2008/05/24/flash-my-view-on-best-practice.aspx</id><published>2008-05-24T09:59:54Z</published><updated>2008-05-24T09:59:54Z</updated><content type="html">&lt;p&gt;A conversation I had with a designer friend today where he asked me what I thought about Flash web sites got me thinking.&lt;/p&gt; &lt;p&gt;Flash content might be &amp;quot;flash&amp;quot;, but it is not necessarily useful, functional or usable. I&amp;#39;m not a great fan of Flash, but I can see it&amp;#39;s value to the web. It provides attractive, fluent and dynamic sites and designs that have a level of interaction that is difficult to duplicate in a conventional web-site - even when using techniques such as JavaScript and, increasingly, AJAX. &lt;/p&gt; &lt;p&gt;Users who visit a Flash site may experience a number of effects of the Flash content that can disrupt a positive web experience, which often reduces the benefits of using Flash in the first place. When visiting a Flash site with a system or browser that does not have Flash installed, a pop-up, yellow bar or a simple failed portion of the page will be displayed. This can be frustrating, because before I can enjoy the quick-satisfaction I love about the web, I have to wait for a number of minutes while I download and install the Flash applet. This is, of course, only done once so it&amp;#39;s annoying once per browser. I remember I recently had to help someone who was having problems with using a web site that used Flash. His browser was experiencing a HAL-9000 style internal conflict. It wanted to install the applet, but his security suite which had integrated itself into his system didn&amp;#39;t like it so much, so caused extra confirmation windows which, quite simple, can be quite scary if you&amp;#39;re not sure what you&amp;#39;re doing.&lt;/p&gt; &lt;p&gt;Once the Flash applet has been downloaded and installed, we then have to wait for the Flash content to load. Well designed Flash content is, of course, loaded asynchronously often with attractive progress bars. Others, just make you wait. But why should I wait? I often have to go to sites and have to watch a progress bar making it&amp;#39;s away across the site, and these are big sites - one key site is Sony Ericsson&amp;#39;s product catalogue at &lt;a title="http://www.sonyericsson.com/cws/products/mobilephones?cc=gb&amp;amp;lc=en" href="http://www.sonyericsson.com/cws/products/mobilephones?cc=gb&amp;amp;lc=en"&gt;http://www.sonyericsson.com/cws/products/mobilephones?cc=gb&amp;amp;lc=en&lt;/a&gt;. It even comes up with &amp;quot;There&amp;#39;s a lot to load, but it&amp;#39;s worth the wait&amp;quot;. Well actually, it isn&amp;#39;t. I struggle to wait for them to bring out decent and reliable phones - I don&amp;#39;t want to add waiting for the most important page on their site to load too. If you haven&amp;#39;t got Flash, maybe they think you&amp;#39;re not worth the effort? Luckily my Nokia has got Flash, but I won&amp;#39;t be browsing their site with it.&lt;/p&gt; &lt;p&gt;When the Flash applet has loaded, we&amp;#39;re often presented with a beautifully designed and thought through experience. Immediate feedback is provided on mouse interaction with screen elements. Animation is smooth and can be beautifully subtle. A well designed Flash web site is a joy to use - if you&amp;#39;re able to fully utilise and benefit from a web experience. Users who require accessibility features such as alternatives to mouse control, larger text, different colour schemes or spoken content all too often lose their experience at this point. No matter how many times they change their browser settings to affect the stylesheet, the text size or control method, the Flash applet will often sit and ignore their wishes. A real shame, because the effort that goes into a Flash applet is not insignificant and requires a paradigm shift in terms of programming. Additionally, even &amp;quot;able&amp;quot; users can struggle to shift their method of interaction to a Flash applet. For instance, I was at a corporate partner&amp;#39;s web-site today and I was navigating their site struggling to find some content. I went on a page that was not relevant and instinctively went for the &amp;quot;Back&amp;quot; button - possibly the biggest button on most browser toolbars. I ended back at my Google search, quite frustrating as I then had to navigate back to where I was (after I had waited for the &amp;quot;web site&amp;quot; to load again).&lt;/p&gt; &lt;p&gt;The support of Flash is subject to a large extent to Adobe&amp;#39;s opinion and support of a particular platform. The PC and Mac will enjoy Flash players for the forseeable future - but what about the increasing number of alternative browsers? Television browsing is growing fast - often via a games console connected to the internet. Also growing fast is mobile browsing. I am lucky that my new Nokia N95 phone supports Flash, but other phones may not. Other phones would need more memory, a better CPU and this can have a big impact on battery life. If Adobe does not believe a particular platform will &amp;quot;work&amp;quot; (which may even be down to licensing or political reasons, luckily, not something Adobe seems prone to yet), no matter the technical qualities of the device, they can choose not to implement a Flash player. Would you like to put your web-site into their hands and have them choose who can and cannot access your site?&lt;/p&gt; &lt;p&gt;Finally, there are the inevitable security concerns and the obligations that come with them that are passed on to you, the user. We&amp;#39;re now at Flash 9. More features are being added each time and this will only provide greater opportunity for bugs and potential security vulnerabilities. We struggle to make sure that our operating system and browser is &amp;quot;patched up&amp;quot; already, now we have to worry about various applets inside the browser. Granted, this is usually an automatic process, but it is using &lt;em&gt;my&lt;/em&gt; time to download and install, &lt;em&gt;my&lt;/em&gt; bandwidth allocation which may be capped and places the responsibility on &lt;em&gt;me&lt;/em&gt; to make sure it is up to date.&lt;/p&gt; &lt;p&gt;Then there are the servers. I always say Google is the most stupid, deaf, dumb and blind user that will use your site - but you want it to use it regularly. Search engines such as Google cannot use a Flash applet. Even when the &amp;quot;Googleplex&amp;quot; achieves sentient status, it will struggle to effectively index and understand a Flash applet and the content it contains in a structured and useful way suitable for indexing. When a search engine goes to your Flash site, it often sees very little. For heaven&amp;#39;s sake, make sure that you at least include a decent &amp;lt;TITLE&amp;gt; tag and effective &amp;lt;META&amp;gt; data.&lt;/p&gt; &lt;h2&gt;So how can you use Flash effectively?&lt;/h2&gt; &lt;p&gt;I&amp;#39;m not interested in being negative for negativity&amp;#39;s sake regarding Flash content. Flash content has it&amp;#39;s place, and it can often create a very positive user experience, if implemented with consideration to users and search engines. I have come up with the following guidelines I like to keep in mind when people ask me about Flash.&lt;/p&gt; &lt;h3&gt;What is Flash good at?&lt;/h3&gt; &lt;p&gt;Recently, we&amp;#39;ve been playing with streaming high-quality video streams using as little bandwidth as possible for as cheap as possible. There are few products that can truly achieve this and have such a wide user-base as Flash. Windows Media Player is on virtually all PCs thanks to it&amp;#39;s integration with Windows (except in Europe, of course!) but this often draws resentment from users, particularly Mac users who often need special software to view the same content. By the same token, Quicktime is available on Macs (although they realistically represent no risk to the true business user market) but PC users may resent (and I do) the repeated attempts by Apple to install iTunes and now Safari along with it. Having a &amp;quot;Go Pro&amp;quot; message everytime you close the application is also frustrating. Finally, there is Real Player, a wild thing that has little respect for your wider use of your PC. It aggressively tries to take control of all your media, constantly wants you to &amp;quot;register&amp;quot; for content and support (read &amp;quot;spam&amp;quot;), places tray icons that have no benefit to users and has effectively turned into bloat-ware. Flash, on the other hand, can handle very efficiently compressed video that can be secured and made available to users no matter what platform they may be using. It is no accident that YouTube use Flash for their video player. While no content on the web is truly secure, I was interested to learn that you can adopt some cute practices to seal up Flash video content - at least to the amateur.&lt;/p&gt; &lt;p&gt;Flash is good at marketing. Marketing channels such as banners were often animated GIF&amp;#39;s which were slow to load, animated jerkily and were unattractive due to their 256-colour palette. Now, Flash is used regularly and - if well implemented - can provide a positive user experience. The silly and pointless Flash adverts that you find on sites like Facebook aside, a Flash applet can entice users in by presenting simple games, video&amp;#39;s (the IBM ones are very popular, good ol&amp;#39; Gill) and elegantly designed animations. If I see a Flash video ad, I usually play it.&lt;/p&gt; &lt;p&gt;Flash is also great for games. So many hours have been spent playing silly, pointless but highly addictive games built in Flash. These games are great as a viral marketing tool, too. Kids love them, they&amp;#39;re safe and they&amp;#39;re highly interactive thanks to their ability to utilise the multimedia features of a PC.&lt;/p&gt; &lt;h3&gt;Never wrap content up only within a Flash applet&lt;/h3&gt; &lt;p&gt;You wouldn&amp;#39;t keep your key web site content behind a username/password protected page, preventing your users and customers from accessing it so you shouldn&amp;#39;t put such content only within a Flash applet. Users who cannot use Flash must be able to access the same information or functionality. Sure, it may not be as snazzy or beautiful, but some people don&amp;#39;t have time, security-privileges to install Flash or just aren&amp;#39;t that superficial. I&amp;#39;m a meat and guts person, myself. Flashy graphics has no effect on me, if I can&amp;#39;t get at what I want, I&amp;#39;m off. &lt;/p&gt; &lt;p&gt;In providing this alternative content, you can choose to do it in two ways. You can check for Flash on the browser in some JavaScript and fail-over to static HTML if Flash isn&amp;#39;t available, or you can present either content and ask the user to choose. But don&amp;#39;t do a &amp;quot;Flash or HTML?&amp;quot;-style page, this has no benefit to search engines and requires an extra click for the user to access their content. A perfect solution, for me, is to try and load the Flash version and then load a small portion of the Flash content along with an option to choose the static version. This maintains a quick and attractive user experience, even if the user opts for the static version as they&amp;#39;ve not been made to wait for the full applet to load.&lt;/p&gt; &lt;h3&gt;Flash works really well when it complements your content&lt;/h3&gt; &lt;p&gt;Consider my hosting company&amp;#39;s site: &lt;a href="http://www.hostinguk.net"&gt;www.hostinguk.net&lt;/a&gt;. The Flash applet along the top is being used for what it is good at: creating an attractive and vibrant promotion mechanism that is central to the user&amp;#39;s eye-line. I visit their site regularly, and this applet is used to convey latest marketing and products that are being implemented and gets my attention every time. But after a few seconds absorbing the simple content conveyed through the promotion channel, my eyes fall to the text - I want detail and there&amp;#39;s nothing like text for providing it. &lt;/p&gt; &lt;p&gt;So in this case, the Flash content is complementing the site content. It is being used as a vibrant, attractive and sleek channel for conveying a marketing message but if you can&amp;#39;t see it, you don&amp;#39;t miss out. Additionally, it is small, so it loads fast. Search engines will ignore the Flash and attack the text on the same page, which will drive users to the page and who will see the attractive Flash applet and from that, their initial momentary impression of their browsing experience will decide whether they&amp;#39;re likely to stick around and maybe make a purchase.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;A client has recently told me that I had lost out on the development of a charity&amp;#39;s web site to a Flash web site developer. This infuriates me, as, at the end of the day, they will end up with an attractive site but which would be difficult to find - and certainly next to impossible to find and jump straight in to the context which I want. Flash developers might not have realised it yet, but when you search in search engines, they tend to take you to the &lt;em&gt;content&lt;/em&gt; you&amp;#39;re after - not the first page and have you find your way through the navigation to the content - which is what a Flash site forces you to do.&lt;/p&gt; &lt;p&gt;In conclusion, we must also visit Silverlight, Microsoft&amp;#39;s competitor product. Silverlight offers much the same as Flash does now, or will do in a production capacity when v2 is eventually released. Silverlight offers the developer a lot more features than it offers the user, in all honesty. It&amp;#39;s another component that has to be installed in increasingly bloated browsers. From a user&amp;#39;s point of view, I struggle to see any benefits. The benefits are entirely for developers, particularly those with a .NET background. The Silverlight platform has one key difference, however. It uses Javascript for it&amp;#39;s control mechanism, and holds it&amp;#39;s data behind web services and XML files as XAML. While not entirely useful for a search engine, at least it is &lt;em&gt;something&lt;/em&gt;. Again, I would never advise implementing a site or part of a site entirely within Silverlight, particularly when it is such a fledgling product. It has a long way to go and while Microsoft may have a link on every page of their site, it&amp;#39;s going to take more than that to encourage users to install it - particularly as it&amp;#39;s use has actually &lt;em&gt;slowed down&lt;/em&gt; key Microsoft sites such as their Download Site.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://bloggingabout.net/aggbug.aspx?PostID=459323" width="1" height="1"&gt;</content><author><name>Nathan Pledger</name><uri>http://bloggingabout.net/members/Nathan-Pledger/default.aspx</uri></author><category term="Accessibility" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Accessibility/default.aspx" /><category term="SEO" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/SEO/default.aspx" /><category term="Flash" scheme="http://bloggingabout.net/blogs/program.x/archive/tags/Flash/default.aspx" /></entry></feed>
