Home      Algemeen     

Archief van november 2009

Gold Certified Partner

woensdag 25 november 2009

We zijn al enkele jaren met een ISV/Software Solutions competency Certified Partner van Microsoft. Sinds 26 augustus 2009 zijn we, nadat we ook de Hosting Solutions competency binnensleepten, Gold Certified Partner.

Ik kan wel zeggen dat we behoorlijk Microsoft-minded zijn. We maken gebruik van de allernieuwste Microsoft technologie. We houden onze kennis op peil door uitgebreide Microsoft trainingstrajecten (zoals bijvoorbeeld MCPD Enterprise Application Developer) en we zorgen dat we op de hoogte blijven van de nieuwste ontwikkelingen door het bezoeken van  conferenties zoals de Microsoft DevDays en VSLive!.

Ik denk dat we daarmee de behaalde titel Microsoft Gold Certified Partner ook echt eer aan doen.

alt

Geplaatst in Algemeen | Reageren | 167 x bekeken

Donkere uithoeken van .NET

dinsdag 24 november 2009

De uitdaging
Voor het bouwen van een maatwerk web-portal voor een van onze klanten, kwam ik tot de ogenschijnlijke kleine uitdaging om een stuk java-script aan te maken in C# code. Piece of cake… Totdat er een new-line in de java-script kwam te staan, die de browser niet (zomaar) slikte.

In het voorbeeld dat ik hieronder aanhaal gebruik ik het ‘OnClientClick’ event van een Button. Daar komt ter bevestiging een “Weet u het zeker” melding in te staan, alvorens de server-side event afgaat. Het OnClientClick event is eigenlijk een string property die gevuld mag worden met java-script. Voor een “Weet u het zeker” melding zou daar het volgende in kunnen komen te staan:

return confirm('Weet u het zeker.');

Als in de confirmatietekst een new-line (“\r\n”) staat, dan gaat het niet zomaar lukken. De new-line moet ge-escaped worden naar:

return confirm('Weet u het zeker.\\r\\nAlle data gaat verloren');

De eerste oplossing
In eerste instantie zegt mijn intuïtie dat ASP.NET vast ergens wel een method heeft die dit voor me doet. Zo is er de HttpServerUtility.HtmlEncode, en de HttpServerUtility.UrlEncode. Deze zijn hier echter niet voor geschikt.

In een vorig project werd het opgelost door middel van enkele string-replace aanroepen. Zie onderstaand voorbeeld:

/// <summary>
/// Build a javascript string, to be used in a javascript.|
/// </summary>
/// <param>The raw value to create a javascript string for.</param>
/// <returns>The javascript string.</returns>
private static string BuildJavascriptString(string rawValue)
{
    string escapedValue =
        rawValue
        .Replace("\\", "\\\\")
        .Replace("\'", "\\\'")
        .Replace("\"", "\\\"")
        .Replace("\r", "\\r")
        .Replace("\n", "\\n");
    return string.Format("'{0}'", escapedValue);
}

Het gebruik van deze method ziet er als volgt uit:

MyButton.OnClientClick = string.Format("return confirm({0});",
    BuildJavascriptString(confirmMessage));

De echte oplossing
Het is en blijft echter vreemd dat zoveel string-replace aanroepen nodig zijn. Het zou wellicht op te lossen zijn met een regular expression, maar zelfs dan zit ik nog op het verkeerde spoor. En zijn nu alle varianten afgedekt? Blijft dit werken in de toekomst? Dit moet toch beter kunnen!

Ergens in een donkele hoek van alle Microsoft assemblies in de GAC, staat de Microsoft.JScript assembly. Laat deze nou toevallig een method hebben die lijkt op de java-script escape method. Door de method BuildJavascriptString te vervangen door onderstaande, weet ik zeker dat ik er nooit meer naar om hoef te kijken.

