May 04

We have been using a WebAqua Silverlight Navigation control in our application for several years.  Recently, after implementing a few changes to the application and deploying to our test server, we started seeing an “Unlicensed Version” message in the middle of the application.  Our version was licensed and had no issues until the most recent set of changes.

Over last few weeks I’ve been emailing WebAqua Tech Support and spent several hours on their Live Chat trying to resolve the issue without any success.  After all licensing attempts have failed, I went down the path of backtracking through our code, which led me to my solution.

Solution

The issue was caused by the levels of nesting.   To begin with, the FishEye control was nested 11 layers deep inside Border controls and Grids.  We have 10 Border controls with a Grid inside used for layout.  The issue came up when I added another layer of nesting by wrapping everything in a Grid to add a “Loading…” message that overlays the whole User Control.  This seems very odd, but the message went away after I removed the outer Grid.

I hope that this solution will come in handy for someone with a similar issue.

Tagged with:
Feb 19

 

I was looking to implement Silverlight Telerik Transitions in my Silverlight 5 application with User Controls to walk a user through a wizard.  My initial approach was to use a Visual State Manager, which would allow me to keep all the UI logic in the XAML.  This did not work well with Telerik Transitions.  I decided to use DataTriggers that modified the state of the UI  based on a WizardState enumeration on my View Model.

View Model

 
Namespace ViewModels.Employee
 
    Public Class EmployeeViewModel
        Inherits BaseViewModel
 
 
#Region "Properties"
 
        Private _employeeSetupState As EmployeeSetupStateEnum
 
        Public Property EmployeeSetupState As EmployeeSetupStateEnum
            Get
                Return _employeeSetupState
            End Get
            Set(ByVal value As EmployeeSetupStateEnum)
                If _employeeSetupState <> value Then
                    _employeeSetupState = value
                    NotifyPropertyChanged("CanMoveForward")
                    NotifyPropertyChanged("CanMoveBack")
                    NotifyPropertyChanged("EmployeeSetupState")
                End If
            End Set
        End Property
 
        Public ReadOnly Property CanMoveForward() As Boolean
            Get
                Dim newState As Integer = EmployeeSetupState + 1
                If [Enum].IsDefined(GetType(EmployeeSetupStateEnum), newState) Then
                    Return True
                End If
 
                Return False
            End Get
        End Property
 
        Public ReadOnly Property CanMoveBack() As Boolean
            Get
                Dim newState As Integer = EmployeeSetupState - 1
                If [Enum].IsDefined(GetType(EmployeeSetupStateEnum), newState) Then
                    Return True
                End If
 
                Return False
            End Get
        End Property
 
        ' The Properties for the View Models are defined here.
 
#End Region
 
#Region "Base Overrides/Overloads"
 
        Public Overrides Sub Initialize()
            MyBase.Initialize()
 
            EmployeeSetupState = 0
            InitializeStep()
        End Sub
 
#End Region
 
#Region "Public Methods"
 
        Public Sub NextStep()
 
            If CanMoveForward Then
                EmployeeSetupState = CType(EmployeeSetupState + 1, EmployeeSetupStateEnum)
                InitializeStep()
            End If
 
        End Sub
 
        Public Sub PreviousStep()
 
            If CanMoveBack Then
                EmployeeSetupState = CType(EmployeeSetupState - 1, EmployeeSetupStateEnum)
                InitializeStep()
            End If
 
        End Sub
 
#End Region
 
#Region "Private Methods"
 
        Private Sub InitializeStep()
 
            Select Case EmployeeSetupState
                Case EmployeeSetupStateEnum.EmployeeGeneralInformationState
                    EmployeeGeneralInformationViewModel.Initialize()
                Case EmployeeSetupStateEnum.EmployeeAddressInformationState
                    EmployeeAddressInformationViewModel.Initialize()
                Case EmployeeSetupStateEnum.EmployeeContactInformationState
                    EmployeeContactInformationViewModel.Initialize()
                Case EmployeeSetupStateEnum.EmployeeCommentsState
                    EmployeeCommentsViewModel.Initialize()
            End Select
 
        End Sub
 
