donderdag 4 december 2008

Firefox is een browser welke steeds vaker gebruikt wordt door software ontwikkelaars. Dit komt door de ondersteuning van verschillende tools, soms in vorm van een add-on, welke het ontwikkelen en debuggen van de front-end van een webapplicatie veel efficienter maken. In deze serie van blosg zal ik van een aantal features van firefox en een aantal add-ons bespreken hoe deze gebruikt kunnen worden tijdens de ontwikkeling van applicaties. 

Simpele tips en tricks

View-source
Met Firefox is het mogelijk om de bron van een pagina te bekijken 
zonder deze pagina eerst te bezoeken. Waarom zou je dit willen? Nou allereerst zijn er soms pagina's waarin je meteen wordt doorgestuurd naar een andere pagina, voordat je de pagina te zien krijgt.  In dat geval kan het lastig zijn om het met een browser als Internet Explorer te verkrijgen. Stel je wilt de broncode zien van deze pagina, dan kan je simpelweg in de adresbar de volgende tekst typen:

view-source:http://softwaresolutionsleones.blogspot.com 

view-source geeft aan dat je de broncode van dit bestand wilt bekijken. Dit opent dan netjes de broncode van de pagina in het scherm. 

Error Console
In tegenstelling tot Internet Explorer heeft Firefox een uitgebreide javascript debugger. Foutmeldingen welke in IE vaak cryptisch en onduidelijk zijn, worden beter omschreven in Firefox. Je kunt de error console vinden via Tools > Error Console

Behalve dat deze javascript foutmeldingen geeft, zijn hier ook HTML en CSS warnings te vinden. Deze foutmeldingen blijven hier staan totdat ze verwijderd worden, dus het kan zinvol zijn om gewoon eens door een webapplicatie te browsen, om vervolgens te kijken wat voor meldingen de Error Console geeft.

Ik heb nu twee simpele features van firefox belicht, welke mij ontzettend helpen bij het ontwikkelen van applicaties. Toch is dit nog maar het topje van de ijsberg. In een aantal volgende blogs zal ik het bijvoorbeeld nog hebben over Javascript Breakpointing, Preformance Analysis, DOM manipulatie en veiligheid van de applicaties. 

vrijdag 24 oktober 2008

Om te controleren of een gebruiker een geldig BSN of bankrekeningnummer heeft ingevoerd kan je de elf rpoef uitvoeren. De elfproef is een standaard waaraan alle Bankrekeningnummers (Niet Giro) en BS-nummers in Nederland aan moeten voldoen. De Elf proef voor het BSN kan worden uitgevoerd aan de hand van de volgende formule.

(9*A + 8*B + 7*C + 6*D + 5*E + 4*F + 3*G + 2*H + (-1*I)) % 11 == 0

IN deze formule corespondeerd A met het eerste getal van het nummer, B het tweede getal van het nummer, .. , I met het negende en laatste getal van het nummer. Als de rest deling van de som gelijm is aan nul is het een geldig BSN nummer. Dit heeft een manco, namelijk dat het BSN 000000000 ook als geldig wordt gezien (0 % 11 = 0).
De ElfProef voor een bankrekening nummer wijkt op één punt af van de elfproef voor de BSN. Het laatste cijfer in het nummer wordt dan niet vermenigvuldigd met -1 maar met 1.

Hier onder staat een stukje code dat ik gebruikt heb voor de ElfProef van een BSN in de codebehind van een InfoPath formulier. Over het gebruiken van c# codebehind in combinatie met een infoPath formulier heb ik al een post gechreven. Klik hier om de post te bekijken.


public partial class FormCode
{
public void InternalStartup()
{
EventManager.XmlEvents["/my:mijnVelden/my:BSN"].Changed += new XmlChangedEventHandler(BSN_Changed);
}
public void BSN_Changed(object sender, XmlEventArgs e)
{
String bsnXpath = "//my:BSN";
XPathNavigator bsnBox = MainDataSource.CreateNavigator().SelectSingleNode(bsnXpath, NamespaceManager);
String BSN = bsnBox.Value;
String messageXpath = "//my:Message";
XPathNavigator messageBox = this.MainDataSource.CreateNavigator().SelectSingleNode(messageXpath, NamespaceManager);
if (BSN.Length == 9)
{
int A = int.Parse(BSN.Substring(0, 1));
int B = int.Parse(BSN.Substring(1, 1));
int C = int.Parse(BSN.Substring(2, 1));
int D = int.Parse(BSN.Substring(3, 1));
int E = int.Parse(BSN.Substring(4, 1));
int F = int.Parse(BSN.Substring(5, 1));
int G = int.Parse(BSN.Substring(6, 1));
int H = int.Parse(BSN.Substring(7, 1));
int I = int.Parse(BSN.Substring(8, 1));
int checkInt = 9 * A + 8 * B + 7 * C + 6 * D + 5 * E + 4 * F + 3 * G + 2 * H + (-1 * I);
if (checkInt % 11 == 0)
{
messageBox.SetValue("geldig");
}
else
{
messageBox.SetValue("ongeldig");
}
}
else
{
messageBox.SetValue("Een geldig BSN nummer bestaat uit 9 cijfers");
}
}
}

Om meer geavanceerde functies toe te voegen aan een InfoPath formulier kan gebruik gemaakt worden van visual studio. De codebehind voor InfoPath kan geschreven worden in C# en VB. Om dit mogelijk te maken moet er een onderdeel van Microsoft office worden geinstalleerd (zie plaatje, Configuratiescherm>software>programma's wijzigen of verwijderen>Microsoft Office).







