Archive for February, 2010

WCF Client Generic Base Class

Posted: 26th February 2010 in WCF

Further to my previous blog entry about the WCF 10 connection limit and its inability to implement the IDisposable interface or allow the use of the “using block” to free up the connections, I decided to write a generic base class.

This base class does not close the connection automatically,nor does it dispose of the connection, but it does allow me to create and use a service client a lot easier.

  1. public class BaseServiceConnector<T> where T : ICommunicationObject, new()
  2. {
  3. private T serviceClient = new T();
  4. /// <summary>
  5. /// Instance variable to access the Cache from the enterprise library
  6. /// </summary>
  7. private static readonly ICacheManager cacheManager = CacheFactory.GetCacheManager();
  8. /// <summary>
  9. /// Gets the service client.
  10. /// </summary>
  11. /// <value>The service client.</value>
  12. protected T ServiceClient
  13. {
  14. get
  15. {
  16. try
  17. {
  18. if (this.serviceClient.Equals(default(T)) || this.serviceClient.State == CommunicationState.Closed)
  19. {
  20. this.serviceClient = new T();
  21. }
  22. this.ReEstablishProxyIfNecessary();
  23. }
  24. catch (FaultException)
  25. {
  26. this.ReEstablishProxyIfNecessary();
  27. }
  28. catch (Exception)
  29. {
  30. this.ReEstablishProxyIfNecessary();
  31. }
  32. return this.serviceClient;
  33. }
  34. }
  35. /// <summary>
  36. /// Instance variable to access the Cache from the enterprise library
  37. /// </summary>
  38. public ICacheManager CacheManager
  39. {
  40. get { return cacheManager; }
  41. }
  42. /// <summary>
  43. /// Re-establish proxy if necessary.
  44. /// </summary>
  45. private void ReEstablishProxyIfNecessary()
  46. {
  47. if (this.serviceClient.State != CommunicationState.Faulted)
  48. {
  49. return;
  50. }
  51. this.serviceClient.Abort();
  52. this.serviceClient = new T();
  53. }
  54. }

Now I can create service  clients and reuse the code all I have to do is inherit from it and pass in the proxy client instance name.

  1. public class LookupServiceCache : BaseServiceConnector<LookupServiceClient>, ILookupServiceCache
  2. {
  3. #region Lookups
  4. /// <summary>
  5. /// Gets the towns.
  6. /// </summary>
  7. /// <returns>The list from the cache if it exists; or from the database</returns>
  8. public IList<TownDto> GetTowns()
  9. {
  10. var cacheKey = LookupDataType.Towns.ToString();
  11. if (!this.CacheManager.Contains(cacheKey))
  12. {
  13. var towns = this.ServiceClient.GetTowns();
  14. this.CacheManager.Add(
  15. cacheKey,
  16. towns,
  17. CacheItemPriority.Normal,
  18. null,
  19. new SlidingTime(TimeSpan.FromMinutes(Constants.CacheTimeout)));
  20. this.ServiceClient.Close();
  21. }
  22. return (IList<TownDto>)this.CacheManager.GetData(cacheKey);
  23. }
  24. }

I’ve found this useful for creating a business logic layer above the service for purpose of caching, validation, etc.

Two brilliant tools for blogging

Posted: 19th February 2010 in General

These two tools make blogging a whole lot easier than having to fiddle about with formatting in HTML text editors

One: Download Windows Live Writer for editing  and creating blog posts on the most popular blogging sites.

Two: Paste as Visual Studio Code plug–in allows you to paste code in colour format from Visual Studio.

Enjoy…

When you want to update a value from a control in the control template section of a data bound collection of an accordion control it is necessary to find the control in the collection to update it.

Shown below is a basic example to explain what I mean.

basic accordion control
  1. <asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
  2.         </asp:ToolkitScriptManager>
  3.         <asp:Accordion ID="Accordion1" runat="server" OnItemCommand="Accordion1_ItemCommand" >
  4.         <HeaderTemplate>
  5.             <asp:Label runat="server" ID="Label1" Text='<% #Eval("Text") %>'></asp:Label>
  6.         </HeaderTemplate>
  7.         <ContentTemplate>
  8.              <asp:Label ID="label1" runat="server" Text='<% #Eval("Id") %>'  ></asp:Label>
  9.              <asp:TextBox ID="textBox1" runat="server" Text='<% #Eval("Text") %>'  ></asp:TextBox>
  10.              <asp:Button ID="Button1" runat="server" Text="submit" CommandName="Update" CommandArgument='<% #Eval("Id") %>' />
  11.         </ContentTemplate>
  12.         
  13.         </asp:Accordion>

