Snelle SVN installatie met VisualSVN

28 09 2009

Een tijdje geleden heb ik op een project gewerkt met SVN voor source control.
Meestal werk je als Microsoft developer met VSS (Visual Source Safe) of TFS (Team Foundation Server) maar voor een klein project was ik best gecharmeerd geraakt van SVN tezamen met Tortoise  als client tool.
tortoisesvn_logo_hor468x64
Vooral het principe dat er geen bestanden read-only worden gemarkeerd en je lekker kunt editen, ook off-line, vond ik erg ok.
Waar ik echter tegenop zag was het installeren van een SVN server; de how-to pagina’s waren niet altijd even consistent en helder.
Maar wat is er nu (of misschien al langer, maar voor mij is het er nu): Visual SVN.
logo_visual_svn_server

Een Next, Next, Finish installatie van SVN.
Geprobeerd, en het werkt. Dus ook voor kleinere projecten of 1-mans projecten waar je source control wilt gebruiken (al is het alleen maar om een dolgedraaide designer te kunnen rollbacken) een mooie oplossing.





The Scott

26 09 2009

Hij was er, wel een van de meest bekende mensen en sprekers van- en over .Net: Scott Guthrie.
Verantwoordelijk voor een groot deel van .Net, webforms en het verhaal gaat dat hij de grote lijnen van ASP.Net MVC in een vliegtuig in elkaar heeft getimmerd.
Hij was in Engeland en Nederland, en de vrienden van DotNed hebben het voor mekaar gekregen om hem als spreker te boeken. Afas was zo vriendelijk de sessie te hosten, en het was in 1 woord geweldig.
Wat een ervaring, wat een enthousiasme, wat een drive, wat eigenlijk niet?
Daar staat dus een van de grote mensen van Microsoft voor 250 man in Nederland te vertellen over ASP.Net MVC en over Visual Studio 2010. En dan niet een standaard sales praatje of een schrale demo, maar twee keer 2 1/2 uur praten. En hoe! vol enthousiasme en plezier vertelt hij de dingen alsof hij ze pas net heeft ontdekt.
Een genot om deze man mee te maken, veel wijzer geworden en een leuke avond gehad.

IMAG0230





Ervaringen met het ASP.NET MVC framework

3 09 2009

Deel 2 over de ervaringen met het ASP.NET MVC framework

aspnetmvcpreview

Testbaarheid
Veel genoemd als voordeel en dat is zeker terecht: de testbaarheid.
Omdat de (business logica) rol van de view heel klein is ligt alle logica bij de controller of anders gezegd: als je de controller van de juiste data voorziet en de juiste actie aanroept, dan zal deze de juiste data teruggeven en ook de juiste view aanroepen. Dat is natuurlijk mooi te testen: wat een pagina uit je site doet, namelijk het posten van data (via FormPost of Get) naar een actie van een controller, kun je vanuit je testproject ook. Je hebt dus geen last van allerlei verborgen acties die nog in je view worden uitgevoerd. Een plus voor testen

Viewstate
Geen viewstate. Omdat we geen server controls hebben die allerlei state met zich mee dragen hebben we ook geen viewstate. Uitzetten kan in een gewone ASP.NET applicatie natuurlijk ook, maar de wat intelligentere server controls zoals de GridView vinden dat geen goed idee: het event model houdt er dan ook mee op. En geen view state geeft toch al gauw een fikse page size verbetering. Een plus voor filesize.

Bewuster van htmlcode
Een indirect voordeel van het werken met het ASP.NET MVC framework is dat je je veel bewuster bent van de html die je site oplevert. Van een GridView weet eigenlijk niemand wat voor html deze oplevert, en in het geval van een server control is dat ook eigenlijk niet belangrijk. Maar als je je wel van de html bewust wilt zijn, bijvoorbeeld omdat search engine optimalisatie belangrijk is, dan is dat met het MVC framework sneller het geval.

Microsoft’s versie 1.
Het verhaal gaat dat een versie 1 product van Microsoft eigenlijk niet productierijp is. In dit geval is dat in ieder geval niet zo. We hebben vanaf dag één productie kunnen draaien.

Overzicht aspx
Bij een gewone ASP.NET site staat veel code in de code behind file. Ook wordt daar veel opmaak werk gedaan, controls aangemaakt etc.
Met het ASP.NET MVC framework doe je dat allemaal in de view (de aspx / ascx files). Dat geeft soms wel een wat onoverzichtelijke pagina: het wordt al snel een mengelmoes van html tags en for-each loops die door de data heenlopen die de controller aan de view heeft gegeven. Een min voor overzichtelijkheid van de view.

Leercurve
41vsFoLZq9LEen nadeel om er mee aan de slag te gaan is zoals altijd de leercurve. Deze is bij dit framework best aanwezig, want het is niet iets dat je half kunt implementeren en het is ook niet iets dat er even naast hangt: het vervangt een redelijk deel van de ASP.NET kennis die je hebt; o.a. die van de vele server controls die ASP.NET rijk is. Zelf heb ik het boek van o.a. ScottGu gelezen (Professional ASP.NET MVC 1.0) en daarmee heb je de basis in ieder geval snel onder de knie. Een min als je morgen direct moet beginnen. 