/// <summary>
/// Build a javascript string, to be used in a javascript.
/// </summary>
/// <param>The raw value to create a javascript string for.</param>
/// <returns>The javascript string.</returns>
private static string BuildJavascriptString(string rawValue)
{
    return string.Format("unescape('{0}')",
        Microsoft.JScript.GlobalObject.escape(rawValue));
}

Bovenstaande method is overigens in ons framework geadopteerd, met een uitbreiding voor booleans, integers, doubles en nullables:

/// <summary>
/// Convert a value, regardless of it's type, to be used in a javascript.
/// </summary>
/// <typeparam>The type of the parameter.</typeparam>
/// <param>The value to convert.</param>
/// <returns>A javascript string which represents the specified value.</returns>
public static string ConvertValueToJavaScript<T>(T value)
{
    string valueAsJavaScriptString = string.Empty;

    if (value == null)
        valueAsJavaScriptString = "null";
    else if (typeof(T) == typeof(bool))
        valueAsJavaScriptString =
            value.ToString().ToLowerInvariant();
    else if (typeof(T) == typeof(string))
        valueAsJavaScriptString =
            "unescape('{0}')".FormatInvariant(
            Microsoft.JScript.GlobalObject
                .escape(value as string));
    else
        valueAsJavaScriptString = Convert.ToString(value,
            CultureInfo.InvariantCulture);

    return valueAsJavaScriptString;
}

Java-script syntax verifiëren met C#
In diezelfde donkere uithoek zit ook een java-script compiler, die run-time gebruikt kan worden om java-script te complileren en verifiëren. Hiermee is het mogelijk om een unit-test te schrijven, die alle java-script bestanden opzoekt in het project, en verifieërd. Maar voor deze vonst gaan de credits naar Mads Kristensen, zie zijn blog-post: Verify JavaScript syntax using C#

Geplaatst in .NET | Reageren | 423 x bekeken

Win ppprrrijzen!

dinsdag 17 november 2009

We zijn nu bezig met het opzetten van een sinterklaas actie voor onze payroll-krachten.
Hierbij kunnen ze mooie prijzen winnen. Tenminste: doe mij ook maar een 5 daagse vliegreis voor 2 personen naar Barcelona. Als dat er voor mij niet in zou zitten zou ik toch ook wel blij zijn met een van de Bol.com cadeaubonnen.

Het is de bedoeling dat de prijzen via een soort van digitale tombola verloot worden onder de deelnemers, en aan mij de taak om dit op de Payroll Portal te implementeren.

Omdat ik me voor zou kunnen stellen dat er in de toekomst vaker van dit soort acties plaats zullen vinden, besloot ik geen wegwerp oplossing te maken, maar eentje die herbruikbaar is voor meerdere acties.

Deze actie is bedoeld voor payroll-krachten, maar wellicht is een volgende actie ook voor opdrachtgevers. Het systeem moet hier dus mee overweg kunnen. Verder moet de winkans variabel ingesteld kunnen worden zodat, afhankelijk van het aantal deelnemers, de prijzen zo evenredig mogelijk verdeeld worden. En niet geheel onbelangrijk moet door Driessen een lijst met winnaars en hun prijzen gemaakt kunnen worden.

Technisch gezien is het allemaal compact en eenvoudig. Ik werk met een deelnametabel waar payroll-krachten en opdrachtgevers die deelnemen in worden gelogd. Daarmee kan ik ook controleren of iemand al deelgenomen heeft. Verder hebben we natuurlijk een prijzentabel waar een omschrijving van de prijs in staat, of het de hoofdprijs is, of (en door wie) de prijs gewonnen is. Voor de overzichtslijst van winnaars heb ik een view tegen beide tabellen gebouwd die, naast de gewonnen prijs, ook de NAW gegevens van de deelnemer erbij pakt zodat er contact opgenomen kan worden.

De kansgenerator is alles behalve rocketsience, het is bijna lachwekkend hoe eenvoudig hij is, maar hij spreidt de kansen wel eerlijk. Dat is natuurlijk het belangrijkste.

