Skip to content
/

These days JSON is used a lot. For storing data, for storing settings, for describing other JSON files and often for transporting information between server and client using DTO’s (Data Transfer Objects).

Recently I was monitoring the data transferred from one of my own Web API controllers to a mobile app. I discovered the amount of data transferred was way more then expected. This inspired me try to reduce the size of the transferred data. In this and following blog posts I will describe the different options you can use and combine.

You can download the source code at the end of my article.

These days JSON is used a lot. For storing data, for storing settings, for describing other JSON files and often for transporting information between server and client using DTO's (Data Transfer Objects).

When using an Azure Mobile App Service or ASP.NET Web API you will see that JSON is the default format to transport data. When running apps on a PC's with a fixed internet connection data size might not be a hot topic. But for apps on mobile devices, possibly using slow, limited, or expensive connections you want to save on the amount of data that is transferred.

Recently I was monitoring the data transferred from one of my own Web API controllers to a mobile app. I discovered the amount of data transferred was way more then expected. This inspired me try to reduce the size of the transferred data. In this and following blog posts I will describe the different options you can use and combine.

You can download the source code at the end of my article.

Part 1: Default Value Handling

I created an ASP.NET Web API controller to demonstrate the default behavior. The default controller returns two objects with data, some properties are empty.
A GET request to http://reducejsontraffic.azurewebsites.net/api/default returns:

[
    {
        "AString": null,
        "AnInt": 0,
        "Fourteen": 14,
        "ANullableByte": null,
        "AStringArray": null,
        "NoUri": null,
        "SomeUri": "http://reducejsontraffic.azurewebsites.net/api/",
        "TheDate": "2015-11-05T17:11:29.0809876+00:00",
        "AnEmptyDate": "0001-01-01T00:00:00",
        "AFixedDate": "2015-07-02T13:14:00+00:00",
        "SingleObject": null,
        "SomeEmptyObjects": [],
        "SomeObjects": [
            { "ADouble": 0 },
            { "ADouble": 3.14 },
            { "ADouble": 1.23456789 }
        ]
    },
    ...
]

(formatted for readability)

As you can see every property is present, despite it doesn't have a real value.

In ASP.NET Web API Microsoft has chosen to use the JSON.net serializer. The serializer has a setting called DefaultValueHandling which is set to Include by default. To quote the documentation:

Include members where the member value is the same as the member's default value when serializing objects. Included members are written to JSON. Has no effect when deserializing.

And we can confirm this is the case when we look at the result from the first example.

If a property already gets the default value when deserializing, why would we want to transport that value anyway?

Changing the Default Value Handling

Another option for DefaultValueHandling is Ignore (and for the serializing part IgnoreAndPopulate acts the same). The documentation states:

Ignore members where the member value is the same as the member's default value when serializing objects so that it is not written to JSON. This option will ignore all default values (e.g. null for objects and nullable types; 0 for integers, decimals and floating point numbers; and false for booleans). The default value ignored can be changed by placing the DefaultValueAttribute on the property.

So when we set this option properties with default values will be removed from the data transferred.

The documentation also mentions the DefaultValueAttribute. So we can describe a different default for a property.

[DefaultValue(14)]
public int Fourteen { get; set; }

Now the property Fourteen will only get serialized when its value is not 14.

I created a second controller with the modified setting. This controller demonstrates this new behavior.
A GET request to http://reducejsontraffic.azurewebsites.net/api/defaultvaluehandling returns:

[
    {
        "SomeUri": "http://reducejsontraffic.azurewebsites.net/api/",
        "TheDate": "2015-11-05T17:30:02.3206122+00:00",
        "AFixedDate": "2015-07-02T13:14:00+00:00",
        "SomeEmptyObjects": [],
        "SomeObjects": [
            { "ADouble": 0 },
            {},
            { "ADouble": 1.23456789 }
        ]
    },
    ...
]