Geen server controls
In het begin vraag je je af: waar begin ik aan. Al dat extra werk dat een server control je uit handen neemt. Maar aan de andere kant: het is ook wel vaak gedoe met die controls. Een GridView lijkt heel handig, helemaal als je de voorbeelden ziet met inline editen van data. Maar als je zelf aan de gang gaat, zonder de gesleepte SqlDataSource maar gebruik makend van je DAL, dan moet je vaak toch wel flink wat tweaken. En code als de ItemDataBound, de FindControl, de (Cells[0].Controls[0] as TextBox).Text etc. zijn ook niet altijd even handig. Conclusie: het viel eigenlijk best mee om zonder deze controls aan de gang te gaan. Een GridView is met een foreach loop ook zo opgebouwd, en als je de flow van je site in je hoofd hebt zijn de edit, delete en insert buttons ook zo gemaakt.

Geen abstractie
Het ASP.NET framework biedt een heleboel abstractie aan. De acties binnen een website zijn eigenlijk heel simpel: je doet vanuit de client een GET of een POST, en op de server kijk je welke data er mee is gekomen (via de Form data of de querystring) en afhankelijk van de pagina die wordt geladen en de data die je hebt meegekregen voer je je actie uit en bouw je een nieuwe pagina op.
De hele abstractielaag die ASP.Net daar op heeft gebouwd zoals de Postback, de button_click events als ware het een Windows applicatie, de events die op server controls afgaan: als je de overstap maakte van een windows applicatie leek het zo heel logisch, maar soms maakt de abstractie het moeilijker dan het origineel was. Van een simpele Post wordt een form_load gemaakt met een IsPostback property, een Button_click, een aantal events op een GridView, een findcontrol op de pagina, een OnChange event van een textbox, een databind() van een Repeater en wat al niet meer. Jarenlang een gegeven, maar nu met de ervaring van het MVC framework valt het wel op dat het niet alleen maar simpeler is, zo’n abstractielaag. Een plus voor de overzichtelijkheid van het ASP.NET MVC framework.

Conclusie
Conclusie is dat ik het ASP.NET MVC framework een dikke pluim geef en het volgende keer zeker weer zou inzetten bij een dergelijk project.





Aan de slag met ASP.NET MVC

17 08 2009

‘k heb net een groot project afgerond dat is gebouwd met het ASP.NET MVC framework.
Het betrof hier de herbouw van www.beurs.nl, een site waar performance een must is, SEO ook, en runtime errors en work-arounds zijn niet welkom. Oftewel: een mooie testcase voor dit nieuwe framework.

In deze post als eerste: wat is het ASP.NET MVC framework (vanaf hier genoemd: MVC)?
MVC is een pattern dat al lang bestaat en de opbouw van je applicatie opdeelt in de componenten Model, View en Controller. Hierbij komt een aanvraag of request van in dit geval een webpagina binnen bij de controller. Meestal komt er ook nog data mee in de aanvraag: bij een Get request zit dit in de querystring (www.beurs.nl/zoek/term=AEX) en bij een Post request zit het in een aparte collectie met data en bevat het de inhoud van de velden van je Form.

Het verschil met de gewone aspx pagina is dat nu niet een Page object wordt opgestart (met normaal het eerste contact in de form load, die kijkt of het een postback is etc etc) maar een Class die afgeleid is van een MVC Controller object.
Dit is direct het eerste verschil: je komt nu binnen in een apart object (de controller), terwijl je anders in een code behind van een grafisch element, een form, binnenkomt.
Deze controller (de C uit het MVC) heeft meerdere Actions in zich, die je implementeert als methode in het Controller object. Deze Actions kunnen bijvoorbeeld zijn: SaveNews, PostComment, CreateRssFeed, EditNews etc. De koppeling tussen url’s en de controller/action combinatie doe je in de Global.asax, daar zet je in dat ‘/nieuws/binnenland/AEX stijgt’ naar de controller ‘News’ moet, en naar de Action (methode) ‘news’ en dat deze een parameter van het type string heeft waar dan de tekst ‘AEX stijgt’ in wordt geplaatst.

Je voelt nu al dat dit wel gemakkelijk testbaar is, want een methode aanroepen met een parameter is iets dat je nu ook al doet in test projecten.
De Action heeft dan de kennis in zich wat hij moet doen. In dit geval moet hij de cache controleren, eventueel het nieuws uit de database halen en het toevoegen aan de cache. Deze laatste acties, het al dan niet gecached ophalen van de data, zit in je service- en datalaag. Deze twee lagen samen vormen je Model (de M uit het MVC). Je kunt het Model dus ook wel zien als je business layer gecombineerd met je data layer.

Als de controller deze data heeft opgehaald dan bepaalt hij welke view (de V uit het MVC) deze data moet gaan tonen: is de data bestemd voor een nieuwsfeed of voor een usercontrol of voor een HTML pagina of iets anders. Meestal zal het laatste het geval zijn en geeft de controller de opgehaalde data aan de View. De view ten slotte heeft de kennis in zich hoe een en ander op het scherm getoond gaat worden; welke data in welke DIV geplaatst wordt, en afhankelijk van de data welke css style erop van toepassing is. Standaard is de view een ASPX pagina die niet afleidt van het Page object maar van de Mvc.ViewPage.