/// <summary>
/// Calculates if a prize is won using the winchance factor defined in the settings table
/// </summary>
/// <returns>True if a prize is won</returns>
private static bool CalculateIfPrizeIsWon(Core core)
{
    // Get the win chance factor from the settings table
    Settings<EnmSettingsSectionsFldName, EnmSettingsKeysFldName> settings =
        new Settings<EnmSettingsSectionsFldName, EnmSettingsKeysFldName>(core);
    int winChanceFactor =
        settings.GetValue(EnmSettingsSectionsFldName.V1oPayrollPortal,
        EnmSettingsKeysFldName.V10oCampaignWinChanceFactor,
       defaultWinChanceFactor);
    int participationCount =
        (int)core.DataHandler.ReadValue(“srvGetCampaignWinFactor”);
    // If the participant’s number is the winning number, a prize is won!
    bool prizeWon = (participationCount % winChanceFactor == 0);

    return prizeWon;
}

Behoorlijk recht toe recht aan dus.
De settings class en core zijn onderdelen van ons framework die me een hoop werk uit handen nemen als het gaat om data access en het gebruiken van settings e.d.

Ik heb er inmiddels een paar uurtjes ingestoken in het totale mechaniek en het werkt goed. Omdat het een permanent karakter heeft heb ik gisteravond wat tijd besteed aan het bouwen van de nodige unittests voor het valideren van de deelnemers en het loggen van deelnames en gewonnen prijzen. Het werkt als een trein. Vanavond nog wat werk afronden aan de unittests. Daarna kan ik beginnen aan de UI. Daar is mijn DTP-Collega Hans al een paar mooie ontwerpen voor aan het maken.

Ik denk dat we lekker op tijd klaar zijn, zodat zaterdag de actie van start kan gaan. Ik ben benieuwd naar de reacties.

[Edit]
Bij de unittests die ik inmiddels voor de bovenstaande code heb geschreven bleek dat het principe wel klopt, maar dat het bijvoorbeeld goed kan zijn dat bij een winkans van 1 op 50, bij 5000 passes de ene keer niemand wint en de andere keer 300 mensen.  On the long run werkt het wel, maar voor het doel waar wij het voor willen gebruiken is het niet zeker genoeg dat de prijzen er ook daadwerkelijk uit gaan.

Om te kunnen garanderen de prijzen er uit gaan is de code nu aangepast naar een modulus berekening, wat overeenkomt met ‘iedere zoveelste beller wint’.

/// <summary>
/// Calculates if a prize is won using the winchance factor defined in the settings table
/// </summary>
/// <returns>True if a prize is won</returns>
private static bool CalculateIfPrizeIsWon(Core core)
{
    // Get the win chance factor from the settings table
    Settings<EnmSettingsSectionsFldName, EnmSettingsKeysFldName> settings =
        new Settings<EnmSettingsSectionsFldName, EnmSettingsKeysFldName>(core);
    int winChanceFactor =
        settings.GetValue(EnmSettingsSectionsFldName.V1oPayrollPortal,
        EnmSettingsKeysFldName.V10oCampaignWinChanceFactor,
        defaultWinChanceFactor);
    int participationCount =
        (int)core.DataHandler.ReadValue(“srvGetCampaignWinFactor”);

    // If the participant’s number is the winning number, a prize is won!
    bool prizeWon = (participationCount % winChanceFactor == 0);

    return prizeWon;
}
Geplaatst in Algemeen | Reageren | 173 x bekeken

Visual Studio 2010 / Team Foundation Server 2010

maandag 9 november 2009

Om straks vlekkeloos over te kunnen stappen van Visual Studio 2008 en Team Foundation Server 2008 naar de 2010 versies van deze producten ben ik de afgelopen 2 weken bezig geweest met het inventariseren en testen met de Beta 2 release van beide producten.

Visual Studio

Ik moet zeggen dat het er allemaal erg goed uit ziet. Ik had wel liever gezien dat ze tijd hadden gestoken in bijvoorbeeld een multithreaded compiler dan om de hele UI in WPF te gieten maar ach, het gaat vlot genoeg.