As seen below, the server side code to bind this control is generated by a loop in the LoadData() method

Binding to the accordion
  1. Accordion1.DataSource = this.LoadData();
  2.             Accordion1.DataBind();

And the LoadData() implementation is a simple iteration to create a List of a  simple class Class1 consisting of two properties Id and Title

Creating the list to bind to
  1. protected IList<Class1> LoadData()
  2.       {
  3.           for (var i = 0; i < 9; i++ )
  4.           {
  5.               list.Add(new Class1 { Id = i, Text = i.ToString() });
  6.           }
  7.  
  8.           return list;
  9.       }

Okay, simple enough. Now, we want to update the the value of the displayed value of textBox1 in the ContentTemplate of the “Basic accordion control” example.

To do this, we need to use the ItemCommand event of the accordion control and cast it to a AccordionCommandEventArgs as seen in the following example.

 

Getting the value
  1. protected void Accordion1_ItemCommand(object sender, EventArgs e)
  2.         {
  3.             var t = ((AccordionCommandEventArgs) e).Container.DataItem;
  4.             var id = ((Label) ((AccordionCommandEventArgs) e).Container.FindControl("label1")).Text;
  5.             var text = ((TextBox) ((AccordionCommandEventArgs) e).Container.FindControl("textBox1")).Text;
  6.         }

The variable “text” will now hold the value you are looking for.

Happy coding 🙂

Given the task of populating and binding controls within an AJAX accordion control I thought things would be easy.  However, binding to a selected index of a dropdown control was not as easy as I first suspected.

Below is one of the accordion section included in my tab container.

Accordion with dropdown
  1. <asp:Accordion ID="devicesAccordion" runat="server" OnItemDataBound="DeviceAccordion_ItemDataBound">
  2.                                 <HeaderTemplate>
  3.                                      <tr>
  4.                                         <td><asp:Label ID="Label2" Text='<%# Eval("Name") %>' runat="server"  /></td>
  5.                                      </tr>
  6.                                 </HeaderTemplate>
  7.                                 <ContentTemplate>
  8.                                     <label for="nameTextBox">Name</label>
  9.                                     <asp:TextBox ID="nameTextBox" Text='<%# Eval("Name") %>' runat="server" />
  10.                                     <label for="deviceStatusDropDownList">Status</label>
  11.                                     <asp:DropDownList ID="deviceStatusDropDownList" runat="server" />
  12.                                     <asp:Button runat="server" ID="updateDevicesButton" CommandName="UpdateDevice" OnCommand="UpdateDevicesButton_Command" CommandArgument='<%# Eval("Id") %>' Text="Update" />
  13.                                 </ContentTemplate>
  14.                             </asp:Accordion>

Next, I had to bind the value from the DB to the status of the device and to do this I use the item data bound event of the accordion control. Firstly, I have to AccordionItemEvent being passed in is within the content part of the  control, i.e. the one being edited.

Once I’ve confirmed this, I need to convert the item in the control to the Data Transfer Object being retrieved from the WCF Service.  Then, if the cast to the DTO is not null. I find the control and set the value of the dropdown.

Binding an accordion item
  1. /// <summary>
  2.         /// Event handler when a new item is bound in the contentTemplate of the devices accordion.
  3.         /// </summary>
  4.         /// <param name="sender">The sender.</param>
  5.         /// <param name="e">The <see cref="AjaxControlToolkit.AccordionItemEventArgs"/> instance containing the event data.</param>
  6.         protected void DeviceAccordion_ItemDataBound(object sender, AccordionItemEventArgs e)
  7.         {
  8.             if (e.ItemType != AccordionItemType.Content)
  9.             {
  10.                 return;
  11.             }
  12.  
  13.             var deviceDto = e.Item as DeviceDto;
  14.             if (deviceDto == null)
  15.             {
  16.                 return;
  17.             }
  18.  
  19.             var dropDownList = e.AccordionItem.FindControl("deviceStatusDropDownList") as DropDownList;
  20.             if (dropDownList == null)
  21.             {
  22.                 return;
  23.             }
  24.  
  25.             this.PopulateDropDownListAndSetValue(dropDownList, LookupDataType.DeviceStatuses, deviceDto.Status.Status);
  26.         }