cc337884_fig01

De verschillen tussen een gewoon webproject en een MVC project die het meeste in het oog springen:

  • Geen Viewstate
  • weinig tot geen SessionState
  • Eenvoudig SEO-friendly url’s
  • Geen servercontrols (DataGrid, ObjectDataSource)
  • Wel volledige controle over de gegenereerde HTML
  • Goede testbaarheid
  • Geen code behind
  • Duidelijke separation of concerns

In de volgende post: de ervaringen met het ASP.NET MVC framework.





CSS sprites

14 08 2009

Er is een onderzoek geweest dat sites met veel afbeeldingen (en daarbij tellen zeker ook achtergronden van buttons en hun mouseovers) een groot deel van de laadtijd besteden aan het 1 voor 1 laden van die afbeeldingen.
De browser haalt namelijk de html op, en komt er dan in de CSS (background: url(‘mouse.gif’) no-repeat;) of de HTML zoals de image source (<img src=”mouse.gif”) achter dat er nog een plaatje van de server afgehaald moet worden.
Bij veel afbeeldingen loopt dat aantal requests snel op, en dat geeft wel een ervaring aan de gebruiker dat er iets aan het gebeuren is, maar kan al met al wel tot 50% van de laadtijd extra kosten.
cssspriteVroeger (in internet termen dan) was het wel een must om de gebruiker te laten zien dat de pagina iets aan het doen is, maar aangezien de meeste 28K8 modems er wel zo’n beetje uit zijn, kun je ook het volgende doen:
Je neemt in plaats van allemaal kleine afbeeldingen 1 grote afbeelding, en je laat alleen dat stukje van de afbeelding zien wat je op dat moment nodig hebt.
Als je de eerste aanroep van de afbeelding bovenin je html zet, dan zijn in de rest van de pagina alle afbeeldingen al direct, zonder nieuw request, beschikbaar.





Microsoft DevDays 2009

28 05 2009

Vandaag was het weer zover, de Microsoft DevDays 2009.
devdays

Een bijna vertrouwd gezicht om Arie Leeuwesteijn de opening te zien verzorgen.

Dit jaar een best interessante keynote; niet alleen amusant maar ook informatief over The Azure Services Platform.

Daarna een hele goede presentatie van Ingo Rammer over Dynamic Data. Dynamic data is een te customizen ‘applicatie’ die voor een of meerdere tabellen in je Entity Framework een CRUD site genereert. Het genereren gebeurt runtime aan de hand van templates en je Model, dat grotendeels uit het EF komt maar waar je zelf ook aanpassingen aan kan doen. Je kunt bv van een attribuut aangeven dat het een waarde mag hebben tussen 0 en 100 en er wordt dan bij een refresh van je pagina direct een validator gegenereerd.
Mooi spul, zeker voor een admin tool of een klant die de afweging maakt van een minder tailor made applicatie tegen een lagere kostprijs. Na MS-Access is er eindelijk weer een eenvoudige datadriven oplossing van Microsoft.

Daarna een vrij technische verhandeling over production debugging. Leuk om te zien wat er allemaal mogelijk is aan monitoring, memory dumps, managed- en unmanaged memory e.d. Een leuk stukje: midden in het verhaal was er ineens een heap dump te zien met daarin o.a. een OutOfMemoryException. Het bleek dat je die niet serieus moest nemen in je diagnose omdat die er altijd in zit: als de CLR start dan wordt deze al op de heap geplaatst omdat als de CLR echt een out of memory tegenkomt, hij geen geheugen meer vrij heeft om een OutOfMemoryException op de heap te plaatsen.

Vervolgens een presentatie over ASP.Net Ajax 4.0 die nu in Beta was (of in CTP, ‘k weet niet zeker). Het kwam er eigenlijk in het kort op neer dat ze een hele grote Ajax library aan het bouwen zijn waarmee je in de client op dezelfde manier, dus niet met C# zoals in Silverlight, maar op een gelijke wijze dingen moet kunnen doen als op de server.

Het slot was van Sander Hoogendoorn met een mooie presentatie* over frameworks die niet alleen aan het einde wel trek had in een biertje (wat er overigens niet was zover ik kon zien) maar ook twee mooie uitspraken had:
Over een passend formaat framework: “Frameworks zijn er, net als pizza’s, in 2 formaten: te groot en te klein.
en over de lock-in die een framework vaak met zich mee brengt: “Frameworks zijn net als vrouwen, je kunt er niet mee leven en je kunt ze niet killen“.

Al met al een amusante dag: veel gezien en gehoord, nog wat leuke boeken gescoord en oud(e) collega’s ontmoet.

* Bij Sander spreek je eigenlijk niet echt over een presentatie maar meer over een infotainment show :)





Asp.Net MVC – AjaxOptions

27 05 2009

Ik had een mooie copy-paste actie, die helaas tot een niet te reproduceren fout leidde.
Het begon allemaal met een Ajax sectie in een MVC partial view:

<%
using (Ajax.BeginForm(“AddComment”, “Comment”, null, new AjaxOptions

{
OnComplete =“AddCommentOnComplete”,
LoadingElementId =“AddCommentLoading”,
OnBegin =“AddCommentonBegin”
UpdateTargetId = “DivAddCommentAnonymous”
 }
))
%>

  Toen wilde ik ergens anders een Ajax link maken. Ok, het is iets heel anders, maar ook daar wilde ik een set AjaxOptions meegeven. Dus… copy-paste.
Wel het LoadingElementId element weggehaald, maar de 2 events laten staan voor debug doeleinden met een alert erbij.
Maar toen de link werd uitgevoerd en de controller een partial view retourneerde, werd deze niet, zoals het hoort, netjes in de pagina verwerkt, maar kreeg ik alleen de partial view te zien, in plaats van de hele pagina.
Wat bleek de crux te zijn: de 2 OnXXX events horen natuurlijk helemaal niet bij een Link, en niet alleen horen ze er niet bij, maar als je ze er wel bij doet, dan krijg je genoemd gedrag.





Lambda expressions

14 05 2009

Ik moet zeggen, toen ik 2 jaar geleden voor het eerst een boek over Linq las en daar een heel stuk stond over Lambda expressions, dat ik halverwege wel even achter m’n oren moest krabben: wat is dat voor iets?
Maar zoals met alles, als je het meer en meer ziet ga je zelf ook wat proberen en gebruik ik nu de volgende 2 lambda’s regelmatig.
De ene is voor het selecteren van objecten uit een generic List op basis van een property van dat object, de andere is voor het ophalen van een lijst met de waardes van 1 property van die objecten (deze staat verderop in de blog ook al vermeld, maar voor de compleetheid toch nog even vermeld).

De case bij de eerste is: ik heb een lijst met keyword objecten. Deze hebben allemaal een property ‘rank’. Nu wil ik een lijst met alleen die keywords die minimaal een rankwaarde van 2 hebben. Daarvoor gebruikte ik altijd een mooie anonymous delegate die ik van m’n vriend en oud-collega René had geleerd (en het stond altijd wel biek, een anonymous delegate :-) ) :
keywords.FindAll(delegate(Keyword m) { return m.Rank >= 2; });
Met een Lambda wordt het echter dit:
keywords.FindAll(m => m.Rank >= 2)
En dat is toch ook wel mooie code vind ik.

De case bij de 2e is: ik heb nog steeds die lijst met keyword objecten. Deze hebben naast de genoemde rank ook een value. En dat is waar ik op dit moment interesse in heb: in al die values. Ik heb dus een lijst met keyword objecten, en ik wil graag een lijst met strings gevuld hebben.
De oplossing zit in de ConvertAll methode:
List<string> values = keywords.ConvertAll(z => z.Value);

ps.
ik heb nog even opgezocht wat Microsoft eigenlijk zegt over een lambda expression:
A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.





ASP.NET MVC Routing Debugger

8 05 2009

Als je net begint met het Asp.Net MVC heb je waarschijnlijk veel zaken waar je tegen aan loopt, maar 1 van de eerste is waarschijnlijk de routes: je definieert in je global.asax je routes, je opent de browser en…. daar is je view niet.
Vooral als je veel routes hebt gedefinieerd is het soms moeilijk in te schatten welke paden worden doorlopen en welke niet.
De oplossing is simpel gelukkig: een DLL toevoegen aan je project en 1 regel code aan je global.asax, en dan zie je dit:Route%20Tester%20-%20Windows%20Internet%20Explorer%20(2)_3

Je ziet een lijst met alle routes die je hebt ingegeven, en in het groen de routes die matchen met de url die je op dat moment in hebt gegeven.
Daarnaast zie je bovenin in de kleine tabel welke controller er wordt aangesproken, wel action er wordt uitgevoerd en de waardes van de eventuele parameters.

Hear hear:  http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx





Fiddler gebruik op Vista met ASP.Net site die runt op de webserver van Visual Studio (2008)

25 04 2009

Zo, dat is een hele zin…

Maar goed: stel je wilt in je site die lekker Ajax dingen doet even luisteren naar het HTTP verkeer. Je gebruikt Fiddler (in mijn geval v.2.2.2.0) en je hoort op htpp://localhost:47867/ …. niets.
De standaard oplossing is een punt (.) tussen de localhost en de dubbele punt. Dan krijg je
htpp://localhost.:47867/
Dat werkt alleen niet echt onder Vista. Niet geprobeerd maar gelezen is oplossing 2: geen localhost gebruiken maar je machinenaam. Dan krijg je
http://mydevmachine.:47867/ maar dat schijnt het niet goed te doen bij de interne webserver van Visual Studio.
De laatste mogelijkheid, en die deed het ook bij mij, was het localhost ip adres; en dan krijg je http://127.0.0.1.:47867/

En dan ziet Fiddler alles voorbij komen!





Geblokkeerde DLL

22 04 2009

