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.