#End Region
 
    End Class
 
    ''' <summary>
    ''' States of the Employee setup process. These steps
    ''' are executed in the order specified.
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum EmployeeSetupStateEnum
        EmployeeGeneralInformationState
        EmployeeAddressInformationState
        EmployeeContactInformationState
        EmployeeCommentsState
    End Enum
 
End Namespace

In the code above, I have an enumeration that specifies valid states for my employee setup process (specified in the order I want to show these states) and a property in my View Model that holds the current state of the employee setup process. I have a trigger that calls the Initialize() method on my View Model when the page loads.  During the initialization process, my EmployeeSetupState is set to the first step and the view model for that step is initialized by calling the InitializeStep() method.  I have a property that determines if the current EmployeeSetupState has a previous or next step.  My View Model also holds a reference to the View Models for each of the User Controls that make up my employee setup states (not shown in the code above).

View

<UserControl.Resources>
    <vm:EmployeeViewModel x:Name="ViewModel"/>
</UserControl.Resources>
 
<Grid xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Name="LayoutRoot">
 
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="250" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
 
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <ic:CallMethodAction MethodName="Initialize"
                                 TargetObject="{Binding Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
 
    <telerik:RadTransitionControl Content="{Binding EmployeeSetupState}">
        <telerik:RadTransitionControl.Transition>
            <telerik:FadeTransition />
        </telerik:RadTransitionControl.Transition>
        <telerik:RadTransitionControl.ContentTemplate>
            <DataTemplate>
                <Grid Margin="5,10,5,10">
 
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
 
 
                    <uc:EmployeeGeneralInformationView x:Name="EmployeeGeneralInformationView"
                        Visibility="Collapsed"
                        DataContext="{Binding Source=ViewModel, Path=EmployeeGeneralInformationViewModel, Mode=TwoWay}" />
                    <uc:EmployeeAddressInformationView x:Name="EmployeeAddressInformationView"
                        Visibility="Collapsed"
                        DataContext="{Binding Source=ViewModel, Path=EmployeeAddressInformationViewModel, Mode=TwoWay}" />
                    <uc:EmployeeContactInformationView x:Name="EmployeeContactInformationView"
                        Visibility="Collapsed"
                        DataContext="{Binding Source=ViewModel, Path=EmployeeContactInformationViewModel, Mode=TwoWay}" />
                    <uc:EmployeeCommentsView x:Name="EmployeeCommentsView"
                        Visibility="Collapsed"
                        DataContext="{Binding Source=ViewModel, Path=EmployeeCommentsViewModel, Mode=TwoWay}" />
 
                    <i:Interaction.Triggers>
                        <ei:DataTrigger Binding="{Binding Converter={StaticResource EnumToStringConverter}}"
                                        Value="EmployeeGeneralInformationState">
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Visible"
                                TargetName="EmployeeGeneralInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeAddressInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeContactInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeCommentsView" />
                        </ei:DataTrigger>
                        <ic:DataTrigger Binding="{Binding Converter={StaticResource EnumToStringConverter}}"
                                        Value="EmployeeAddressInformationState">
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeGeneralInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Visible"
                                TargetName="EmployeeAddressInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeContactInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeCommentsView" />
                        </ic:DataTrigger>
                        <ic:DataTrigger Binding="{Binding Converter={StaticResource EnumToStringConverter}}"
                                        Value="EmployeeContactInformationState">
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeGeneralInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeAddressInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Visible"
                                TargetName="EmployeeContactInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeCommentsView" />
                        </ic:DataTrigger>
                        <ic:DataTrigger Binding="{Binding Converter={StaticResource EnumToStringConverter}}"
                                        Value="EmployeeCommentsState">
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeGeneralInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeAddressInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Collapsed"
                                TargetName="EmployeeContactInformationView" />
                            <ic:ChangePropertyAction
                                PropertyName="Visibility" Value="Visible"
                                TargetName="EmployeeCommentsView" />
                        </ic:DataTrigger>
                    </i:Interaction.Triggers>
 
                </Grid>
            </DataTemplate>
        </telerik:RadTransitionControl.ContentTemplate>
    </telerik:RadTransitionControl>

    <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
        <Button x:Name="PreviousButton" Content="&lt; Previous"  HorizontalAlignment="Right"
                Visibility="{Binding CanMoveBack, Converter={StaticResource BoolToVisibilityConverter}}"
                Margin="5"  Style="{StaticResource ButtonPrimaryStyle}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ic:CallMethodAction MethodName="PreviousStep"
                                         TargetObject="{Binding Mode=OneWay}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        <Button x:Name="NextButton" Content="Next &gt;" Width="70" HorizontalAlignment="Right"
                Visibility="{Binding CanMoveForward, Converter={StaticResource BoolToVisibilityConverter}}"
                Margin="5" Style="{StaticResource ButtonPrimaryStyle}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ic:CallMethodAction MethodName="NextStep"
                                         TargetObject="{Binding Mode=OneWay}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
 
    </StackPanel>
 
</Grid>

In my View, I bind the Content property of RadTransitionControl to the EmployeeSetupState from my View Model.  The transitions happen each time the state change occurs.  The data triggers control what view displays depending on the current employee setup state.  In the data triggers I use the ChangePropertyAction to set the Visibility of the User Controls.  This separates my View Model code to only determine and set the state of the setup process and my View handles the display.

Tagged with:
Mar 23

I thought that it would be a good blog post to outline some of the Azure limitations  and considerations that I have come across while working with Azure.  Keep in mind that this list is put together in March of 2011 and Azure is constantly changing.

1.  Long running queries or single transactions:  Currently Azure will kill any connections with queries that execute over 30 seconds.  Since you may share the server with others, Azure has to make sure that your query doesn’t eat up all the resources.  This same logic applies to single transactions.

2.  Support for SSRS:  Currently there is no support for SSRS in Azure, but there is word that it is coming soon.

3. Database backups:  Currently there is no support for database backups, but there are work arounds that allow you to backup to blob storage.

4.  Support for A/D (Active Directory):  There is now support for Windows Azure Connect (currently in beta) , which provides connectivity between on-premises and Azure resources.

5.  Support for FILESTREAM Data type:  This data type is currently not supported in SQL Azure.  A work around would be to store a path to the blob storage.

6.  Database encryption:  Database encryption is currently not supported.

7.  Database transaction log:  There is no way to view transaction logs.

8.  Database Size Limitation:  The current database size limit is set at 50 Gig.  There are other storage optionsAzure Blob Storage, Azure Table Storage, and Azure Queue Storage.

9.  SQL Jobs: There is no SQL Agent in SQL Azure.  An alternative would be to utilize a Worker Role.

Tagged with:
Nov 15

I had a stored procedure that accepted a comma delimited string of id’s as a parameter. My source was a generic list of "Employee" objects from which I had to get the id’s and create a comma delimited string.

image

To accomplish this I used a LINQ Aggregate Query:

  1. Dim employees As New List(Of Employee)
  2.  
  3. Dim e1 As New Employee() With { _
  4.     .EmployeeId = Guid.NewGuid, _
  5.     .FirstName = "John", _
  6.     .LastName = "Smith", _
  7.     .Position = "Engineer"}
  8.  
  9. Dim e2 As New Employee() With { _
  10.     .EmployeeId = Guid.NewGuid, _
  11.     .FirstName = "Bob", _
  12.     .LastName = "Johnson", _
  13.     .Position = "Business Analyst"}
  14.  
  15. employees.Add(New Employee() with
  16.  
  17. Dim employeeIds As String = _
  18.         employees.Select(Function(x) x.EmployeeId.ToString()) _
  19.                     .Aggregate(Function(y, z) y & "," & z)

In the example above, I used a comma as my separator.

Tagged with:
Sep 19

In my previous post I described a performance issue I ran across due to a large amount of ViewState.  Now I will discuss some possible solutions.

To fix this issue I decided to store the ViewState in the Session, by overriding a PageStatePersister property to return SessionPageStatePersistor. The default page state persister is a HiddenFieldStatePersister, which stores ViewState as a hidden Base64-encoded string on the page.  To read more about the PageStatePersister, see the following MSDN documentation.

Code Snippet
  1. Protected Overrides ReadOnly Property PageStatePersister() As PageStatePersister
  2.     Get
  3.         Return New SessionPageStatePersister(Me)
  4.     End Get
  5. End Property

This functionality can be implemented as needed for each page.  I implemented above code only for the few pages that were performing poorly and got the following results:

    • From 143K per postback to 13k per postback
    • From 188K per postback to 2k per postback
    • From 700k per postback to 1k per postback
    • From 244K per postback to 1k per postback

To implement this functionality application wide, override PageStatePersister in the base class for all your pages.  This does place a larger load on the web server, so make sure that this is a right solution for you.

As a long term fix, I plan on going through the screens and disabling ViewState for controls that don’t need it. Since majority of controls do not need ViewState enabled, this should minimize the size of the ViewState.

Tagged with:
Aug 31

I ran into a performance issue with an ASP.Net website that was experiencing a slow down on some of the data heavy screens.  I was not able to recreate this performance issue from my office, but it was very noticeable at the client site.  The pages that were extremely slow were doing a significant number of postacks within AJAX Update Panels.

After some research, I was able to narrow down the cause of this issue to be related to the following:

    1. The internet connection at the client site
    2. Number of postbacks
    3. Size of the ViewState

I was able to rule out the performance of the SQL Server and the Web Server since I was not able to reproduce the issue from my office. 

After testing the bandwidth at the client site, it appeared that their upload bandwidth was low and highly utilized.  The application was doing several postbacks on most utilized screens.  The AJAX Update Panel enhanced user experience by doing partial updates to the screen, therefore minimizing the flicker, but it also caused performance issues since each request to the server was a full ASP.Net postback.

To determine the size of each postback I used a Fiddler to record my HTTP traffic.  Fiddler can be downloaded for free here

After recording the traffic, I looked at the “TextView” of the request in Fiddler to determine the size of my postback. I did this for all slow performing screens. The size of the postback for each of the slow performing screens was as follows:

    • 143K per postback
    • 188K per postback
    • 700k per postback
    • 244K per postback

These are fairly large and can eat up the upload bandwidth quickly.  At this point I could either re-work these screens to eliminate these postbacks or find a way to minimize the size of my ViewState on these pages.

I will discuss my solution to this issue in the Part 2 of this post.

Tagged with:
Jun 13

Telerik controls version 2010.1.422.1040

I recently took over a Silverlight Telerik scheduler which was having an issue with displaying appointments on a resource view.   The only way I could get appointments to display is if “DisplayEmptyGroup” property on the scheduler was set to true.  All the appointments were assigned to a resource, but would not display on the scheduler.

The issue was the assignment of the resources to appointments.  The appointments were loaded and added to the Telerik appointment collection.  Then each appointment in the collection was looped through and assigned to the resource.  So as the appointments were added to the collection, they defaulted to an empty resource group since it was not yet assigned to the resource.  For some reason, since the empty group is not displayed (“DisplayEmptyGroup”  set to false), the appointments did not show up on the scheduler when the resource was eventually assigned to the appointment.

To fix the problem, I assigned the resource to an appointment before adding it to the collection.  Problem solved!!!

Tagged with:
Jun 12

I was experiencing some performance issues in my Silverlight application and got it narrowed down to the mapping of the domain objects.  After running SQL profiler and doing some research I figured out that it was due to Linq lazy loading.

As an example if I have the following data structure:

Employee_EmployeePosition

I would have an “EmployeePosition” domain object and an “Employee” domain object.  I will use the following Linq statement to bring back all Employee Positions:

  1. using (var dc = new DataClasses1DataContext())
  2. {
  3.     var postiions = dc.EmployeePositions.ToList();
  4. }

Linq lazy loading is enabled by default, so by executing the above query Linq will only bring back Employee Positions.  If I am only looking for Employee Positions everything works as expected.  The issue appears if I want to bring back the Employee information for each position.  Since I have a foreign key relationship between “Employee” and “EmployeePosition”, my dbml has “one to many” association between them.  This allows me to write the following mapping to my object that I return to my Silverlight application:
  1. var myEmployees = postiions.Select(x => new EmployeeWithPosition
  2.                     {
  3.                         FirstName = x.Employee.FirstName,
  4.                         LastName = x.Employee.LastName,
  5.                         Position = x.Position
  6.                     }).ToList();

When executing above code, there is a separate call made to the database to get the “FirstName” then another call to get the “LastName” for each of the “EmployeePosition” objects due to LINQ lazy loading (default).  So if I have 10 employee positions, there are 20 additional calls made to the database.

There are a few solutions to solve this issue:

    1. Disable lazy loading for the entire dbml file. 
    2. Specify “DataLoadOptions” on the Data Context.  This is a valid option if you do not re-use the Data Context.
    3. Use projection to load only necessary data.

The best option for my situation was to use projection to load my data.  To do this I extended my existing Employee domain object by creating a partial “Employee” class and adding a string “Position” property.  Then I used projection to load my data to the Employee domain object.

  1. using (var dc = new DataClasses1DataContext())
  2. {
  3.     var myEmployees = dc.EmployeePositions.Select(x => new Employee
  4.     {                    
  5.         FirstName = x.Employee.FirstName,
  6.         LastName = x.Employee.LastName,                    
  7.         Position = x.Position
  8.     }).ToList();
  9. }

When I executed above code I got the following run-time error:

Explicit construction of entity type ‘Employee’ in query is not allowed.

After doing a little research I discovered that projection to a domain object is not allowed. As a work around, I used my “EmployeeWithPosition” custom object which only contains properties that I am interested in from the “Employee” and “EmployeePosition” domain objects to project my data.

  1. using (var dc = new DataClasses1DataContext())
  2.             {
  3.                 var myEmployees = dc.EmployeePositions.Select(x => new EmployeeWithPosition
  4.                 {                    
  5.                     FirstName = x.Employee.FirstName,
  6.                     LastName = x.Employee.LastName,                    
  7.                     Position = x.Position
  8.                 }).ToList();
  9.             }

Tagged with:
Jun 05

Recently I upgraded our Silverlight 3 project with WCF services to Visual Studio 2010 Silverlight 4.  Overall the upgrade went smoothly with a few glitches.  Following are some basic steps:

  • Install Blend 4 (if using blend references)
  • Install Silverlight 4 toolkit
  • Run the Visual Studio conversion wizard
  • Update broken references
  • Change all Silverlight projects to target Silverlight 4 in the project properties
  • Delete all WCF references and re-add them
    • When adding a service reference, choose “Reuse types in referenced assemblies" and select specific assemblies instead of the "Always generate message contracts" option.

WCFConfigureService If attached to source control, you may need to name newly added references differently or re-name existing references before deleting.

After running the solution through the conversion wizard I was getting several errors with the WCF services.  I tried removing and re-adding the services several times with the “Always generate message contracts” option selected, which worked fine with Silverlight 3 in Visual Studio 2008.  By selecting the option to reuse types and checking the specified assemblies, I was able to resolve my issue with WCF in Visual Studio 2010.

Tagged with:
Apr 22

After doing a database move for Microsoft CRM 4 to a separate server we were experiencing issues with the CRM Asynchronous Service which is responsible for processing asynchronous jobs like the workflows. The cause for the issue was the service dependency on MSSQLSERVER.   To resolve the issue I had to perform the following registry  change to remove the dependency.

  1. Run the “regedit” command to open the Registry Editor
  2. Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSCRMAsyncService
  3. Delete the Value (MSSQLSERVER) for the “DependOnService” Name
  4. Restart the server

The service should come up running after the restart.

Tagged with:
preload preload preload