Vandaag bij het runnen van een unittest kreeg ik de volgende melding:
Failed to queue test run ‘michel@AFFINNOLAPTOP 2009-04-22 09:31:21′: Test Run deployment issue: The location of the file or directory ‘C:\project\beurs\Beurs.Web\RouteDebug.dll’ is not trusted.
Even gegoogled, en de eerste hits wijzen naar een rechten probleem: CASPOL dus. Nou is CASPOL al niet snel mijn vriend, maar nu is het gewoon een directory op disk, en vroeg ik me af of het inderdaad een rechtenprobleem is.
Nu is RouteDebug.dll een dll die van een andere site afkomt, en een andere oplossing die ik vond was deze: Rechtsklik het bestand, in dit geval RouteDebug.dll, en kies voor ‘blokkering opheffen’. En dat was de truc: Windows had mijn pc ‘beter beveiligd’, maar dat had ik nu ongedaan gemaakt.

blokkeringopheffen





Sql Server databases vergelijken (freeware tool)

12 02 2009

xSQL data compare en xSQL Objectxsqllogowithstripessmall3

Deze (gebundelde) tools wil ik jullie niet onthouden.
Met deze twee tools kun je databases vergelijken, compare scripts genereren, Sql insert script data dumps maken etc. etc.
Je herkent het misschien wel, dat je bij de ontwikkeling van een nieuwe versie van je Wicked app niet helemaal hebt bijgehouden wat je aan de database hebt aangepast. Oftewel: je wilt een schema vergelijking doen.
En als je dan verschillen ziet, en je wilt de oude database updaten, dan is het ook handig als er een update script beschikbaar is.
Of een van mijn favorieten: je hebt mooie testdata in je database, en die wil je ook wel gebruiken in je testproject: je wilt een script dat je aan je database kan aanbieden om deze in een bepaalde state te brengen.
Wat deze tools ook kunnen: verschillen scripten tussen de content van 2 databases.
scriptdata2

En dan komt natuurlijk de catch :) … of toch niet…..
Je mag de versie 2 weken full gebruiken, daarna wordt het de lite versie, die gelimiteerd is aan het aantal database objecten: niet meer dan x tabellen of niet meer dan x stored procedures.
Maar die restrictie geldt niet voor Sql Express! Als je met Sql Express ontwikkelt op je lokale pc, en dat gebeurt in mijn geval nogal eens, kun je gratis de full versie gebruiken.
Of hoe ze het zelf zeggen: “Note: The (…) limitations do not apply to SQL Server Express edition. As of June 18, 2007 xSQL Software’s comparison and synchronization tools are FREE with no restrictions for SQL Server 2005 Express edition.”.

Downloaden kan hier:
http://www.xsqlsoftware.com/Product/Sql_Bundle_Schema_Data_Compare.aspx





ASP.NET Charting Control

31 01 2009

Net bezig geweest met het ASP.NET Charting Control.
‘k had wel eventjes iets nodig om te ‘grafieken’; ik heb maar eens even wat statistieken gemaakt voor mijn site.
De voorbereiding was eenvoudig: 2 downloads en je kunt aan de slag. Op de blog van Scott (zie verder) staan links naar de downloads en een link naar de sample environment. Het leuke daarvan is dat alle types grafieken staan vermeld, getoond en ook voorzien van wat sample code.
De ervaring: met wat copy-paste uit de sample code ben je zo van start. Met een half uurtje was de eerste chart gereed en na een uurtje was de 2e ook klaar en zagen ze er nog leuk uit ook:

chart1

Dus voor de volgende grafieken een ASP.NET project zal ik deze zeker gebruiken.

Hier klikken voor de blog van Scott voor de links





Barcode voor de consument: Microsoft tag

28 01 2009

We kennen allemaal wel de barcode voor zakelijk gebruik: de streepjes op een pak melk en een schrijfblok.
Iets minder bekend is de 2d-barcode: niet echt een ‘barcode’ omdat het geen ‘bars’ zijn, maar je kunt er wel lekker veel informatie op kwijt.
120px-semacode_svgJe ziet ‘m steeds vaker, helemaal als je met barcodes bezig bent er een beetje op let (ik zit op dit moment op een project bij een klant die veel met RFID en barcodes doet, dus automatisch gaat dan je aandacht meer naar verschijnselen ervan in de dagelijkse pratijk uit).

En nu komt Microsoft met ‘Microsoft Tag’. Een soort barcode, ik weet niet of het een eigen verzonnen formaat is, om commercieel te gebruiken. Bijvoorbeeld in advertenties in tijdschriften, boeken etc. maar ook op vanaf een beeldscherm is de tag leesbaar.
Je kunt in de tag een stuk tekst of een url ‘verbergen’ of ‘opslaan’. En Microsoft heeft daarbij een gratis applicatie voor op je smartphone of PDA, waarmee je met die smartphone of PDA een foto neemt van de tag, en daarna laat de applicatie je de tekst zien die ‘verborgen’ zit in de tag of hij opent internet explorer en opent de pagina die bij de url hoort die in de tag ‘verborgen’ zit.
Er hoort ook een gratis webapplicatie bij om de tags te maken, dus ‘k kon er gelijk mee aan de slag.
Dus in het kort: maak de tag, plaats hem ergens en de gebruiker neemt er een foto van en krijgt jouw info op het scherm.
Hieronder de tag om naar het 2 minuten durende demofilmpje te gaan; als je nog geen Microsoft tag gebruikt kun je ook deze url gebruiken: http://www.microsoft.com/tag/content/what/default.aspx?autoplay=y.

barcode





Jquery

23 01 2009