(formatted for readability)
That's quite a reduction! But are all values recovered after deserialization?
Yes, if we didn't use the DefaultValueAttribute anywhere in our DTO it will work right away. Otherwise we will need to tell the serializer explicitly we want to populate the default values on deserialization using the same DefaultValueHandling setting we used on serialization.

I wrote a small console app as a client to show you everything is restored correctly.
When we look at the watch in the debugger we see all properties not present in the transferred data are populated with either null or their correct default value.
Visual Studio Watch showing a deserialized object with default value handling

Conclusion

In this example we managed a reduction of 41%.
Of course the reduction depends heavily on how often default values are part of your transferred data. But it's an easy diet on transferred data that the other side can reconstruct on itself.

Source code

You can download my Reduce Json Traffic sample project on GitHub.

Filed under C#
Last update:
/

My PC just got upgraded to the latest Windows 10 Insiders build (slow ring, build 10565) and suddenly a couple of VM's were missing from the Hyper-V Manager. I first suspected the security settings on the directories were the problem, but my changes didn't fix anything. After browsing around the internet I found a couple […]

My PC just got upgraded to the latest Windows 10 Insiders build (slow ring, build 10565) and suddenly a couple of VM's were missing from the Hyper-V Manager.
I first suspected the security settings on the directories were the problem, but my changes didn't fix anything. After browsing around the internet I found a couple of fixes that might help you if you have the same problem.

Save your machine

The post Windows 10 Preview - VMs Missing In Hyper-V Manager by Rhoderick Milne shows he was still able to see the Virtual Machines using PowerShell.
He got the Virtual Machines to show up again after saving them from the command line:

Get-VM | Where { $_.State –eq "Running" }  | Save-VM

Get a heartbeat

Although he could see them again in the Hyper-V Manager, some were stuck when starting up.
The problem is the integration service is reporting a corrupt heartbeat. He fixed this by disabling the heartbeat service for these machines.

Get-VM  | Where { $_.Heartbeat -eq "OkApplicationsUnknown" } |
                                              Disable-VMIntegrationService Heartbeat

Adjust the registry

The command were not sufficient for my situation. The VM's were still missing.
Then I ran across the article PSA: Missing Hyper-V VMs on Windows 10 - Build 10547 by Ben Armstrong.
He indicates that it's a registry problem in this build of Windows.

Set-ItemProperty
           -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization"
           -Name "CurrentVmVersion" -Value "6.2"
Restart-Service VMMS

Conclusion

This fixed it for me.
3 Simple PowerShell statements can rescue your VM's from oblivion on the Windows 10 preview.

/

For a Universal Windows App I wanted to implement a Pivot. Reading the guidelines for tabs and pivots by Microsoft I got inspired by the examples given. However, no code samples are supplied so there is no indication how to actually create this in your own Xaml app.

In this blogpost I will show the different steps to get the basics done and I will supply the source code for you to use.

For a Universal Windows App I wanted to implement a Pivot. Reading the guidelines for tabs and pivots by Microsoft I got inspired by the examples given. However, no code samples are supplied so there is no indication how to actually create this in your own Xaml app.

In this blogpost I will show the different steps to get the basics done and I will supply the source code for you to use.

The examples

For mobile

Example design from pivot guidelines by Microsoft

For desktop

Example design for desktop from pivot guidelines by Microsoft

The default Pivot

The default Pivot looks just like the pivot we know from Windows Phone.

<PivotItem Header="item 1">
    <TextBlock>Content 1</TextBlock>
</PivotItem>

Default Pivot in a UWP app

Adding an icon to the header

So the first step is to add an icon and do some styling. A bit lazy I used the Pivot sample from the Windows Universal Samples as a starting point.

<PivotItem>
    <PivotItem.Header>
        <local:TabHeader Label="item 1" Glyph="&amp;#xE716;" />
    </PivotItem.Header>
    <TextBlock>Content 1</TextBlock>
</PivotItem>

Icon in Pivot Header with problem

