So far I have worked on 3 USD implementations and multiple CCA projects as well. One of the most common requirement for almost all these projects is “Validate/Verify customer”. During an Incoming/out going call the first thing majority of the call centers do is “checking” whether he/she is the right customer.
In all the projects we have gone through “custom hosted controls” to achieve this functionality. When I started working on my Notification forms post it self I got this thought that, can I replace all my custom controls created so far? And the first step of it happened today :), I’m able to replace my Custom control for Customer validation.
Here is how the output of the form looks like and believe me we are not going to single line of c# code (except some XAML) and is 100% configurable solution.

So, with out any further delay, lets get into the configurations required for this.
NOTE: I’m assuming by this time all my readers would have had good understanding on what is Hosted controls, Actions, Action calls and events and so I’m not showing how the Screen looks like for each of these action calls I’m creating :). If you are not, I would highly recommend you to go through MSDN & Neil’s blog to understand some basics of it at the first place.
- Create a new Notification Form(refer how to do so over here) with the following details.
Field value Remarks Name Validation If you want you can change it, but remember to use the same Name any where else we are referring further below Order 100 Markup Given below… <Border xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:CCA="clr-namespace:Microsoft.Crm.UnifiedServiceDesk.Dynamics;assembly=Microsoft.Crm.UnifiedServiceDesk.Dynamics" xmlns:Converters="clr-namespace:USDConverters;assembly=USDConverters" BorderBrush="Black" Background="DarkGray"> <Grid Height="400" Width="350" Margin="3" Background="White"> <Grid.Resources> <Style TargetType="TextBlock" x:Key="DefaultTextBlock"> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <Style TargetType="TextBlock" x:Key="HeaderText" BasedOn="{StaticResource DefaultTextBlock}"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Margin" Value="5"/> </Style> <Style TargetType="Border" x:Key="GridRowBorder"> <Setter Property="Grid.ColumnSpan" Value="3"/> <Setter Property="Margin" Value="2"/> <Setter Property="CornerRadius" Value="3"/> <Setter Property="Background" Value="#F0F0F0"/> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="BorderThickness" Value="1"/> </Style> <CCA:CRMImageConverter x:Key="CRMImageLoader" /> <Converters:CommandParameterConverter x:Key="CommandParameterConverter" /> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="20" /> <RowDefinition Height="50" /> <RowDefinition Height="*" /> <RowDefinition Height="40"/> </Grid.RowDefinitions> <Grid Background="#444444" Grid.Row="0" Height="auto"> <Grid.ColumnDefinitions> <ColumnDefinition Width="6*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <TextBlock Foreground="White" Grid.Column="0" Margin="9,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" TextWrapping="Wrap" FontFamily="Calibri"> <Run Text=":: Customer Verification for [[$Context.fullname]+]::" /> </TextBlock> </Grid> <Grid Grid.Row="1" Height="auto"> <TextBlock Margin="5" HorizontalAlignment="Left" FontSize="30" TextWrapping="Wrap" FontFamily="Calibri"> <Run Text="Verification" /> </TextBlock> </Grid> <Grid Grid.Row="2" Height="auto" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="2*"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <!-- Add a New row definition for every validation you want to perform --> <RowDefinition Height="40"/> <RowDefinition Height="40"/> <RowDefinition Height="40"/> <RowDefinition Height="40"/> </Grid.RowDefinitions> <!--Add a new Border as shown below for every new validation row --> <Border Grid.Row="0" Style="{StaticResource GridRowBorder}"/> <Border Grid.Row="1" Style="{StaticResource GridRowBorder}"/> <Border Grid.Row="2" Style="{StaticResource GridRowBorder}"/> <Border Grid.Row="3" Style="{StaticResource GridRowBorder}"/> <!-- Holds the Header Text Block, Add a new Header text block for every vaidation --> <TextBlock Grid.Row="0" Style="{StaticResource HeaderText}" Text="DOB" /> <TextBlock Grid.Row="1" Style="{StaticResource HeaderText}" Text="PostCode" /> <TextBlock Grid.Row="2" Style="{StaticResource HeaderText}" Text="Designation"/> <TextBlock Grid.Row="3" Style="{StaticResource HeaderText}" Text="Register #"/> <!--Holds the value from the replacmenet parameter, add a new textbloc for every validation --> <TextBlock Grid.Row="0" Grid.Column="1" Style="{StaticResource DefaultTextBlock}" Text="[[Contact.birthdate_GMT]+]"/> <TextBlock Grid.Row="1" Grid.Column="1" Style="{StaticResource DefaultTextBlock}" Text="[[Contact.address1_postalcode]+]" /> <TextBlock Grid.Row="2" Grid.Column="1" Style="{StaticResource DefaultTextBlock}" Text="[[$Context.jobtitle]+]" /> <TextBlock Grid.Row="3" Grid.Column="1" Style="{StaticResource DefaultTextBlock}" Text="[[$Context.telephone1]+]" /> <!--Add a new set of Grid for Thumbs up & down, make sure you are using the same values as shown here. --> <Grid Grid.Column="2" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_DOB%3D165740000" GroupName="dob" > <RadioButton.Content> <Image Source="{Binding Source=sri_valid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_DOB%3D165740001" GroupName="dob" Grid.Column="2"> <RadioButton.Content> <Image Source="{Binding Source=sri_invalid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> </Grid> <Grid Grid.Column="2" Grid.Row="1" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_PostalCode%3D165740000" GroupName="pcode" > <RadioButton.Content> <Image Source="{Binding Source=sri_valid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_PostalCode%3D165740001" GroupName="pcode" Grid.Column="2"> <RadioButton.Content> <Image Source="{Binding Source=sri_invalid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> </Grid> <Grid Grid.Column="2" Grid.Row="2" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_Designation%3D165740000" GroupName="desg" > <RadioButton.Content> <Image Source="{Binding Source=sri_valid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_Designation%3D165740001" GroupName="desg" Grid.Column="2"> <RadioButton.Content> <Image Source="{Binding Source=sri_invalid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> </Grid> <Grid Grid.Column="2" Grid.Row="3" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_PhoneNumber%3D165740000" GroupName="phno" > <RadioButton.Content> <Image Source="{Binding Source=sri_valid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> <RadioButton Command="CCA:ActionCommands.DoActionCommand" CommandParameter="http://uii/CRM%20Global%20Manager/CopyToContext/Validation_PhoneNumber%3D165740001" GroupName="phno" Grid.Column="2"> <RadioButton.Content> <Image Source="{Binding Source=sri_invalid, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" Height="16" Width="16" /> </RadioButton.Content> </RadioButton> </Grid> </Grid> <Grid Grid.Row="3" Background="#F0F0F0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button Grid.Column="1" Height="22" Width ="120" Background="Green" Foreground="Black" Command="CCA:ActionCommands.UIIEvent" CommandParameter="SaveValidations"> <Button.Content> <Bold>OK</Bold> </Button.Content> </Button> </Grid> </Grid> </Border>
This is the main part of it which actually gives the design of it. You can change the design the way you want, but if you want to use the same and add further different validations watch the below video where I have explained all the steps involved.
Once after updating the XAML use it as the Markup in the Notification record.
- Create a New session based Popup Notification type hosted control with the following information (leave all other properties to default values)
Field value Remarks Name Validation Notification If you want you can change it, but remember to use the same Name any where else we are referring further below Component Type Popup Notification Application Is Global FALSE Unchecked - Navigate to Events section of it and add a new Event with the details
Field value Remarks Name SaveValidations Should be the SAME Name Component Type Validation Notification Should be populated automatically - Create the following action calls and Attach them to the SaveValidations Event created in the previous step
S.No Name Order Hosted Control Action Data 1 Verification_CreateRecord for DOB 10 CRM Global Manager CreateEntity LogicalName=sri_verification
sri_name=DOB
sri_Result=OptionSetValue([[$Context.Validation_DOB]+])
sri_Customer=EntityReference(“contact”, “[[Contact.Id]+]”)2 Verification_CreateRecord for Designation 20 CRM Global Manager CreateEntity LogicalName=sri_verification
sri_name=Designation
sri_Result=OptionSetValue([[$Context.Validation_Designation]+])
sri_Customer=EntityReference(“contact”, “[[Contact.Id]+]”)3 Verification_CreateRecord for Phone Number 30 CRM Global Manager CreateEntity LogicalName=sri_verification
sri_name=Phone Number
sri_Result=OptionSetValue([[$Context.Validation_PhoneNumber]+])
sri_Customer=EntityReference(“contact”, “[[Contact.Id]+]”)4 Verification_CreateRecord for Postalcode 40 CRM Global Manager CreateEntity LogicalName=sri_verification
sri_name=Postal Code
sri_Result=OptionSetValue([[$Context.Validation_PostalCode]+])
sri_Customer=EntityReference(“contact”, “[[Contact.Id]+]”)5 Close Validation Notification 100 Validation Notification Close Note that, you have to add the other action calls if you have added any further validations in your screen. Also, The Entity and the fields we have to still create in CRM which I will cover later in the post. A quick look of SaveValidations event :
Save Validations Event - One Final action call to display the Notification after loading the contact form in the session. Create the action call with the following details and add it to the Contat hosted control’s BrowserDocumentComplete Event (Hosted Controls >>Contact >>Events >>BrowserDocumentComplete)
Field Value Remarks Name Show Validation Notification Any name should be fine Order 100 Hosted Control Validation Notification Action Show Data formName = validation
top = 40
left = 30Adjust Top & Left according to your required position Condition [[$Context.InitialEntity]+]==”contact” Condition to ensure the notification opens if the session is Contact session
That’s it, we are done with the USD Validations bit of it. The left out part is, creating a new entity (which I know is a cakewalk for you all :)). Just create the entity with the following fields to suite with my above action calls.
NOTE: The publisher name I have used for Solution in CRM is “sri” (as in srikanth :)) and so, If you see my CrateEntity action calls above all the field names are “sri_”. So, If your publisher name is other than “sri”, you have to change the action calls as well.
Entity/Field | Name | Data Type | Values | Remarks |
Entity | Validation | n/a | n/a | This is the custom entity that you have to create |
Field | Name | String | Used oob Name Field | |
Field | Result | OptionSet | Value 1: Valid, Value: 165,740,000 Value 2: Invalid, Value: 165,740,001 |
New option set, I would prefer the optionset with same value, Otherwise, you have to edit the XAML as explained in the video |
Field | Customer | Customer | New Customer Data type lookup |
Download the following 2 Icons (16X16) to display the Thumbs Up & Down for Yes/No. Upload these 2 as 2 Icon web resources in to CRM with the name valid & invalid (in my case the final name of the resources looks like sri_valid & sr_invalid, as said above, if your publisher name is different then you have to adjust the XAML accordingly).
That’s it, Publish the solution and Open the USD freshly. Start a contact Session and you should be able to see some thing like below 🙂

I don’t know how exiting it is to you, but if you ask me – USD Rocks… 🙂 Unleash the potentiality of USD, share your fun/feedback to the world..
Happy USDing 🙂
This is extremely cool stuff..Thank you!!!
LikeLiked by 1 person