logo_jquery_215x53‘k moet zeggen dat ik in eerste instantie niet stond te springen om weer een nieuw soort framework: Jquery.
Het lijkt wel alsof de die dingen de laatste tijd uit elke hoek je om de oren vliegen, en dan is dit er nog eens eentje voor iets wat in de meest positieve bewoordingen nog wordt gezien als ‘een noodzakelijk kwaad’: Javascript.
Maar toen ik luisterde naar de .Net rocks uitzending met Rick Strahl over Jquery, werd ik toch wel enthousiast. Want wat bleek het te zijn: het is een meer een developer aid dan een framework dat is verzonnen om iets nog correcter te maken qua architectuur standaarden.
Bijvoorbeeld: een korte notatie om elementen uit de DOM te halen, code om met WCF services te praten, extension methods om bewerkingen uit te voeren op geselecteerde elementen, grafische effecten, een eenvoudig model voor event handlers en many more. En wat mij persoonlijk altijd stoorde aan Javascript: had je iets moois gebouwd dat goed werkte in IE6, werkte het weer niet in IE7 en Firefox, of wel in Firefox maar niet in IE voor de Mac of Safari.
En ook dat is iets wat JQuery oplost: in dit framework of library zit de code die de browserverschillen voor je heeft uitgezocht en opgelost, en dat is voor mij al een reden om er mee aan de slag te gaan.
Geeft dit stukje je hoop? Download dan gewoon even de uitzending, brand ‘m op CD en luister ‘m in de auto op weg naar je volgende Javascript klus, in de sauna of tijdens het sporten.

http://www.dotnetrocks.com/default.aspx?showNum=351





Lambda expressions op de generic list

23 12 2008

Sinds C# 2.0 hebben we generic lists. Ik gebruik ze vrij vaak, want je kunt er zo lekker door for-eachen en het is strong typed etc.

Maar de methodes op zo’n list zoals Find, Exists, ConvertAll etc. nemen als parameter altijd een Predicate. En ik moet zeggen, zo’n predicate die je dan implementeert door een anonymous delegate, het was toch altijd weer even zoeken hoe je het ook alweer typt.  Zoals als je een lijst met objecten hebt van het type MissingOrderregel. Dat type heeft een veld RecordId en dat is nu precies het enige veld waarin je bent geïnteresseerd: je wilt eigenlijk alleen een lijst met RecordId waardes. Een manier is natuurlijk om met een foreach door de lijst heen te wandelen en dan van elk MissingOrderregel object de RecordId te nemen en die in een nieuwe lijst met Int32’s te stoppen.
Maar het kan ook anders:

Met een delegate doe je het zo:
List<int> recordids = regels.ConvertAll(delegate(MissingOrderregel z) { return z.RecordId; });

Maar, met de nieuwe mogelijkheid van Lambda expressions kun je ook dit typen:
List<int> recordids = regels.ConvertAll(z => z.RecordId);
Op de MSDN pagina staat dat je het moet lezen als ‘goes to‘, dus ‘z goes to z.RecordId‘.

 En zo kun je met die Lambda expressions ook gemakkelijk hele Lists casten van het ene type naar het andere (in dit voorbeeld wordt een hele List met Child objecten gecast naar een lijst met Parent objecten):
List<Parent> parents = childs.ConvertAll(z => (Parent)z);
z goes to z casted to a Parent type‘.





Top 5 tips voor Mobile development (in industriële omgevingen)

19 12 2008

products_datalogic_kymannetMijn top 5 ervaringstips:

 5: think small
Als je gewend bent webservices te bouwen op een dikke Windows 2003 server of flitsende DirectX goodies op desktops: de Windows mobile powered terminal is iets minder krachtig. Net als bij de laptop moeten veel device specs worden afgezet tegen de belangrijkste vijand: het batterijgebruik. Veel leuke zaken zoals GPS, bluetooth, WiFi, processor power, memory usage etc. kosten of vreten stroom.
Vraag je dus bij je ontwerp al af: kan mijn device mijn functionele en technische ideeën aan? Een Xmldocument van 5 MB parsen bijvoorbeeld is niet echt een goed idee.

 4: gebruik functietoetsen
Als je ze hebt op je device: gebruik de functietoetsen. Soms zijn de buttons op het scherm gewoon te klein om fatsoenlijk aan te raken met je vinger of de stylus (al is de styles in industriele omgevingen niet het meest gebruikte attribuut….). Dus als je een toetsenbord hebt: een druk op de ‘V’ geeft alle pickopdrachten met de status ‘Verzameld’, de ‘ESC’ knopt sluit het scherm en je werkt net wat gemakkelijker dan elke keer het scherm te moeten aanraken.

 3: Bedien je applicatie met het scherm uit