To help me with this process, I created a basic interface to be implemented by all DTO’s that can be used in a dropdown. 

Interface for Dropdowns
  1. /// <summary>
  2.     /// Interface to be implemeted to use a class as part of a drop down list.
  3.     /// </summary>
  4.     public interface ILookupData
  5.     {
  6.         /// <summary>
  7.         /// Gets the key for the lookup data.
  8.         /// </summary>
  9.         /// <value>The key of the lookup.</value>
  10.         string Key { get; }
  11.  
  12.         /// <summary>
  13.         /// Gets the value for the lookup data.
  14.         /// </summary>
  15.         /// <value>The value of the lookup.</value>
  16.         string Value { get; }
  17.     }

I also created a method to populate and set the value of the dropdown’s  selected index setting the Text and Key properties defined in the above interface.

Populate and set the dropdown
  1. /// <summary>
  2.         /// Populates the drop down list and set value.
  3.         /// </summary>
  4.         /// <param name="dropDownList">The drop down list.</param>
  5.         /// <param name="lookupDataType">Type of the lookup data.</param>
  6.         /// <param name="selectedValue">The selected value.</param>
  7.         protected void PopulateDropDownListAndSetValue(ListControl dropDownList, LookupDataType lookupDataType, string selectedValue)
  8.         {
  9.             dropDownList.DataSource = this.serviceConnector.GetLookupData(lookupDataType);
  10.             dropDownList.DataTextField = "Value";
  11.             dropDownList.DataValueField = "Key";
  12.             dropDownList.DataBind();
  13.             if (string.IsNullOrEmpty(selectedValue))
  14.             {
  15.                 return;
  16.             }
  17.  
  18.             dropDownList.SelectedValue = selectedValue;
  19.         }

In the code sample above it is shown that the data source for the the dropdown comes from a WCF Service which, in turn, returns a list of interfaces ILookupData. The working and casting for this service call is shown in the code sample below.

Casting items in a list
  1. /// <summary>
  2.         /// Gets the lookup data.
  3.         /// </summary>
  4.         /// <param name="lookupDataType">Type of the lookup data.</param>
  5.         /// <returns></returns>
  6.         public IList<LookupData> GetLookupData(LookupDataType lookupDataType)
  7.         {
  8.             IList<ILookupData> lookDataList = new List<ILookupData>();
  9.             switch (lookupDataType)
  10.             {
  11.                 case LookupDataType.Countries:
  12.                     lookDataList = this.GetCountries().ToList().ConvertAll(item => (ILookupData)item);
  13.                     break;
  14.                 case LookupDataType.DeviceStatuses:
  15.                     lookDataList = this.GetDevicesStatuses().ToList().ConvertAll(item => (ILookupData)item);
  16.                     break;
  17.                 case LookupDataType.Towns:
  18.                     lookDataList = this.GetAllTowns().ToList().ConvertAll(item => (ILookupData)item);
  19.                     break;
  20.             }
  21.  
  22.             return lookDataList.ToList().ConvertAll(item => (LookupData)item);
  23.         }

Hopefully, this post helps someone out there…

WCF 10 connection limitation

Posted: 15th February 2010 in AJAX, WCF

Recently, I had a problem with an AJAX enabled application which was calling a WCF service. As can be seen below, in my calls to the Service, I used the “using statement” to allow the connection to the service to be closed after use. 

Code Snippet
  1. /// <summary>
  2.         /// Gets the towns.
  3.         /// </summary>
  4.         /// <returns>The list from the cache if it exists; or from the database</returns>
  5.         public List<TownDto> GetTowns()
  6.         {
  7.             if (!this.cacheManager.Contains("towns"))
  8.             {
  9.                 using (var svc = new NetworkServiceClient())
  10.                 {
  11.                     var towns = svc.GetAllTowns();
  12.                     this.cacheManager.Add(
  13.                         "towns",
  14.                         towns,
  15.                         CacheItemPriority.Normal,
  16.                         null,
  17.                         new SlidingTime(TimeSpan.FromMinutes(Constants.CacheTimeout)));
  18.                 }
  19.             }
  20.  
  21.             return (List<TownDto>)this.cacheManager.GetData("towns");
  22.         }

However, as i played with the application it became apparent that the more calls its made the slower the application became.   Eventually, after wading threw all the application tiers I found the culprit was: by default WCF only allows 10 connections, which meant my connections weren’t being closed by the using statement.

The code has now been refactored to close the service client explicitly. It now works!