Immediatly we spot a problem. It seems the Pivot Header has a fixed height.
Browsing around I found a MSDN forum post and a Stack Overflow question about this. Both are resolved using code to adjust the height of the items.

Because we want a responsive solution where the height is not known beforehand, code is not the best option.
Lucky for us, Microsoft has added the Live Visual Tree tool in Visual Studio 2015 making it possible to debug what is happening in the app at runtime. This shows that the PivotHeaderItem has a default Style with a fixed height.

Visual Studio 2015 Live Visual Tree showing the fixed height from the default template

The problem is that Visual Studio does not have any option to edit (a copy of) this template. So we have to get it the hard way.

To find the default template of every control and style in UWP apps we have to go to the following file:

%ProgramFiles(x86)%\Windows Kits\10\DesignTime\CommonConfiguration\Neutral
                                    \UAP\10.0.10240.0\Generic\generic.xaml

Look for the PivotHeaderItem template and copy it to the Resources Dictionary for your preferred scope.
In the Style we change the Height to Auto.

<Setter Property="Height" Value="Auto" />

If the height of your pivot header can be less than 36 you will also need the modify the height of the Previous and Next buttons in the Pivot Header as these have a fixed height too. These changes are made in the Pivot Style.

<Button x:Name="PreviousButton" ... Height="Auto" ... />
<Button x:Name="NextButton" ... Height="Auto"  ... />

Create a copy of the Pivot Style

If you don’t know how to edit a copy of a Style, here are the 3 steps to follow:

  1. Select the Pivot in the Document Outline
  2. Right Click and select "Edit Template"
  3. Choose "Edit a Copy..."

Make the Pivot Header Item reponsive

First I will list how I want the header items to repond:

  • If the app is narrow, the icon is centered above the label
  • If the app is wide, the label is on the right side of the icon
  • The transition from narrow to wide is at 500

Getting this working is quite easy in UWP apps without writing any code at all.
For this we use the new AdaptiveTrigger and the RelativePanel.

We alter the TabHeader.xaml adding a RelativePanel for layout and VisualStates for the transition. Something like this:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="Narrow">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="Icon.(RelativePanel.AlignHorizontalCenterWithPanel)" Value="True" />
                <Setter Target="LabelText.(RelativePanel.Below)" Value="Icon" />
                <Setter Target="LabelText.(RelativePanel.AlignHorizontalCenterWith)" Value="Icon" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="Wide">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="500" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="Icon.(RelativePanel.AlignVerticalCenterWithPanel)" Value="True" />
                <Setter Target="LabelText.(RelativePanel.RightOf)" Value="Icon" />
                <Setter Target="LabelText.(RelativePanel.AlignVerticalCenterWith)" Value="Icon" />
                <Setter Target="RelativePanel.Margin" Value="0,0,12,0"/>
                <Setter Target="Icon.Margin" Value="0,0,0,0"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<RelativePanel x:Name="RelativePanel">
    <FontIcon x:Name="Icon"
                HorizontalAlignment="Center"
                Margin="0,12,0,0"
                Glyph="{Binding Glyph}"
                FontSize="16" />
    <TextBlock x:Name="LabelText"
                Text="{Binding Label}"
                Style="{StaticResource CaptionTextBlockStyle}"
                Margin="2,4,2,4" />
</RelativePanel>

Run the app and resize it so we see the pivot items change when it's wide enough.
Responsive Pivot Header Items

Aligning the Pivot Header Items

I like it when the pivot items are centered in the mobile layout. To achieve this we need to add the Visual States to the Pivot Style.
If you didn’t have a Pivot Style already look in the previous section how to create a copy of the Style.

We add the Visual State Group the existing VisualStateManager.VisualStateGroups in the RootElement of the Pivot ControlTemplate:

<VisualStateGroup>
    <VisualState x:Name="Narrow">
        <VisualState.StateTriggers>
            <AdaptiveTrigger MinWindowWidth="0" />
        </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="HeaderClipper.HorizontalContentAlignment" Value="Center" />
        </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="Wide">
        <VisualState.StateTriggers>
            <AdaptiveTrigger MinWindowWidth="500" />
        </VisualState.StateTriggers>
        <VisualState.Setters>
            <Setter Target="HeaderClipper.HorizontalContentAlignment" Value="Stretch" />
        </VisualState.Setters>
    </VisualState>
</VisualStateGroup>

Now the items are centered when the app is “narrow”, and left aligned when the app is “wide”.
The Pivot Header Items centered

Source code

You can download my Universal Windows Platform App sample project on GitHub.

Filed under C#, Windows
Last update:
/

I received a couple of comments on my article about making the pull-down-to-refresh work with a Windows Phone virtualizing list control. The problem was that the functionality stopped working after navigating away from the page containing the ItemsControl. Today I committed the code to GitHub to fix this issue.

I received a couple of comments on my article about making the pull-down-to-refresh work with a Windows Phone virtualizing list control.

The problem was that the functionality stopped working after navigating away from the page containing the ItemsControl.
To prevent events from triggering when the list is not in view I deregistered all events. But when the list came back in view I didn't start monitoring these events again.
Today I committed the code to GitHub to fix this issue.

Source code

You can download my Windows Phone 8 example project on GitHub.

/

Every Microsoft Dynamics CRM developer has faced this problem: How to get the entity type code for your custom entity in JavaScript. If you need the entity type code for the current form there are several supported ways to get it. But when you want the entity type code for a different custom entity, you are in trouble. The SDK has no real solution for this, and hard-coding is no option as the numbers can change per deployment.

Digging through the client side object model I found a nice, although still unsupported, treasure which works with CRM 2011 and up, including the latest installment: 2015 update 1.

Every Microsoft Dynamics CRM developer has faced this problem: How to get the entity type code for your custom entity in JavaScript. If you need the entity type code for the current form there are several supported ways to get it. But when you want the entity type code for a different custom entity, you are in trouble. The SDK has no real solution for this, and hard-coding is no option as the numbers can change per deployment.

So how do most people solve this? A popular choice is the unsupported Remote Command and Lookup service. Because of the asynchronous nature the use of a service adds a performance penalty and complexity to your code. It also seems this will break in CRM 2015 Update 1.

Digging through the client side object model I found a nice, although still unsupported, treasure which works with CRM 2011 and up, including the latest installment: 2015 update 1.

Mscrm.EntityPropUtil.EntityTypeName2CodeMap

This class contains a dictionary of all out-of-the-box entities but also all custom entities. And as it's already loaded in memory there is no performance loss.

Form JavaScript

When using JavaScript in a form the goodies are readily available:

Mscrm.EntityPropUtil.EntityTypeName2CodeMap.account
// 1

Mscrm.EntityPropUtil.EntityTypeName2CodeMap["account"]
// 1

Mscrm.EntityPropUtil.EntityTypeName2CodeMap.wv_country
// 10025

Web Resource

From a web resource just target the parent window:

window.parent.Mscrm.EntityPropUtil.EntityTypeName2CodeMap

Or if you have included the ClientGlobalContext.js.aspx, you can also use the class directly:

Mscrm.EntityPropUtil.EntityTypeName2CodeMap

Turbo Forms

With the introduction of the turbo forms in CRM 2015 update 1 you need an additional line of code to make the mapping work:

if (Mscrm.EntityPropUtil == null) {
    Mscrm.EntityPropUtil = parent.Mscrm.EntityPropUtil;
}

From entity type code to entity type name

If you want to use this map to get the entity type name from the entity type code you can use the following line of JavaScript:

Object.keys(Mscrm.EntityPropUtil.EntityTypeName2CodeMap).filter(function(key) {
  return Mscrm.EntityPropUtil.EntityTypeName2CodeMap[key] === 10025
})[0]
// "wv_country"

It's that easy!