Als developer ben je gewend naar je scherm te kijken. Ook in administratieve omgevingen zitten de mensen achter het scherm: het werk vindt plaats achter de computer.
De magazijnmedewerker bijvoorbeeld, werkt niet met de computer. Hij werkt met vorkheftruck en palletwagen en voor hem is jouw terminal(applicatie) iets voor erbij: de goederen staan al op de juiste plek, en nou moet hij het alleen nog even in het systeem verwerken. Dus apparaat erbij, scan barcode , scan scan scan en klaar. En dat allemaal zonder op het scherm te kijken, want hij verwacht dat als hij de codes in de juiste volgorde scant, de applicatie dit ook oppikt. Of, met de EAN128 codes, dat hij random mag scannen.
Dus al je mooie feedback met kleurcodes, foutmeldingen op het scherm, hints bij een veld: het wordt simpelweg niet gezien. Wil je de aandacht: PIEP!; laat je device geluid maken en de medewerker zal zijn aandacht verplaatsen naar je scherm.

 2: deploy op het device
Soms moet je deployen op een exotisch device en is er geen beschikbaar, mag je er niet een van de klant gebruiken of moet ‘ie nog worden besteld. Zorg dat je ‘m krijgt. De emulator is een prachtig ding, maar houd rekening met diverse device specifieke ‘features’ als je op het device gaat deployen.
Dus zorg dat je de UI goed scheidt van de BL en DL zodat je die laatste twee gemakkelijk met je testapplicatie kunt doorlopen, en als je de UI moet gaan testen: get the target device.

1: Think BIG!
Tip 5 zegt: think small, houd rekening met de beperkingen van het device.
Maar even belangrijk: met de combinatie Windows mobile, het compact framework en SqlMobile kun je functioneel heel veel bieden.
Tegenwoordig is WiFi op de werkplek heel normaal, dus je mag gewoon een smartclient maken die met webservices op de server communiceert. Data opslaan: ga je gang via data services of met SqlMobile. En programmeren met het compact framework: het is natuurlijk een subset van het full framework, maar het verbaast eigenlijk nog vaker wat er allemaal WEL mee kan.

Dus think big: met de hedendaagse development omgeving en connectivity kun je heel veel mooie oplossingen maken.





.Net 3.5: Linq op een DataSet / DataTable

13 09 2008

Ik zit op een project waar in een winform een typed DataTable wordt gebruikt om een DataGrid te vullen.
Een snelle implementatie: een tabel slepen op een dataset en je hebt een typed datatable en een typed datarow behorend bij die datatable.
Nou moest er een kleine selectie uit de gevulde datatable worden gemaakt, en nou is de gangbare manier om dat via een dataview te doen, en ik vroeg me af of het ook met Linq zou kunnen, want een datatable is toch ook een Enumerable object.
De volgende code is het geworden:

TransactieDataTable srcTable = ds.Transactie;
var result = from n in srcTable.Select()
    where n.Field<int>(srcTable.TransactieIdColumn) < 50
    select n as TransactieRow ;
DataTable doelTable= result.CopyToDataTable<TransactieRow>();
dgTransacties.DataSource = doelTable;

Wat gebeurt er allemaal?
- We starten met een strong typed DataTable srcTable;
- daar selecteren we alles uit, waarbij N een DataRow is, en geen typed DataRow;
- dan stoppen we in de where de property field<T>(index) waarbij we de index uit de strong typed DataTable halen;
- de T vervangen we door het juiste datatype van de transactiekolom, zijnde een int;
- en dan casten we N in de select naar de strong typed ‘TransactieRow’;
- de variabele sesult is dan een, let op: System.Linq.Enumerable.SelectIterator<System.Data.DataRow,TransactieRow>
- elke IEnumerable<T> waarbij T afleidt van een DataRow kan gebruik maken van de DataRow-extension method CopyToDataTable die er een datatable van maakt.

Tot slot: die datatable binden we dan aan een datagrid.





Loggen in .Net met Nlog

12 09 2008

Een component waar ik al enige tijd gebruik van maak is Log4Net.
Loggen is namelijk iets dat je wel graag doet, maar waar je niet te veel tijd in wil steken. En, omdat het vaak neerkomt op loggen naar een tekstbestand, de database of de eventlog, is het een van die functionaliteiten die zich prima leent voor iets dat nog niet heel vaak gebeurt: hergebruik. (behalve bij sommige klanten, waar ze open source niet toestaan en je een eigen log component moet schrijven. Nu ben ik geen pleitbezorger voor open source, maar in dit geval is het een absolute meerwaarde vind ik. Anyway, ik dwaal af, terug naar het onderwerp).
Wat altijd wel wat rommelig was, was de fase van het configureren van Log4Net. Ook al pakte je de config-file van het vorige project, zelden werkte het in één keer, en het grappige was dat collega’s hier ook last van hadden (voor als je denkt dat het toch vnl. aan mij ligt :-) )
Maar nu op een nieuw project gebruiken ze Nlog. In de introductie ervan verwijzen ze al naar Log4Net (dat ze een vrij gelijke API hebben) maar het mooie is: geen enkel probleem met de configuratie.
Iets dat ik erg prettig en user friendly vind: je hoeft niet aan te geven waar je config-file precies staat, als je ‘m een bepaalde naam geeft en in dezelfde map als je app.config zet, dan pikt Nlog deze automatisch op. En alle config voorbeelden (ik heb gebruik gemaakt van de eventlogger, filelogger en maillogger) uit de help werken direct, en de parameters zijn zo duidelijk genaamd dat ze voor zich spreken.
En het goede (en verwachte) nieuws is dat ie gewoon snel logt. Oftewel: ik ben om naar Nlog.





