Reporting Services rapporten verversen vanuit een SSIS package

Een veel gehoorde wens bij gebruikers van Reporting Services is het verversen van rapporten op het moment dat er nieuwe gegevens beschikbaar zijn. Het opzetten van snapshots voor dergelijke rapporten, is niet altijd een optie omdat je niet altijd weet wanneer de nieuwe gegevens beschikbaar zijn. Omdat de nieuwe gegevens vaak met behulp van Integration Services packages worden klaargezet, zou het erg mooi zijn wanneer je het verversen van rapport snapshots zou kunnen initiëren vanuit een SSIS package. En met slechts een klein beetje .NET code, is dat mogelijk! Het voorbeeld package wat in dit artikel wordt geconstrueerd, kun je hier downloaden. Let op dat dit voorbeeld is gemaakt voor Reporting Services 2008 R2 in SharePoint integrated mode. Het voorbeeld is eenvoudig aan te passen naar een native mode omgeving of een 2005 of 2008 omgeving. Het dient slechts als voorbeeld!

Als je gebruik wilt maken van het vanuit een SSIS package verversen van report snapshots, zet je als eerste van één of meer rapporten de Data Refresh Options op Use snapshot data. Vervolgens maak je geen schedule aan voor de snapshot(s), maar je maakt alleen eenmalig een snapshot aan bij het verlaten van de pagina.

image

In een SSIS package neem je vervolgens een script task op. In de Script Task Editor klik je op Edit Script… om de benodigde code te gaan schrijven. In de Project Explorer klik je vervolgens met rechts op web references en vervolgens op Add Web Reference…

image

In de Add Web Reference dialoog die nu verschijnt, geef je URL op van het ReportService 2010 management endpoint van de Reporting Services web service. Je verkrijgt deze URL door de URL van de web service uit te breiden met ReportService2010.asmx (voor SQL Server 2008 en ouder, ReportService2005.asmx gebruiken). De URL van de web service kun je achterhalen via de Reporting Services Configuration Manager.

image

Het communiceren met de web service om te achterhalen welke diensten deze allemaal verleent, duurt enige tijd! Zodra de dialoog de gevonden diensten toont, geef je de web reference een naam, bijv. ReportService en klik je op Add Reference.

image

In de code moet je nu als eerste een using statement opnemen om de diensten van de zojuist toegevoegde web service te kunnen gebruiken. Hoe het using statement wordt opgebouwd, heb ik in onderstaande figuur proberen te illustreren. Je neemt als eerste de namespace van de script task. Omdat dit een gegenereerde namespace is, ziet die er wat raar uit. Daar voeg je de naam aan toe die je aan de web service referentie hebt gegeven.

image

Nu is het tijd voor de daadwerkelijke code die je nodig hebt om de rapporten die geconfigureerd zijn met een snapshot te refreshen. De volgende code doet dat (het voorbeeld is gemaakt voor een Reporting Services 2008 R2 omgeving gebruik makend van het ReportingService2010 management endpoint):

image

Deze code neem je als code binnen de Main methode van de script task. Als je nu deze script task uitvoert, worden alle rapporten in de gebruikte SSRS instance die geconfigureerd zijn met een snapshot ververst.

Een SSIS package met bovenstaande voorbeeld code, vind je hier. Let op dat dit voorbeeld is gemaakt voor een Reporting Services 2008 R2 in SharePoint integrated mode omgeving.

Automatic web UI test tools

Being a developer means you can get hooked on making computers work for you instead of the other way around. Our team recently figured automatic web UI test tools can make life a lot easier for testers, by taking care of repetitive tests for them. However, it is important to keep future changes in the UI in mind. These changes could make maintenance on automatic tests more time-consuming than doing the tests manually! In these first few posts, I’d like to discuss several aspects of automatic web UI tests to keep in mind. Using these criteria, we can compare a number of automatic test tools to decide which to use for automatic web UI testing. In this comparison, we have decided to require support for Selenium, a popular web browser automation tool.
Continue reading

TechDays 2012 I’m Speaking!

As the title says: I’ll be attending and speaking at the Dutch TechDays february 16th and 17th in The Hague, The Netherlands.

Currently my talk about The Charms of Windows 8 is scheduled on Friday the 17th. If you are looking for an opportunity to talk to me or one of my colleagues (Alex, Edwin and Marcel will be speaking as well) you can always drop by at our Info Support stand or try to find us strolling around.

badge_speaking

My talk will be about Windows 8 Metro Apps:

Windows 8 Metro will allow the developer to create an App that integrates with Windows 8 and with other Apps in a new immersive way. By implementing a contract that has been defined by Windows 8, the App will be able to respond to other Apps or to Windows 8. This way, the user will be able to seamlessly pass data between Apps and enjoy a consistent behavior of Apps. The user will use these contracts by either using the Apps of by using the Windows 8 toolbar that contains the so-called Charms.

In this session we’ll take a look at all the Charms and contracts currently offered by Windows 8. Their features and architecture will be explained and in a demonstration all the Charms will be added to an actual App. After this session you will understand what each Charm is for and how it can be used properly in a Windows 8 Metro App.

I hope to see you there.

Windows Phone 7 Custom ProgressBar

What appeared to be straight forward proved to be a bit more difficult than I anticipated. I wanted to create a customized ProgressBar for the Windows Phone. The ProgressBar should take any image as input and Fill the image depending on the progress indicated by the Value property.

In pictures:
image imageimageimage

So I create a class deriving from ProgressBar:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace CustomControls
{
    [TemplatePart(Name="CLIPRECTANGLE", Type=typeof(RectangleGeometry))]
    public class ImageProgressBar : ProgressBar
    {
        public ImageProgressBar()
        {
            this.DefaultStyleKey = typeof(ImageProgressBar);
        }

        public ImageSource Source
        {
            get { return (ImageSource)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageProgressBar), new PropertyMetadata(null));

        public Brush Fill
        {
            get { return (Brush)GetValue(FillProperty); }
            set { SetValue(FillProperty, value); }
        }

        public static readonly DependencyProperty FillProperty =
            DependencyProperty.Register("Fill", typeof(Brush), typeof(ImageProgressBar), new PropertyMetadata(null));

        private RectangleGeometry _clip;

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _clip = this.GetTemplateChild("CLIPRECTANGLE") as RectangleGeometry;
            this.ValueChanged += ImageProgressBar_ValueChanged;
            this.SizeChanged += ImageProgressBar_SizeChanged;
        }

        void ImageProgressBar_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateClip();
        }

        void ImageProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            UpdateClip();
        }

        private void UpdateClip()
        {
            if (_clip != null)
            {
                _clip.Rect = new Rect(0, 0, this.ActualWidth, this.ActualHeight * ((this.Value - this.Minimum) / (this.Maximum - this.Minimum)));
            }
        }
    }
}

The Source property can be used to point to the image. The Fill property points to a brush that should fill the image. The _clip points to a RectangleGeometry in the template that has to cut off a part of the fill according to the progress.

The UpdateClip adjusts the Rectangle based on the size of the progress bar and the progress indicated by the Value property.

Next up; the template:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomControls">
    <Style TargetType="local:ImageProgressBar">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ImageProgressBar">
                    <Border BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Margin="{TemplateBinding Margin}"
                            Background="{TemplateBinding Background}"
                            Width="{TemplateBinding Width}"
                            Height="{TemplateBinding Height}">
                        <Grid>
                            <Image Source="{TemplateBinding Source}"
                                    Stretch="Fill" />
                            <Rectangle Fill="{TemplateBinding Fill}">
                                <Rectangle.OpacityMask>
                                    <ImageBrush ImageSource="{Binding Path=Source, RelativeSource={RelativeSource TemplatedParent}}"
                                                Stretch="Fill" />
                                </Rectangle.OpacityMask>
                                <Rectangle.Clip>
                                    <RectangleGeometry x:Name="CLIPRECTANGLE" />
                                </Rectangle.Clip>
                            </Rectangle>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

This template is pretty straight forward except for a couple of things:

  1. The Source image is used for both the image and the OpacityMask.
  2. To bind the OpacityMask’s ImageSource to the Source property I could not use {TemplateBinding} but had to fall back to {Binding Path=Source, RelativeSource={RelativeSource TemplatedParent}}. This is probably because the TemplateBinding is not able to find its way up in the hierarchy to resolve the string/uri of the image and turn it into an ImageSource.

To use the control:

<my:ImageProgressBar Width="100"
                     Height="100"
                     Fill="Red"
                     Source="ProgressBar.png"
                     Minimum="100"
                     Maximum="200"
                     Value="{Binding ElementName=slider1, Path=Value, Mode=TwoWay}" />
<Slider Margin="0"
        Name="slider1"
        VerticalAlignment="Top"
        Minimum="100"
        Maximum="200"
        Value="125" />

I added a slider to see the progress on the Phone.

Download the code here

C# 5.0 Async explained as simple as possible :)

Welcome to another blog post! This time about the new C# Async features! There is already al lot written about these features but after reading all those posts that are already available I still had a couple of questions and not everything was clear.

In this post I will try to explain the new async features in my own style, I will try to keep it as simple and clear as possible. Let’s get started! Continue reading