Buiten natuurlijk de language support voor C# 4.0 zijn er toch 3 nieuwe zaken die er voor mij echt uitspringen in deze versie van Visual Studio.

Run Impacted Tests
Een hele welkome toevoeging op Visual Studio Team System (ik gebruik op dit moment beta 2 van de Ultimate edition) is de ‘Run Impacted Tests’ feature. Ik heb er even mee geëxperimenteerd en het werkt fantastisch!
Na een build bekijkt visual studio welke unittests (direct of indirect) geraakt worden door de code die gewijzigd is.  Vervolgens kun je ervoor kiezen om alleen de ‘Impacted Unittests’ te draaien. Zo weet je zeker dat je geen gerelateerde unittests over het hoofd ziet, zonder alle unittests te hoeven draaien.

Intellisense
De intellisense is ook wat intelligenter geworden door een contains filter op het gedeelte van je invoer te zetten. Een member hoeft dus niet langer te beginnen met je invoer.

Intellisense2008 �
Visual Studio 2008

Intellisense2010
Visual Studio 2010


Code Analysis

Er zijn bovendien een hoop nieuwe Code Analysis rules bijgekomen die voor ons een zeer welkome toevoeging zijn op de bestaande set rules en onze custom rules. Aan 90% van de nieuwe rules voldeden we al zonder het in de gaten te hebben. 5% van de nieuwe rules is bij ons eigenlijk niet van toepassing. De overige 5% van de nieuwe rules zijn wel in lijn met onze guidelines, dus die zouden feitelijk geen meldingen moeten geven. Maargoed, we zijn allemaal mensen dus er kan wel eens wat doorheen glipppen. Het aantal meldingen die hierdoor ontstaan is dusdanig beperkt dat we toch wel trots op onszelf kunnen zijn. Deze gaan we dus aanpakken en oplossen.

 Ook het nieuwe ‘Ruleset’ concept dat met Visual Studio 2010 geïntroduceerd wordt is zeer welkom. Dit helpt om zelf vaste sets te maken waar de code in projecten aan moet voldoen, zonder dit steeds op ieder nieuw project handmatig een voor een in te moeten stellen. Ook is een ‘minimium requirement’ ruleset op te geven bij de Check-In policy van Team Foundation server, wat ook enkele onhebbelijkheden uit het verleden opheft.

 

Team Foundation Server

Team Foundation server is eenvoudiger te beheren en biedt tools om aan Team Project inrichting te sleutelen zonder Visual Studio daarbij nodig te hebben.
TFS Web Access zit nu geintegreerd in de Team Foundation installatie, maar als ik zie wat er allemaal voor ‘neat features’ beschikbaar zijn gekomen direct op de Project Portal (zoals het beheren van de User Stories en Tasks) denk ik niet dat TFS Web Access nog nodig is. Team Foundation Server is nu toch wel volwassen te noemen.

Bij Driessen valt met de komst van Team Foundation Server 2010 het doek voor de Scrum project template van Conchango die we tot nu toe gebruikten voor project planning. De MSF for Agile project template dekt de lading om volgens het Scrum principe te werken ruimschoots.
Ik verwacht dat ook onze product owners hier op korte termijn goed mee uit de voeten kunnen.

capacity overview
Sprint Planning met Excel in Team Foundation Server 2010. Even wennen maar het werkt toch wel erg lekker!
Een goed overzicht met de workload op iedere developer. Marco blijkt wat teveel hooi op zijn vork te hebben genomen, dus moet er  wat werk van Marco naar de andere developers gezet worden.

 Al met al dus genoeg om naar uit te kijken. Ook de proefconversies van onze projecten die ik tot nu toe heb gedaan zien er goed uit. We wachten in spanning af tot Q1 2010.

Geplaatst in .NET, TFS | Reageren | 389 x bekeken


Dit is Driessen
Werken bij Driessen
Gratis Magazine