Watermark textbox met Javascript en CSS

25 08 2008

Een van de onderdelen van de ASP.Net Ajax control toolkit is de watermark textbox. Voor hen die deze nog niet kennen, de watermark textbox is een texbox waarin bijvoorbeeld een hint staat wat je moet invullen in die textbox. De bedoeling is natuurlijk dat die hint verdwijnt als je er iets invult, en weer tevoorschijn komt als je je invoer weer verwijdert. Wat er vaak ook bij wordt gemaakt is een aparte opmaak voor die textbox, zodat je duidelijk kunt zien dat je in die textbox nog niets hebt ingevoerd.
Dit zou er als volgt uit kunnen zien:

(er is ook een mini-filmpje van hoe het er uit ziet, maar ik kan bij deze overigens fijne blog dienst geen Flash of Avi’s hosten. Als je het mini-filmpje wilt zien moet je even dit linkje openen.)

Dus, gebruiken en klaar zou je zeggen.
Helaas… de control toolkit is in Visual Studio 2008 als ’standaard’ opgenomen, maar in Visual Studio 2005 is het nog een aparte download, en dat wil niet elke beheerder installeren. En in mijn huidige project, met Visual Studio 2003, is het niet eens beschikbaar.
De oplossing is snel gemaakt, want heel complex is het niet.
Wat hebben we nodig:

  • Een CSS voor de opmaak als de watermerk-text zichtbaar is en eentje voor als de watermerk-text niet zichtbaar is
  • Een stukje Javascript om bij de onBlur te kijken of de textbox leeg is of de watermerk-text bevat of een ingevoerde tekst bevat en dan de juiste CSS te zetten
  • Een stukje Javascript om bij het selecteren van een textbox (focus verkrijgen) de watermerk-CSS weg te halen
  • Een stukje code behind om bij het renderen van de pagina de juiste style te zetten en de Javascript aan de textboxen te knopen.

Als eerste de CSS. Is natuurlijk een voorzet, style het the way you like it.

.watermarkOn
{
  font-size: 0.8em;
  font-family : Verdana, Helvetica, sans-serif;
  background-color : #ddffaa;
  font-variant: small-caps

}
.watermarkOff
{
}

Als tweede de Javascript. Mag in de pagina zelf of in een externe file:

function OnWatermarkFocus(elementId, defaultText)
{
  //als de control de focus krijgt kijken of de waarde gelijk is aan de defaulttext
  //dan heeft de control de watermarkOn style maar tijdens invoer moet de control de
  //watermarkOn value hebben en leeg zijn

  if (document.getElementById(elementId).value == defaultText)
  {
    document.getElementById(elementId).className = “watermarkOff”;
    document.getElementById(elementId).value = “”;
  }
}

function OnWatermarkBlur(elementId, defaultText)
{
  //als de textbox leeg is of de waarde van de defaultValue heeft
  //dan de watermarkOn style toepassen
  var textValue = document.getElementById(elementId).value;
  if (textValue == defaultText || textValue.length == 0)
  {
    document.getElementById(elementId).className = “watermarkOn”;
    document.getElementById(elementId).value = defaultText;
  }
  //in alle andere gevallen de watermarkOff style toepassen

  else
  {
    document.getElementById(elementId).className = “watermarkOff”;
  }
}

En tot slot de code behind. Naamgeving is natuurlijk afhankelijk van de namen van je textbox controls die je hebt ingevoegd.

private void Page_Load(object sender, System.EventArgs e)
{
  SetWatermark();

}

private void SetWatermark()
{
  CreateWatermarkCode(TextBoxWoonplaats , “Uw woonplaats aub in hoofdletters”);
  CreateWatermarkCode(TextBoxNaam , “Vul hier uw volledige naam in”);

}
private void CreateWatermarkCode(TextBox textbox, string defaultValue)
{
  //als de textbox leeg is of de waarde van de defaultValue heeft
  //dan de watermarkOn style toepassen
  if ((textbox.Text == defaultValue) || (textbox.Text.Length ==0))
  {
    textbox.Attributes.Add(“class”, “watermarkOn”);
  }
  else //in alle andere gevallen de watermarkOff style toepassen
  {
    textbox.Attributes.Add(“class”, “watermarkOff” );
  }
  //de eerste keer bij het laden van de pagina
  //een hook zetten naar de focus en blur events
  //en de default waarde zetten
  if (!IsPostBack)
  {
    textbox.Attributes.Add(”onfocus”, string.Format(”OnWatermarkFocus(’{0}’, ‘{1}’)”, textbox.ClientID, defaultValue));
    textbox.Attributes.Add(”onblur”, string.Format(”OnWatermarkBlur(’{0}’, ‘{1}’)”, textbox.ClientID, defaultValue));
    textbox.Text = defaultValue;
  }
}
Dit soort grafische zaken heeft natuurlijk eigenlijk niet zo veel met Ajax van doen. Het wordt wel vaak in één adem genoemd en zoals gezegd is het ook onderdeel van de Ajax control toolkit, maar het doet niets a-synchroons en ook al niets Xml’s.
Laatst las ik iemand en die noemde het: JAC (Javascript and CSS). Dat klinkt al beter, en dan noemen we het beestje tenminste bij zijn naam.