Na de instalatie kan je op een control rechter muis knop drukken en vervolgens onder de knop Programmeren een functie van het onderdeel aanklikken. Hierdoor wordt als het goed is Visual studio geopend met wat gegenereerde code. Wordt de Microsoft Script Editor geopend dan kan je bij Extra>opties>Ontwerp of bij Extra>Formulieropties>Programmeren de programmeer taal waarin de codebhind wordt geschreven aanpassen (C#, VB, JScript of VBScript)



Als de 'Visual hulp-programma's voor toepassingen' zijn geinstalleerd en de gewenste programmeer taal is geslecteerd is er nog een instelling in InfoPath die geweizgd moet worden. Deze instelling is het beveiligings niveau van het InfoPath formulier. Deze instelling moet op Volledig vertouwen worden gezet. Als dit niet is ingesteld krijg je als je de codebehind uitvoerd een security exception. Je kan het beveiligings niveau aanpassen in Extra>Formulieropties>Beveiliging en vertrouwen.

Als je het InfoPath Formulier ook wil gebruiken moet er ook een handtekening worden toegevoegd aan het formulier. Dit gebeurd op de zelfde plek als het aanpassen van het beveiligings niveau.

Als je de stappen hierboven gevolgd heb kan je een InfoPath formulier aanmaken waarbij gebruik gemaakt kan worden van C# codebehind. Hieronder geef ik een aantal code voorbeelden voor het aanroepen en manipuleren van de controls op het InfoPath formulier.

Aanroepen van een control van het InfoPath formulier:

String controlXpath = "//my:Coltrol"; // 'Control' is de variabele naam van de control.
XPathNavigator control = MainDataSource.CreateNavigator().SelectSingleNode(controlXpath, NamespaceManager);

Opvragen en Aanpassen van waarde van een control

String value = control.Value;
control.SetValue("Een string") // In dit voorbeeld gaat het om een TextBox.

Het is ook handig om te weten dat als je een in een Validatie event van een Control zit er geen anpassing gedaan kunnen worden bij andere controls (control.CanEdit = false).

maandag 20 oktober 2008

Met het downloaden van PDF-bestanden als Response in je ASP.NET-pagina's kun je nogal wat problemen tegenkomen. Wij hadden een goed werkende manier hiervoor, maar die wilde plotseling niet helemaal goed meer werken.

Het volgende stukje code laat grofweg zien wat wij altijd hebben gedaan om een Stream als PDF-Response te versturen in ASP.NET:

Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename;
Response.BinaryWrite(outputStream.ToArray());

// filename is een string met de bestandsnaam
// outputStream is een MemoryStream met daarin de PDF-inhoud

We krijgen we dan een venster met daarin de vraag of we het bestand willen openen, willen opslaan of dat we willen annuleren.

Bij een recent project dat we van ASP.NET 1.1 hebben omgezet naar ASP.NET 3.5 begonnen plotseling de problemen. In IE7 werkte alles nog goed, in Firefox werkte het ook nog naar behoren, maar in IE6 traad een vreemd probleem op. Bij het direct openen van het bestand kregen we de volgende foutmelding in Adobe Reader: "There was an error opening this document. This file cannot be found.". Als we het bestand echter eerst opsloegen en daarna openden dan was er geen vuiltje aan de lucht.

De oplossing bleek achteraf erg simpel. Slechts één regel code toevoegen:

Response.ClearHeaders();

De volledige code zier er dan als volgt uit:

Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename;
Response.BinaryWrite(outputStream.ToArray());

// filename is een string met de bestandsnaam
// outputStream is een MemoryStream met daarin de PDF-inhoud

donderdag 2 oktober 2008

Om PDF-icoontjes te kunnen gebruiken in je Sharepoint moet je voor de content query webpart al een bestandje icpdf.gif hebben aangemaakt in de images map.

Om deze ook in de documentenlijsten te kunnen tonen moet je het volgende doen:

  1. Save the image you wish to see as the PDF document icon to "\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\Images\pdf.gif" - Images should be 15x15 pixels in size. (However the 17 x 17 icon from http://www.adobe.com/misc/linking.html works fine)
  2. Edit  "\Program Files\Common Files\Microsoft Shared\Web server extensions\12\Template\Xml\DOCICON.XML"
  3. Add the following line <Mapping Key="pdf" Value="pdf.gif"/>
  4. run iisreset

 
 

Hier gebruiken ze pdf.gif, maar dat kan natuurlijk wel worden gewijzigd in icpdf.gif, aangezien je niet tig dezelfde bestanden in die map wilt hebben staan.

Hide empty fields in sharepoint

Probleem:

Voor een project waar we mee bezig zijn liepen we tegen het volgende probleem. Een detailpagina met cursusinformatie bevat enkele lege (niet ingevulde velden) welke niet moeten weergegeven worden. Deze pagina is opgezet als template in Sharepoint Designer zodat wij niet direct in de code-behind dingen hoeven aan te passen


 

Hieronder een voorbeeld van een cursus

Naam cursus:

Javascript voor gevorderen

Doelstelling:

 

Locatie:

Almere


 

De cursus wordt weergegeven in een tabel en op de plaats waar normaal de doelstelling wordt ingevuld staat nu een spatie ( )


 

Oplossing:

Je kunt in je template (of in je masterpage) wel JavaScript laten uitvoeren. De JavaScript functie doorloopt de tabel en kijkt voor ieder cel (td) of het leeg is, is het leeg dan wordt de rij (tr) niet weergegeven met behulp van CSS.

Hieronder een voorbeeld:


 

<table>

      <tbody>

            <tr>

                  <td
class="CursusVeld">

                        Doelstelling

                  </td>

                  <td
class="CursusWaarde">

                  </td>

            </tr>

      </tbody>

</table>


 

<script
type="text/javascript">

function removeEmptyRows()

{

      //vraag alle td elementen op

      var e=document.getElementsByTagName("td");

  
 

      for(var i=0;i<e.length;i++) classname ="=" innertext ="=" p =" e[i].parentNode;" display =" 'none';">

}

</script>


 

Vervolgens kun je of onderaan het template of in de onload functie van de body-tag het script laten uitvoeren en worden de lege rijen automatisch verborgen.

donderdag 10 juli 2008

MOSS and editing user profiles!

What is the problem?

When you go to to my settings in MOSS you see your profile details but when you click on edit you only see your account.
MySettings userdisp page:



MySetting useredit Page:



What is the cause of this problem?
When i searched on the web for this problem i came accross this thread:
Rachel gave a good idea on why this problem occors she said:

"There are actually 2 user profiles - one is a WSS profile and one is a MOSS profile. The WSS profile you access from Welcome user > My Settings page. The MOSS profiles are created when users are imported into the system from AD or LDAP. They are access from People Search or from a link off of your MySite.

The reason there are 2 is that you can install WSS without MOSS and they wanted a basic user profile. If you installed WSS without MOSS, you would see the profile (again, accessed through Welcome user > My Settings page) with about 3 properties.

If you install MOSS, do an import, and go to the WSS profile, you'll see a bunch of properties added that MOSS adds. We now depricate the WSS profile. If you want to add property values to your profile, you need to go to your MOSS profile from your MySite (MySite > Details). You'll be on the editprofile.aspx page. Add your properties. We then sync your properties to the WSS user list. You will see the values show up on the WSS profile after the sync happens."

So i thought do i really need to use MySite some off our customers mayb don't want to use it and then this means they can't edit user info.

But when i read what what rrdp said about that you can come in the editing page by directly going to editprofile.aspx.
So what is the solution?
The solution is simpler then you think go to the layouts map and copy your useredit.aspx page as a backup.
then go to editprofile.aspx and copy the content of it. Open your useredit.aspx and past the content you just copied into the file save it. And your done!
now when you click on edit you see this page:




Keep in mind to put the correct settings for this fields in the SharedService provider because it will overwrite field values when SSP imports the user profiles if you dont change the settings.





maandag 26 mei 2008

Afgelopen vrijdag was het mijn beurt om ook eens naar de DevDays te gaan. Ik had mezelf redelijk goed voorbereid door al een paar weken vantevoren de sessies op te schrijven waar ik heen wilde gaan. De sessies die mij het meest interessant leken waren:
1. Data protection with .NET Framework 3.5 and Cryptography Next Generation (Rafal Lukawiecki)
2. Is LINQ your data access layer? (Anko Duizer)

3. Understanding ADO .NET data services (Mike Taulty)

4. More intelligent applications using data mining (Rafal Lukawiecki)

5. Leveraging C#3.0 and LINQ (Best practice) (Krishnan Subramanian)

De ene sessie leek me wel leuker als de andere, maar dat blijf je toch houden.

Gelukkig stonden er afgelopen vrijdag nagenoeg geen files richting Amsterdam RAI, dus was ik nog net op tijd om de eerste sessie te volgen.

Rafal begon hier eerst met een ‘basis’ van cryptografie. Voor m’n MCTS examen heb ik hier ook het een en ander voor moeten leren, dus de basis begreep ik redelijk goed. Hij had het over wat momenteel de meest veilige manier was om je applicatie te beveiligen, bijvoorbeeld met smart cards. Ook noemde hij nog de twee functies ProtectData en ProtectMemory die je zeker moet kennen als je heel eenvoudig stukken code van je applicatie wilt beveiligen. Deze twee functies zijn beschikbaar vanaf versie 2.0 van het .Net Framework.
Vanaf versie 3.5 van het .Net Framework zijn er echter veel betere encryptie methoden beschikbaar. Verder kwam er nog een lijstje met methoden die je nu nog wel en niet meer mag gebruiken voor encryptie.
Het wel lijstje bestond uit:
Rijndael / AES 128
RSA 3072

SHA-2 (als het moet)
DSA

Wat je niet meer moet gebruiken is:
DES (Kerberos)
IDEA
RC2 / RC5
Blowfish, Twofish (nou ja, deze zijn wel goed, maar niet standaard)

Ook noemde hij nog 2 functies welke je tegenwoordig kunt gebruiken voor encryptie. In het 3.0 Framework is dit bijvoorbeeld RijndaelManaged en het 3.5 Framework is de functie AesManaged geintroduceerd. Van wat ik begrepen heb zijn het beide implementaties van Rijndael.

Dit bovenstaande was echter nog maar het begin en er waren ook nog maar 20 minuten voorbij. Het leek trouwens wel alsof Rafal aan speed-talking deed zo snel ging het.
Nu begon het moeilijke gedeelte van de sessie. Hij begon ineens over Suite-B, een ‘nieuwe’ encyryptie methode welke onder andere is ontwikkeld door de NSA. De NSA zelf maakt gebruik van Suite-A wanneer iets boven het level ‘top-secret’ komt. Hierop maakte hij nog de opmerking dat Suite-B dus eigenlijk helemaal niet zo veilig was, maar gewoonweg het beste was wat er momenteel door het publiek kan worden gebruikt.
Suite-B maakt gebruik van ‘Elliptical Curve Cryptography’. Dit houdt in het kort in dat het sneller is, je hebt minder bits nodig en is minstens zo veilig als ‘oude’ methoden met meer bits. Vanaf dit moment werd het me allemaal een beetje te technisch en heb ik het niet meer zo goed kunnen volgen.
Wel heb ik nog een aantal aantekeningen kunnen maken van de stukken die ik wel snapte, maar het hele Suite-B verhaal heb ik zelf een beetje overgeslagen.

Tegen het einde aan noemde Rafal nog dat het gebruik van hashes helemaal niet zo veilig meer is, als je dit tenminste voor cryptografie wilt gebruiken. Hij stelde voor om een heel bericht te encrypten en dat dan te gebruiken als ‘hash’. Het nadeel hiervan is dat wanneer je een bericht van 1GB hebt, je ook een ‘hash’ van 1GB hebt.

Ik was blij dat dit bijna het einde was van die sessie, zodat ik even kon bijkomen van wat hij allemaal te zeggen had.
Een kort filmpje van de sessie is op Tweakers.net te vinden: http://tweakers.net/advertorials/devdays/video/20/data-protection-with-net-frameworks-35.html

De tweede sessie was voor mij al een stuk eenvoudiger om te volgen. Zelf ben ik namelijk al een tijdje bezig met LINQ te implementeren in m’n data access layer, dus was ik wel benieuwd wat anderen hiervan vonden.
Anko vertelde hier over de twee verschillende maniere hoe je L2SQL kunt gebruiken in je n-tier applicatie. Ten eerste als data layer en ten tweede als toevoeging in je data layer.

De eerste methode ben ik zelf niet zo’n enorme fan van. Het kwam er op neer dat je je dbml-bestand als DAL gebruikt en zo dus gelijk (in welke laag dan ook) je wijzigingen kunt wegschrijven. Hij gaf zelf ook al aan dat dit meestal niet echt gewenst is, aangezien je overal in je project DA code hebt staan en je bij wijzigingen dus je gehele project moet doorlopen. Het was daarentegen wel snel te implementeren.

De tweede methode, L2SQL gebruiken [b]in[/b] je DAL, vind ik zelf de beste oplossing voor nu. Je kunt zo beter je objecten afstemmen op wat je wilt gebruiken in je applicatie en je hebt maar op 1 plek in project de DA code staan. Het kost echter wel weer meer tijd om te maken in vergelijking tot de eerste methode.

Tijdens deze sessie kwam ik nog enkele leuke opties tegen die je kunt gebruiken met L2SQL. Dit waren bijvoorbeeld de mogelijkheden om ContinueOnConflict te gebruiken, een soort On Error Resume Next, ResolveAll, om een soort rollback te doen en ChangeConflicts. Deze waren volgens Anko nodig omdat L2SQL er van uit gaat dat het opslaan goed gaat en dat hoeft natuurlijk niet zo te zijn, aangezien het systeem aan dirty-reading doet, sowieso wanneer je een n-tier applicatie hebt.

Zelf was ik het niet met Anko op alle fronten eens, maar daar was ik er ook voor, om te kijken wat andere ontwikkelaars nou precies vinden van L2SQL en hoe te gebruiken.

De derde sessie ging over ADO.Net. Dit vond ik een enorm leuke sessie om bij te wonen. Mike kon het allemaal goed vertellen en ik werd enorm enthousiast om dit systeem te gaan gebruiken in een van mijn projecten. Waar het in het kort op neer kwam is dat je via een soort webservice (via WCF) queries kon doen via je webbrowser. Niet alleen simpele queries, maar ook behoorlijk geavanceerde queries. Als je je data service enigszins goed opzet dan kun je via foreign keys zo alles opzoeken van iemand. Wanneer ‘medewerker y’ bijvoorbeeld enkele klanten heeft die op hun beurt orders hebben geplaatst bij het bedrijf waar ‘medewerker y’ werkt, dan kun je via de querystring in je browser alle orders opzoeken die bij ‘medewerker y’ zijn geplaatst. Ook kan er worden gegroepeerd en derdelijke. Dit werkt allemaal met collecties die AsQueryable zijn. Je wilt natuurlijk niet altijd via een browser naar informatie zoeken en aangezien de collecties queryable zijn, kun je ook met het Entity Framework of L2SQL/L2O je gewenste objecten zoeken. Ik vond dit de meest interessante sessie van de dag. Rodi zat ook bij deze sessie, hij zag echter gelijk al de nadelen van de methode die Mike aan het vertellen was. Een van die nadelen was het beveiligen van je WCF webservice. Dat kan natuurlijk niet en je wilt niet je hele data omgeving blootleggen aan de buitenwereld. Dit is zeker een valide punt om het niet te gebruiken. Misschien dat ze daar nog over na gaan denken, of dat hier al lang een oplossing voor is. De techniek is in ieder geval ontzettend gaaf. Enkele links met meer informatie die Mike nog gaf waren http://www.datadeveloper.net, http://www.miketaulty.com en http://blogs.msdn.com/astoriateam
De sites heb ik zelf nog niet bekeken, maar zodra ik weer eens tijd over heb zal ik dat zeker doen.

Mijn vierde sessie werd weer gegeven door Rafal, dit keer ging het over data mining. Eigenlijk wist ik niet precies wat ik moest verwachten, maar dat werd al snel duidelijk. Het ging er namelijk om dat door de gebruiker ingevoerde gegevens strookt met de werkelijkheid. Rafal gaf als een voorbeeld een formulier met soortgelijke gegevens als deze:

Naam: John
Geslacht: Female
Leeftijd: 900
Thuissituatie: Zoon van ouders

De Analysis Services van SQL Server geven nu een melding dat de gegevens waarschijnlijk niet kloppen. De leeftijd is bijvoorbeeld veel te hoog en het is onwaarschijnlijk dat iemand een vrouw is en tegelijk een zoon.

Deze onwaarschijnlijkheden worden niet zo uit de lucht gevist, maar worden berekend door Analysis Services aan de hand van honderden/duizenden/tienduizenden records die als verificatie dienen. AS vind namelijk patronen in die records en aan de hand daarvan berekend hij hoe waarschijnlijk het is dat de ingevoerde data klopt.

Het grote voordeel van dit systeem is dat je je logica voor een formulier niet meer zelf hoeft te maken, dat doet SQL wel voor jou. Dit scheelt uiteraard enorm veel ontwikkeltijd, omdat je dus niet meer tig if-statements hoeft te schrijven.

Het nadeel dat ik al snel kon bedenken is dat wanneer je een paar grapjassen hebt die een paar keer foute data in je database stoppen, je AS denkt dat dit valide is en op een gegeven moment dus niet meer meldingen geeft bij situaties als hierboven beschreven. Hier zul je dus alsnog alert om moeten zijn.

Dit is dus een leuke techniek, maar ik denk niet dat je het nu al kunt gebruiken in een productie omgeving bij een druk bezochte website.

De laatste sessie die ik heb gevolgd ging weer over LINQ en C# 3.0. Deze sessie vond ik wel iets interessanter dan die van Anko eerder die vrijdag. Je kon wel merken dat Krishnan een ontwikkelaar is en geen vertegenwoordiger of iets dergelijks, dat hoop ik tenminste, want het ontbrak hem een beetje aan presentatie skills. Dat geeft verder niet, want z’n verhaal was wel goed. Hij gaf enkele voorbeelden hoe je je partial methods kunt gebruiken met LINQ. Zelf gebruik ik die ook al, maar met de hij gaf ook als voorbeeld om de OnValidate functie te gebruiken in je partial method. Hier had ik zelf nog niet aan gedacht, maar is wel een goede suggestie. Je kunt dan tijdens het valideren al zien of de data in een object wel of niet juist is.
Ook gaf hij een mooie oplossing om N:N-relaties te maken met L2SQL. Officieel kan dit niet, maar hij gaf er een mooie work-around voor. Hierdoor heeft hij wel wat credits van me gekregen. Wat wel jammer is, is natuurlijk dat hij de gegevens alleen maar ophaalde uit de database en niet weer terug schreef. Echter, zal het in de praktijk waarschijnlijk niet vaak voorkomen dat je in 1 mutatie N:N inserts wilt doen, dus op zich was het wel te begrijpen. De oplossing die hij gaf was om een property te maken van IEnumerable en die in je partial class te zetten waar je dat object in wilde hebben. Dit was wel een goed idee van hem waar ik zelf nog niet aan had gedacht, dus was het toch ook weer nuttig om deze sessie bij te hebben gewoond.
Om je query dynamisch te maken maakte hij gebruik van [i]predicates[/i] in de where-clause van je L2SQL query. Dit is niet gelijk fout natuurlijk, maar het geniet toch mijn voorkeur om hiervoor echt Lambda expressies te gebruiken, waar ik al eerder over heb geschreven ( http://www.jan-v.nl/ViewPost.aspx?PostID=aeb2009d-2624-dd11-afa4-003048874dd5 )
Een filmpje van een eerdere sessie van Krishnan is hier te vinden: http://tweakers.net/advertorials/devdays/video/21/linq-trekt-volle-zaal!.html
De mensen in het commentaar daar vinden hem een goede spreker, nou ja, meningen kunnen verschillen natuurlijk. Wat ze wel goed opmerken is dat het goed is dat hij live code klopt, je zou dit ook als nadeel kunnen opmerken trouwens.

Op zich was ik blij dat de dag voorbij was, want het was toch zwaarder dan ik had verwacht. Al met al heb ik behoorlijk wat informatie opgedaan. In eerste instantie ga ik waarschijnlijk niet gelijk met alles aan de slag, maar het is wel goed om het in het achterhoofd te houden. Op naar volgend jaar!

Donderdag is MartinS op mijn pas geweet en vrijdag was het dan eindelijk mijn beurt om een bezoekje te plegen aan de DevDays van dit jaar. De eerste sessie die ik op het programma had staan was van Alex Thissen over het ASP.NET MVC Framework. MVC staat voor Model-View-Controller en is een interessant design pattern waar Microsoft dus een eigen Framework voor aan het bouwen is. Dit Framework is nog niet af en kan in details nog wel veranderen, maar je kon er een goede indruk van krijgen. Omdat ik verkeerd was gelopen en aan de andere kant van de RAI bij een andere sessie uitkwam, kon ik geen plaatsje meer veroveren en moest ik de hele sessie staan. Mede daarom heb ik ook geen aantekeningen gemaakt.

Als je gebruik maakt het MVC Framework, gooi je een hele hoop functionaliteit de deur uit en kun je niet meer vertrouwen op de Page Lifecycle; Page_Load en andere (postback) events zul je niet meer op de normale manier gebruiken; veel Server Controls werken niet. Een request komt binnen op de Controller, die bepaalt wat er precies gevraagd wordt en zorgt dat de juiste gegevens worden uitgewisseld met het Model om vervolgens de juiste View (pagina/aspx) op te starten en gegevens aan mee te geven. Een Request gebeurt wel met een mooie url in de zin van: www.mijnwebsite.nl/Artikel/Edit/67. Deze ‘routes’ zijn helemaal te configureren met standaard waarden voor elk onderdeel uit de url en wat al niet meer, nu nog in de global.asax, maar wellicht straks ook in de Web.config. Wat wel een grote drempel voor mij en vele andere ASP.NET ontwikkelaars zal zijn, is dat de View (de aspx) erg veel gaat lijken op oude asp. Je ‘for loopjes’ komen tussen de html te staan en je maakt zelf je html op; wel zijn er veel hulpfuncties om html te genereren voor bijvoorbeeld dropdowns en textboxen, maar het wordt toch weer de ouderwetse wirwar van code en html. Een van de grootste voordelen die altijd worden genoemd, is dat dit design pattern de testbaarheid van je presentatielaag velen malen groter maakt en het wordt dan vaak ook aangehaald in combinatie met TDD (Test Driven Development), hoewel daar ook wel Model-View-Presenter voor wordt gebruikt, een iets andere variatie op MVC. Om dit te benadrukken wordt een MVC project in Visual Studio altijd automatisch voorzien van een testproject.

De vraag blijft staan of dit Framework toegepast moet/kan worden in toekomstige projecten of niet. Sommige projecten zijn minder geschikt dan andere en er zal een grote omschakeling moeten komen van de ontwikkelaars. Wat de keuze nog moeilijker maakt, is dat het design pattern zo cool is en dat het heel goed bijdraagt aan ‘Seperation of Concerns’, dus het scheiden van code met elk een ander doel in de applicatie.

De tweede sessie had als titel ‘Is LINQ your Data Access Layer’ en werd gepresenteerd door Anko Duizer. Wederom was ik te laat voor een stoel, maar hier kon je redelijk relaxed achteraan op de grond hangen en toch nog wat volgen. Twee stellingen werden er voorgelegd: LINQ to SQL is de DAL en LINQ to SQL wordt gebruikt in de DAL.

Als LINQ to SQL (vanaf nu gewoon LINQ voor het gemak) de DAL is, dan zal eventuele business logica ook in deze laag moeten zitten en is het dus eigenlijk twee lagen in één. Voordelen zijn o.a. simpel en snel om te gebruiken, dus goed voor RAD, binding is heel goed geregeld. Nadelen zijn o.a. dat er nagenoeg een 1 op 1 mapping is tussen Relationele DB structuur en Object structuur in code en dat je dus een mix krijgt van Presentatie, Business en Data Access. De uitbreidingen die je maakt (business logica) zijn wel mooi weg te stoppen in Partial Classes/Methods. Van 1 tabel met een soort Type-veld is het mogelijk om obv dat veld onderscheid te maken en er een base-class van te maken met meer dan één afgeleide classes (BaseUser -> Author en Publisher).

Als LINQ wordt gebruikt in de DAL zul je een betere scheiding kunnen realiseren, maar is er ook veel meer werk nodig. Voordelen zijn o.a. dat je een echte DAL hebt, dat je een betere mapping hebt naar je eigen Domain Model (Business Entiteiten / Information Packages), dat het mogelijk is om nog te switchen naar andere techniek, omdat het een eigen laag is. Nadelen zijn o.a. dat er veel meer code nodig is en dus veel meer tijd zal kosten; bovendien moet er veel meer nagedacht worden over bepaalde obstakels die je zal tegenkomen. Omdat alles in een DataContext zit opgesloten is het lastig om de objecten naar de Presentatielaag te serialiseren en weer terug te deserialiseren. Hier zijn 3 methoden voor: LNQ to SQL Entities (de meest simpele), POCO’s (Plain Old CLR Objects, meeste werk, maar ook meest clean door gebruik van eigen Domain Model / Information Packages) en DataSets (veel support, maar ook beperkingen). Normaal wordt gebruik gemaakt van Deferred Loading, wat inhoud dat er pas iets uit de DB wordt gehaald op het moment dat je het in je code (in een loop bijvoorbeeld) nodig hebt. Dat is na serialisatie naar de Presentatielaag natuurlijk niet meer mogelijk, dus je moet van te voren bepalen wat je nodig hebt: heb je bijvoorbeeld alleen de Orders nodig of wil je ook alle Orderregels erbij hebben?

Algemeen zijn er nog wat opmerkingen te maken. LINQ to SQL is standaard optimistisch qua concurrency, wat inhoudt dat je zelf conflicten moet afhandelen als Dirty Reads e.d. Het is mogelijk om een cache mismatch te krijgen, doordat de DataContext los van de database staat. Een gebruiker zal dan vreemde resultaten te zien krijgen.

Het antwoord op de vraag die in de titel van de sessie wordt genoemd, is niet anders te beantwoorden dan met iets als: “Het kan, maar het hangt ervan af.” Als je je eigen Domain Model wilt behouden, dan moet je het gebruiken in je DAL en kan het niet de DAL zijn. Wat je je dan wel goed moet afvragen, is of LINQ to SQL je dan voordeel oplevert t.o.v. gewoon ADO.NET. In mijn eigen beleving is dit niet het geval, zeker niet als je je bedenkt dat we al een hele opzet hebben voor een DAL. Het voordeel van LINQ to SQL zou dan vooral zijn dat er heel veel wordt gegenereerd en je dus minder (steeds weer dezelfde) code hoeft te schrijven.

Na de lunch stond “Understanding ADO.NET Data Services” op het programma. Dit gaat over een tegenhanger van Web Services en worden ook wel RESTful Services genoemd. Data Services gaat volledig over http en maakt gebruik van het pure http-protocol. Het is dus geen SOAP. WCF kan onderliggend gebruikmaken van REST en van SOAP, dus je blijft de keuze houden; Microsoft gooit SOAP niet weg na zoveel investeringen.

Elk soort data kan gebruikt worden over deze Data Services. Ophalen van gegevens is eenvoudig, maar voor een update moet er veel moeite gedaan worden. In het toekomstige Entity Framework zal een ObjectContext beschikbaar zijn; als je daarvan gebruik maakt is ook het updaten weer eenvoudig geworden.

Wat erg mooi is, is dat je je volledige datasource al kan zien/testen via de url van je browser. Je krijgt dan alles wat je opvraagt (inclusief query-achitge zaken als top, startpositie, filter etc.) in XML. Ook in de code is het erg makkelijk om een query te schrijven tegen een Data Service; dit is zelfs mogelijk met LINQ: de LINQ query wordt dan vertaald naar een Data Service query. En wat ook erg handig en makkelijk is, is dat dit ook erg eenvoudig vanuit Javascript is te doen, dus voor AJAX.

De vierde sessie was moeilijk te kiezen, want eigenlijk spraken de titels me allemaal niet aan. Ik heb gekozen voor Parallel Extensions to the .NET Framework, gepresenteerd door een echt grappige kerel: Daniel Moth. Deze Extensions zijn nog in de maak en er is nu pas een eerste openlijke beta/ctp uit; het enige wat zeker is, is dat het niet dit jaar uitkomt. Ook zullen wij er als Web Developers niet veel mee te maken krijgen. In het begin stonden er quotes op het scherm die we konden lezen; wel interessant wat men denkt over de toekomst van normale desktops pc’s: meer Hz is niet goed meer te doen door de beperkingen in koeling van de chips; in de laatste twee jaar zijn we daardoor heel snel al naar Quad cores gegaan voor de normale consument. Volgens de wet van Moore verwachten ze dat we binnen tien jaar al mainstream pc’s hebben met 80 cores (dat hoeft niet perse 1 cpu te zijn natuurlijk). Het is daarom belangrijk om je te richten op het efficiënt gebruiken van de cores. De Parallel Extensions moeten dat makkelijker gaan maken. Het biedt een laag niveau API dat je niet hoeft te gebruiken, maar wel beschikbaar is en twee meer bruikbare/simpele API’s die daarop gebouwd zijn. De ene is slimmer dan de Thread Pool class, maar minstens zo uitgebreid en bruikbaar als de Thread class, de tweede is een uitbreiding op LINQ en kan LINQ query’s heel makkelijk uitbreiden voor multiple cores.

De laatste sessie was: “Leveraging C#3.0 and LINQ (Best Practice)”, en beetje saai en de spreker probeerde grappig te zijn, maar was het niet. Misschien lag het ook deels aan mijzelf, maar ik kon mijn gedachten er niet goed bijhouden. Toch heb ik nog wel een paar dingen genoteerd. Voor de rest kun je bij JanV zijn, want die heeft deze sessie ook gevolgd.

Met Partial Classes kun je goed uitbreiden. Wil je in LINQ op een mooie manier n op m relaties leggen (dus relaties die een koppeltabel nodig hebben), dan kun je zelf een property maken in de ene class die een List van e andere teruggeeft. De getter van de property loopt dan door de ‘koppeltabel’ heen om de juiste items terg te geven. Het is ook mogelijk om met een extra property enkele properties samen te voegen in 1 nieuwe property van een eigen type. Als je bijvoorbeeld adresgegevens los hebt staan in een tabel, dan kun je deze private maken in LINQ. Vervolgens kun je een Adres-Class maken en een nieuwe property van het type Adres. In het adres geef je dan de afzonderlijke (private) adresgegevens terug.

In LINQ is paging standaard ingebouwd! Je doet in een LINQ query gewoon heel gemakkelijk “.skip(x).take(y)” om x items te skippen en vervolgens y items op te halen. LINQ zal er dan zelf voor zorgen dat de meest optimale query wordt uitgevoerd. In SQL2005 zal dit vaak met ROW_NUMER() zijn (behalve op de eerste pagina (optimaal dus)) en in SQL 2000 zal de query een stuk ingewikkelder zijn. Het mooie is dus dat je daar zelf niets meer mee te maken hebt.

Al met al was het dus een interessante dag. Ik vond het minder dan vorig jaar, maar misschien komt dat doordat er vorig jaar nog allemaal spannende onbekende nieuwe dingen waren die heel erg uitgebreid belicht werden, maar er nog niet waren. Nu ging het vooral wat dieper op de dingen in de nu al uit zijn, maar dan soms ook weer niet diep genoeg, niet met de juiste uitgangspunten (voor mij) of een beetje te chaotisch (zoals de laatste sessie). Maar dat betekent niet dat het geen geslaagde dag was; ik heb toch weer wat geleerd.

woensdag 2 april 2008

Een hoge notering op zoekmachines willen we natuurlijk erg graag, maar om in de resultaten van zoekmachines voor te komen, moet de zoekmachine de site wel kunnen indexeren. Dat lijkt allemaal vanzelfsprekend, maar is dat ook zo? Met ASP.NET 2.0 kan daar een addertje onder het gras zitten.

Sommige sites maken standaard gebruik van cookies, bewust of onbewust. Zonder aanpassingen wordt voor Session state gebruik gemaakt van een cookie met daarin het ID van de Session state, zodat deze terug te leiden is naar een specifieke gebruiker. Dat is op zich geen probleem voor de meeste zoekmachines, maar kan toch gevolgen hebben voor een slechte indexering in combinatie met ASP.NET 2.0.

Crawlers van zoekmachines identificeren zichzelf vaak als Mozilla/5.0. Ze doen dit om ervoor te zorgen dat meer sites ze op een goede manier accepteren en er dus meer sites geïndexeerd kunnen worden. Ook Google doet dit sinds 2006:

  • Voor: Googlebot/2.1 (+http://www.googlebot.com/bot.html)
  • Na: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

In ASP.NET 2.0 wordt gekeken naar de User agent en wordt vervolgens in de browserdefinities, die bekend zijn, gekeken welke mogelijkheden worden ondersteund, zoals javascript en cookies. Als de User agent niet herkend wordt, wordt gebruik gemaakt van de standaard browserdefinitie (default.browser), waarin beschreven staat dat cookies worden ondersteund. In het geval van de zoekmachines wordt de browserdefinitie van Mozilla (mozilla.browser) gevonden en wordt daarin opgezocht welke versie en welke variant wordt gebruikt. Er is echter geen definitie voor de generieke Mozilla/5.0, dus wordt de meest relevante definitie gebruikt, wat neerkomt op Mozilla/1.0 en er dus voor zorgt dat ASP.NET 2.0 vindt dat er geen cookies ondersteund worden en zorgt er dan voor dat het ID van de Session state in de url wordt meegestuurd.

Als je hier problemen van ondervindt en je site wordt niet goed geïndexeerd door zoekmachines - zoekresultaten naar je site bevatten de ID's van de Session state en werken daardoor niet, er worden niet of nauwelijks pagina's geïndexeerd of de crawler stuit op foutmeldingen bij het indexeren - dan is het mogelijk om zelf een browserdefinitie op te geven die ervoor zorgt dat de zoekmachines wel worden herkend met mogelijkheden als cookies.

In de speciale map App_Browsers kun je het bestand met de juiste browserdefinites opslaan. Het is niet nodig om de applicatie opnieuw te compileren, dus het kan zonder problemen in bestaande, draaiende applicatie toegepast worden.

Bij bestaande, draaiende applicaties kun je de map zonder problemen aanmaken en het bestand naar deze map kopiëeren. In de ontwikkelomgeving is het verstandig om het op de volgende manier te doen:
  1. Om de map App_Browsers aan te maken, klik je met de rechter muisknop op het betreffende Web Application Project en kies je voor Add > Add ASP.NET Folder > App_Browsers.
  2. Vervolgens kopiëer je het bestand met de juiste browserdefinitie in Visual Studio (dus niet de verkenner) naar deze map.
Je kunt het bestand met de browserdefinities hier downloaden.





Oorspronkelijke blogpost waar het meeste van deze informatie gevonden is: http://www.kowitz.net/archive/2006/12/11/asp.net-2.0-mozilla-browser-detection-hole.aspx

zaterdag 23 februari 2008

Met de komst van het nieuwe .Net Framework 3.5 kunnen ontwikkelaars nu ook gebruik maken van een nieuwe feature welke schuil gaat onder de naam LINQ.

LINQ is een verzamelnaam voor, momenteel, 3 verschillende onderdelen.

Ten eerste is er LINQ to Objects (L2O).

Met L2O kunnen ontwikkelaars met behulp van LINQ-queries zoeken in verzamelingen van objecten. Een voorbeeld hiervan is een ArrayList. Tot op heden moest men altijd gebruik maken van for-loops om objecten in zo’n verzameling te zoeken, dit is met de komst van L2O verleden tijd. Met een LINQ-query kun je namelijk een selectie maken van de objecten die aan je eisen voldoen.

Ten tweede hebben we LINQ to XML (L2XML).

Net zoals met L2O, is het met L2XML mogelijk om te zoeken naar objecten, elementen of bijvoorbeeld waarden, dit doormiddel van een LINQ-query. Dit heeft ook weer als voordeel dat je niet meer zelf code hoeft te genereren om een XML-document in te lezen in een XMLDocument en hier stap voor stap door te lopen, net zo lang totdat je iets hebt gevonden dat je zocht. Met L2XML schrijf je een query met de LINQ-syntax en .Net zorgt voor de rest. Behalve dat dit vele regels code scheelt, bespaard het ook veel ontwikkel tijd.

Ten derde kunnen we nu gebruik maken van LINQ to SQL (L2SQL).

Zelf vind ik het werken met SQL en databases in het algemeen leuk en interessant werk, vandaar dat L2SQL mij het meest aanspreekt en ik hier ook iets verder over ga uitweiden. Met behulp van L2SQL wordt het mogelijk gemaakt om vanuit je .Net code dynamische queries te genereren welke op de database worden uitgevoerd. De queries zijn het beste te vergelijken met de aloude dynamische SQL statements welke men vroeger vaak ook in de code had staan. De afgelopen jaren is er een trend geweest om dynamische SQL in code niet meer te gebruiken en alleen nog maar gebruik te maken van stored procedures. Deze verschuiving van werkwijze was ook meer dan logisch, aangezien dynamische SQL statements behoorlijk veel veiligheidsrisico’s met zich mee kunnen brengen. In een tijd waar veiligheid hoog in het vaandel staat kun je dat dus niet gebruiken.

Het voordeel van L2SQL is dat je de flexibiliteit van dynamische SQL statements hebt, maar de veiligheid van stored procedures. Wanneer je een LINQ-query maakt, dan wordt deze ‘vertaald’ naar een parameterized query welke wordt uitgevoerd op de database. In figuur 1 is een voorbeeld te zien hoe een LINQ-query wordt vertaald in een SQL-query

Figuur 1

De queries die ik zelf heb gemaakt zijn redelijk eenvoudig en ook goed te bevatten voor een ontwikkelaar die nog niet eerdere een LINQ-query heeft gezien. Een voorbeeld alhier:

var query = from item in dataContext.GetTable<Information.Item>()

select item;

Deze LINQ-query heeft nog behoorlijk veel weg van een ‘normale’ SQL-query, echter zijn de verschillen ook duidelijk zichtbaar.

Als eerste valt op de term var. Dit is een nieuw type dat is geintroduceerd in het .Net Framework 3.5. Heel kort door de bocht is het type var niets anders als een declaratie voor een generic object. Uiteraard zijn er vast wel verschillen op te noemen, maar zelf vind ik het wel een prettige gedachte om het zo te benoemen.

Verder is in deze query te zien dat men nu gebruik kan maken van de termen from en select in Visual Studio, welke we eerder al kenden van SQL-queries. Met LINQ hebben beide termen eigenlijk dezelfde functie behouden, namelijk bij from wordt gekozen uit welk object er een selectie moet plaatsvinden en bij select wordt aangegeven wat er moet worden geretourneerd.

Het bovenstaande is nog redelijk eenvoudig, maar het moge duidelijk zijn dat met de komst van LINQ er behoorlijk veel tijd kan worden bespaard in de ontwikkeltrajecten.

Door L2SQL hoeven er immers niet meer tientallen, danwel honderden, stored procedures te worden gemaakt/gegenereerd voor eenvoudige CRUD-acties. Door L2XML is het niet meer nodig om tientallen regels code te schrijven om een XML-document te doorzoeken en door L2O hoeven ontwikkelaars niet meer tig foreach-loops te maken in de code. Over het algemeen betekend minder code ook dat er minder bugs gemaakt kunnen worden, wat dus automatisch resulteert in stabielere applicaties.

Een goede bron van informatie over LINQ is het weblog van Scott Guthrie. Hier heb ik zelf veel kennis opgedaan van de mogelijkheden over LINQ: http://weblogs.asp.net/scottgu/archive/tags/LINQ/default.aspx


donderdag 21 februari 2008

SharePoint features deel 1


Wat is een Feature?


Bij het ontwikkelen van op maat gemaakte oplossingen voor Windows SharePoint Services of Microsoft Office SharePoint Server 2007, is het van belang dat de ontwikkelaar goed begrijpt wat features zijn. Hiermee worden niet de standaard features bedoelt die in SharePoint geïntegreerd zijn, maar functionaliteiten/Features die de ontwikkelaar wil toevoegen aan de SharePoint oplossing.


Feature of functionaliteiten geven de ontwikkelaars de kans om elementen aan SharePoint sites toe te voegen. Deze elementen kunnen automatisch geactiveerd worden binnen een gekozen SharePoint Site of zelfs binnen een hele Site Collectie. Voorbeelden van elementen die gedefinieerd kunnen worden zijn onder andere lijst types, lijst instanties, menu commandos/links, pagina templates, pagina instanties, Event handlers, workflows etc.


Hoe zitten Features in elkaar?


Een Feature bestaat uit een folder die aangemaakt is in een speciale WSS systeem folder binnen het filesysteem van elke front-end Web server. De folder van een feature bestaat uit één of meerdere xml gebaseerde bestanden die Collabarotive Application Markup Language of kort gezegd CAML bevatten. Elke Feature folder bevat een manifest file genaamd feature.xml. Dit bestand definieert de hoge-level attributen zoals zijn ID en de Naam.


Naast een feature.xml bestaat een feature meestal nog uit andere xml bestanden zoals element.xml die de eigenlijke elementen van de feature beschrijft. Ook zouden er nog andere bestanden in kunnen staan voor templates, bijvoorbeeld een document template voor je lijst instantie/type of resources met afbeeldingen etc.


Om een betere indruk te krijgen van de opzet van een feature zou je naar de voorgedefinieerde features kunnen kijken die in WSS/MOSS aanwezig zijn. Hieronder zie je In Figuur 1 bijvoorbeeld de voorgedefinieerde features van WSS. De feature directory van MOSS zal er heel anders uitzien omdat deze meer dan 100 voorgedefinieerde features bevat.




Hoe maak ik een feature?


Een Feature is op verschillende manieren te bouwen. Hieronder vindt u 3 bekende methodes:



  1. Je maakt een folder aan binnen de feature map van SharePoint(C:/Program Files/Common Files/Microsoft Shared/web server extions/12/TEMPLATE/Feature. Nadat de feature is aangemaakt installeer je de feature via de command line tool van Visual Studio. Deze methode heeft natuurlijk als groot nadeel dat er in de directory van je server wordt gewerkt, en dit is niet altijd wenselijk.

  2. Je maakt voor je Feature een lege Visual Studio class library aan en ontwikkelt hierin de feature. Er zijn op internet tal van blogs/sites te vinden die hierbij kunnen helpen. Zelf heb ik veel aan deze site gehad. Op dezelfde pagina is nog meer info te vinden over wat features zijn. Er is tevens te lezen dat het erg veel werk is om op die manier een feature in je SharePoint omgeving te krijgen. Een voordeel is echter dat je niet direct binnen je server directory hoeft te werken.

  3. De laatste methode die ik hier beschrijf is via Windows Services extentions voor Visual Studio 2005. VS2005 versie 1.1 genereert automatisch de xml bestanden, "signed" de feature en via het build menu kan de site direct naar de server worden ge-deployed. Hoe je precies een feature maakt met behulp van deze tool zal ik later meer over vertellen. Als je niet kan wachten en er nu al mee aan de slag wilt, vindt je hier de WSS extension manual inclusief een voorbeeld.



URL's


WSS/MOSS demo en informatie:


http://www.wssdemo.com/default.aspx


WSS downloads:


Klik hier


WSS Visual Studio 2005 Extensions Manual:


Klik hier

donderdag 14 februari 2008

Microsoft Office SharePoint Server (MOSS) heeft ‘out-of-the-box’ workflow zoals het goedkeuren van documenten. Het nadeel van deze standaard workflow is dat het geschikt is voor één enkele taak, als deze is goedgekeurd stopt deze workflow.

Om een workflow uit te breiden zodat deze na een goedkeuring een volgende workflow start kan SharePoint Designer gebruikt worden. Hoe dit werkt wordt hieronder beschreven.

Maak een bibliotheek of lijst aan zoals bijvoorbeeld een lijst voor de aanvraag voor een laptop.


Stel een workflow (MOSS) in op deze lijst die start als er een nieuw item wordt aangemaakt.




Maak een workflow met SharePoint Designer die start wanneer de aanvraag voor de laptop wordt goedgekeurd. Deze workflow maakt een nieuw item aan in de lijst Bestellingen.





Op de Bestellingen lijst kan dan weer een workflow (MOSS) worden ingesteld zodat de juiste persoon weer een taak krijgt toegewezen. Hieronder staat het overzicht voor één bestelling workflow.


woensdag 13 februari 2008

In SharePoint (zowel WSS 3.0 en MOSS) kan er gebruik gemaakt worden van de structuurweergave (Tree View). Het activeren van dit handige navigatiehulpmiddel kan via de Site-instellingen.



Als voorbeeld zijn de volgende mappen geplaatst: Afdelingen, Software Solutions en SharePoint implementaties waadoor we drie niveaus krijgen.



De navigatie heeft een vaste breedte en hoogte waardoor er scrollbalken verschijnen. Om de breedte en hoogte dynamisch te maken, zodat deze zicht aanpast aan de inhoud, moet het volgende gebeuren:

-> Open de desbetreffende masterpage zoals default.master in bijvoorbeeld SharePoint Designer




-> Zoek de volgende tag:
sharepoint:sprememberscroll runat="server" id="TreeViewRememberScroll" onscroll="javascript:_spRecordScrollPositions(this);" style="overflow: auto;height: 400px;width: 150px; "



-> Vervang de vaste height en width met auto:
sharepoint:sprememberscroll runat="server" id="TreeViewRememberScroll" onscroll="javascript:_spRecordScrollPositions(this);" style="overflow: auto;height: auto;width: auto;
"
Nu krijgt de structuurweergave een dynamische afmeting:

maandag 21 januari 2008

Hieronder staan een aantal praktische tips voor het opschonen van een server om te voorkomen dat actieve ontwikkelingen verloren gaan.

Voor het opschonen van bepaalde mappen is het handig om te controleren of deze map nog actief gebruikt wordt. Een eenvoudige manier om dit te controleren is:

  • Rechtermuisknop op de map
  • Klik op “Search…”
  • Vul “*.*” in bij “All or part of the filename:” en klik op “Search”
  • Als het zoeken klaar is klik dan op de kolom “Date Modified” om te zien wanneer de laatste wijziging heeft plaatsgevonden



Voor het opschonen van bepaalde databases kan bijvoorbeeld de volgende controle gebruikt worden:

  • Open een tabel die in het systeem waar de meeste acties in plaatsvinden zoals een logging tabel of bijvoorbeeld de Atoom tabel in KR.
  • Gebruik bijvoorbeeld de query “SELECT * FROM Atoom ORDER BY MutatieDD DESC” om te sorteren op de laatste mutatie.