Een bestandsbijlage programmatisch coderen en decoderen met visual C# in InfoPath 2010 of in InfoPath 2007

Samenvatting

In Microsoft® InfoPath® 2010 of in Microsoft Office InfoPath 2007 kunt u een besturingselement Bestandsbijlage gebruiken om een bestand toe te voegen aan de InfoPath-formuliersjabloon. In specifieke omstandigheden kunt u het bestand dat is gekoppeld aan het besturingselement Bestandsbijlage coderen en vervolgens decoderen. In dit geval kunt u Microsoft Visual C# gebruiken om een Encoderclass en een Decoderclass te maken. Vervolgens kunt u de Encoderclass en de Decoderclass gebruiken om de bestandsbijlage te coderen en decoderen. In dit artikel wordt beschreven hoe u een InfoPath-formuliersjabloon ontwerpt waarmee een bestand voor bijlage bij het formulier wordt gecodeerd en de bijlage voor het opslaan in het bestandssysteem wordt gedecodeert.  

Voor meer informatie over hoe u dit doet in InfoPath 2003, klikt u op het volgende artikelnummer om het artikel in de Microsoft Knowledge Base weer te geven:

892730 Een bestandsbijlage programmatisch coderen en decoderen met behulp van Visual C# in InfoPath

Meer informatie

Microsoft biedt programmeervoorbeelden alleen ter illustratie, zonder expliciete of impliciete garantie, inclusief, maar niet beperkt tot, de impliciete garanties van verkoopbaarheid en / of geschiktheid voor een bepaald doel. In dit artikel wordt ervan uitgegaan dat u bekend bent met de programmeertaal die wordt gedemonstreerd en met de tools die worden gebruikt om procedures te maken en fouten op te lossen. Microsoft-ondersteuningsprofessionals kunnen helpen bij het uitleggen van de functionaliteit van een bepaalde procedure, maar zij zullen deze voorbeelden niet wijzigen om extra functionaliteit te bieden of procedures samenstellen die aan uw specifieke behoeften voldoen.

In het volgende voorbeeld voert u de volgende stappen uit:

  1. Maak een formulier dat een Visual C#-project bevat.
  2. Maak een encoderklasse.
  3. Maak een Decoderclass.
  4. Wijzig het formulier om de code aan te roepen.
  5. Test de codebewerkingen in het formulier.

Een formulier maken dat een Visual C#-project bevat

Maak een formuliersjabloon en -project met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt.

InfoPath 2010

  1. Maak in InfoPath Designer een lege formuliersjabloon en klik vervolgens op het pictogram Opslaan.
  2. Wanneer u hierom wordt gevraagd, typt u de bestandsnaam en klikt u op Opslaan.
  3. Klik op het tabblad **Ontwikkelaar **en klik vervolgens op Taal.
  4. Selecteer C# onder Codetaal van formuliersjabloon en klik op OK.

InfoPath 2007

  1. Klik in het menu **Bestand **op Een formuliersjabloon ontwerpen.
  2. Klik in het taakvenster **Een formuliersjabloon ontwerpen**op Leeg en klik vervolgens op OK.
  3. Klik in het menu Bestand op Opslaan.
  4. Wanneer u hierom wordt gevraagd, typt u de bestandsnaam InfoPathAttachmentEncoding en klikt u op Opslaan.
  5. Klik in het menu Extra op Formulieropties.
  6. Klik onder Categorie in het dialoogvenster **Formulieropties **op Programmeren.
  7. Selecteer C# in de lijst met codetalen van de formuliersjabloon onder Programmeertaal en klik op OK.

Een encoderklasse maken

Maak een Encoderclass met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt.

InfoPath 2010

  1. Klik op het tabblad Ontwikkelaars op **Code-editor **om de Visual Studio Tools for Applications -editor (VSTA) te starten.
  2. Klik in het menu Project op Nieuw item toevoegen.
  3. Klik om Klasse te selecteren.
  4. Wijzig in het veld Naam de naam in InfoPathAttachmentEncoder.cs en klik op Opslaan.
  5. Vervang in het codevenster de bestaande code door de code uit de volgende sectie Encodercode.

InfoPath 2007

  1. Start de VSTA-editor (Visual Studio Tools for Applications). 
  2. Klik in het deelvenster **Projectverkenner **met de rechtermuisknop op InfoPathAttachmentEncoding, klik op Toevoegen en klik vervolgens op Nieuw item.
  3. Selecteer Klasse in de sectie Sjablonen, wijzig de naam in InfoPathAttachmentEncoder.cs en klik op Toevoegen.
  4. Plak in het codevenster de code uit de volgende sectie Encodercode.

Coderingscode

Gebruik de volgende code in InfoPath 2010 of in InfoPath 2007:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using InfoPathAttachmentEncoding;

namespace InfoPathAttachmentEncoding
{
/// <summary>
/// InfoPathAttachment encodes file data into the format expected by InfoPath for use in file attachment nodes.
/// </summary>
public class InfoPathAttachmentEncoder
{
private string base64EncodedFile = string.Empty;
private string fullyQualifiedFileName;

/// <summary>
/// Creates an encoder to create an InfoPath attachment string.
/// </summary>
/// <param name="fullyQualifiedFileName"></param>
public InfoPathAttachmentEncoder(string fullyQualifiedFileName)
{
if (fullyQualifiedFileName == string.Empty)
throw new ArgumentException("Must specify file name", "fullyQualifiedFileName");

if (!File.Exists(fullyQualifiedFileName))
throw new FileNotFoundException("File does not exist: " + fullyQualifiedFileName, fullyQualifiedFileName);

this.fullyQualifiedFileName = fullyQualifiedFileName;
}

/// <summary>
/// Returns a Base64 encoded string.
/// </summary>
/// <returns>String</returns>
public string ToBase64String()
{
if (base64EncodedFile != string.Empty)
return base64EncodedFile;

// This memory stream will hold the InfoPath file attachment buffer before Base64 encoding.
MemoryStream ms = new MemoryStream();

// Obtain the file information.
using (BinaryReader br = new BinaryReader(File.Open(fullyQualifiedFileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
string fileName = Path.GetFileName(fullyQualifiedFileName);

uint fileNameLength = (uint)fileName.Length + 1;

byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName);

using (BinaryWriter bw = new BinaryWriter(ms))
{
// Write the InfoPath attachment signature. 
bw.Write(new byte[] { 0xC7, 0x49, 0x46, 0x41 });

// Write the default header information.
bw.Write((uint)0x14);// size
bw.Write((uint)0x01);// version
bw.Write((uint)0x00);// reserved

// Write the file size.
bw.Write((uint)br.BaseStream.Length);

// Write the size of the file name.
bw.Write((uint)fileNameLength);

// Write the file name (Unicode encoded).
bw.Write(fileNameBytes);

// Write the file name terminator. This is two nulls in Unicode.
bw.Write(new byte[] {0,0});

// Iterate through the file reading data and writing it to the outbuffer.
byte[] data = new byte[64*1024];
int bytesRead = 1;

while (bytesRead > 0)
{
bytesRead = br.Read(data, 0, data.Length);
bw.Write(data, 0, bytesRead);
}
}
}

// This memorystream will hold the Base64 encoded InfoPath attachment.
MemoryStream msOut = new MemoryStream();

using (BinaryReader br = new BinaryReader(new MemoryStream(ms.ToArray())))
{
// Create a Base64 transform to do the encoding.
ToBase64Transform tf = new ToBase64Transform();

byte[] data = new byte[tf.InputBlockSize];
byte[] outData = new byte[tf.OutputBlockSize];

int bytesRead = 1;

while (bytesRead > 0)
{
bytesRead = br.Read(data, 0, data.Length);

if (bytesRead == data.Length)
tf.TransformBlock(data, 0, bytesRead, outData, 0);
else
outData = tf.TransformFinalBlock(data, 0, bytesRead);

msOut.Write(outData, 0, outData.Length);
}
}

msOut.Close();

return base64EncodedFile = Encoding.ASCII.GetString(msOut.ToArray());
}
}
}

Een Decoder-klasse maken

Maak een Decoderclass aan de hand van de aanwijzingen voor de versie van InfoPath die u gebruikt.

InfoPath 2010

  1. Klik in code-editor in het menu Project op Nieuw item toevoegen en klik vervolgens om Klasse te selecteren.
  2. Wijzig in het veld Naam de naam in InfoPathAttachmentDecoder.cs en klik op Opslaan.
  3. Vervang in het codevenster de bestaande code door de code uit de volgende sectie Decodercode. 

InfoPath 2007

  1. Klik in VSTA in het deelvenster **Projectverkenner **met de rechtermuisknop op InfoPathAttachmentEncoding, klik op Toevoegen en klik vervolgens op Nieuw item.
  2. Selecteer Klasse in de sectie Sjablonen, wijzig de naam in InfoPathAttachmentDecoder.cs en klik op Toevoegen.
  3. Plak in het codevenster de code uit de volgende sectie Decodercode.

Decodercode

Gebruik de volgende code in InfoPath 2010 of in InfoPath 2007:

using System;
using System.IO;
using System.Text;

namespace InfoPathAttachmentEncoding
{
/// <summary>
/// Decodes a file attachment and saves it to a specified path.
/// </summary>
public class InfoPathAttachmentDecoder
{
private const int SP1Header_Size = 20;
private const int FIXED_HEADER = 16;

private int fileSize;
private int attachmentNameLength;
private string attachmentName;
private byte[] decodedAttachment;

/// <summary>
/// Accepts the Base64 encoded string
/// that is the attachment.
/// </summary>
public InfoPathAttachmentDecoder(string theBase64EncodedString)
{
byte [] theData = Convert.FromBase64String(theBase64EncodedString);
using(MemoryStream ms = new MemoryStream(theData))
{
BinaryReader theReader = new BinaryReader(ms);
DecodeAttachment(theReader);
}
}

private void DecodeAttachment(BinaryReader theReader)
{
//Position the reader to obtain the file size.
byte[] headerData = new byte[FIXED_HEADER];
headerData = theReader.ReadBytes(headerData.Length);

fileSize = (int)theReader.ReadUInt32();
attachmentNameLength = (int)theReader.ReadUInt32() * 2;

byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
//InfoPath uses UTF8 encoding.
Encoding enc = Encoding.Unicode;
attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2);
decodedAttachment = theReader.ReadBytes(fileSize);
}

public void SaveAttachment(string saveLocation)
{
string fullFileName = saveLocation;
if (!fullFileName.EndsWith(Path.DirectorySeparatorChar.ToString())){
fullFileName += Path.DirectorySeparatorChar;
}

fullFileName += attachmentName;

if(File.Exists(fullFileName))
File.Delete(fullFileName);

FileStream fs = new FileStream(fullFileName, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(decodedAttachment);

bw.Close();
fs.Close();
}

public string Filename
{
get{ return attachmentName; }
}

public byte[] DecodedAttachment
{
get{ return decodedAttachment; }
}
}
}

Het formulier wijzigen

Voeg een besturingselement Bestandsbijlage, een tekstvakbesturingselement en een knopbesturingselement toe aan het InfoPath-formulier. Ga hiervoor als volgt te werk:

  1. Open het taakvenster Besturingselementen met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt. 

    • InfoPath 2010:Vouw in de InfoPathAttachmentEncoding InfoPath-formuliersjabloon onder het tabblad **Start **de galerie **Besturingselementen**uit.
    • InfoPath 2007:Klik in de InfoPathAttachmentEncoding InfoPath-formuliersjabloon op Besturingselementen in het taakvenster **Ontwerptaken**.
  2. Voeg een besturingselement Bestandsbijlage toe aan het InfoPath-formulier met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt:

    • InfoPath 2010:Klik in het taakvenster Besturingselementen onder Objecten op Bestandsbijlage.
    • InfoPath 2007:Klik in het taakvenster Besturingselementen onder Bestand en Afbeelding op Bestandsbijlage.
  3. Klik met de rechtermuisknop op het besturingselement **Bestandsbijlage **en klik vervolgens op Eigenschappen van bestandsbijlage.

  4. Typ in het dialoogvenster **Eigenschappen van bestandsbijlage **het vakAttachmentFieldin het vak **Veldnaam **en klik vervolgens op OK.

  5. Voeg een tekstvakbesturingselement toe aan het InfoPath-formulier met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt:

    • InfoPath 2010: Klik in het taakvenster Besturingselementen onder Invoer op Tekstvak.
    • InfoPath 2007: Klik in het taakvenster Besturingselementen onder Standaard op Tekstvak.
  6. Klik met de rechtermuisknop op het besturingselement Tekstvak en klik vervolgens op Eigenschappen van tekstvak.

  7. Typ deAttachmentName in het vak **Veldnaam **in het dialoogvenster **Eigenschappen van tekstvak **en klik op OK.

  8. Voeg een knop Bijvoegen toe aan het InfoPath-formulier met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt:

    • InfoPath 2010: Klik in het taakvenster Besturingselementen onder Objecten op Knop.
    • InfoPath 2007: Klik in het taakvenster Besturingselementen onder Standaard op Knop.
  9. Klik met de rechtermuisknop op het nieuwe knopbesturingselement en klik vervolgens op Knopeigenschappen.

  10. Typ in het dialoogvenster **Knopeigenschappen **Bijvoegen in het vak **Label **, typ btnAttach in het vak Id en klik vervolgens op Formuliercode bewerken.

  11. Ga naar de bovenkant van het codevenster en voeg vervolgens de volgende regel code toe:

    using InfoPathAttachmentEncoding;
    
  12. Ga terug naar 'schrijf hier uw code' en voeg vervolgens de volgende code toe:

     //Create an XmlNamespaceManager
     XmlNamespaceManager ns = this.NamespaceManager;
    
    //Create an XPathNavigator object for the Main data source
     XPathNavigator xnMain = this.MainDataSource.CreateNavigator();
    
    //Create an XPathNavigator object for the attachment node
     XPathNavigator xnAttNode = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentField", ns);
    
    //Create an XPathNavigator object for the filename node
     XPathNavigator xnFileName = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentName", ns);
    
    //Obtain the text of the filename node.
     string fileName = xnFileName.Value;
     if (fileName.Length > 0)
     {
      //Encode the file and assign it to the attachment node.
      InfoPathAttachmentEncoder myEncoder = new InfoPathAttachmentEncoder(fileName);
    
    //Check for the "xsi:nil" attribute on the file attachment node and remove it
      //before setting the value to attach the filerRemove the "nil" attribute
      if (xnAttNode.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
       xnAttNode.DeleteSelf();
    
    //Attach the file
      xnAttNode.SetValue(myEncoder.ToBase64String());
     }              
    
    

Een knop Opslaan toevoegen aan het InfoPath-formulier

  1. Ga terug naar de formuliersjabloon InfoPathAttachmentEncoding.

  2. Voeg een knop Opslaan toe met behulp van de aanwijzingen voor de versie van InfoPath die u gebruikt:

    • InfoPath 2010: Klik in het taakvenster Besturingselementen onder Objecten op Knop.
    • InfoPath 2007: Klik in het taakvenster Besturingselementen onder Standaard op Knop.
  3. Klik met de rechtermuisknop op het nieuwe knopbesturingselement en klik vervolgens op Knopeigenschappen.

  4. Typ in het dialoogvenster **Knopeigenschappen **Opslaan in het vak **Label **, typ btnSave in het vak **ID **en klik vervolgens op Formuliercode bewerken.

  5. Voeg de volgende code in:

     //Create an XmlNamespaceManager
     XmlNamespaceManager ns = this.NamespaceManager;
    
    //Create an XPathNavigator object for the Main data source
     XPathNavigator xnMain = this.MainDataSource.CreateNavigator();
    
    //Create an XPathNavigator object for the attachment node
     XPathNavigator xnAttNode = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentField", ns);
    
    //Obtain the text of the node.
     string theAttachment = xnAttNode.Value;
     if(theAttachment.Length > 0)
     {
         InfoPathAttachmentDecoder myDecoder = new InfoPathAttachmentDecoder(theAttachment);
         myDecoder.SaveAttachment(@"Path to the folder to save the attachment");
     }                                              
    
    

Opmerking

In deze code geeft de tijdelijke aanduiding Pad naar de map om de bijlage op te slaan de locatie weer waarin u het bestand wilt opslaan.

Klik op het pictogram Opslaan en sluit VSTA.

Het formulier testen

Voordat dit formulier een bestand kan bijvoegen, moet de InfoPath-formuliersjabloon volledig worden vertrouwd. Voer een van de volgende acties uit om dit te controleren:

  • Gebruik een certificaat voor ondertekening van code om het formuliersjabloonbestand (.xsn) digitaal te ondertekenen. Wanneer u dit doet, wordt gebruikers gevraagd het formulier te vertrouwen wanneer ze het formulier openen. Hierdoor wordt het formulier volledig vertrouwd. Daarom worden machtigingen voor volledig vertrouwen verleend aan uw Visual C#-code.
  • Maak een installeerbare sjabloon.

Nadat u ervoor hebt gezorgd dat de formuliersjabloon volledig wordt vertrouwd, moet u deze testen. Ga hiervoor als volgt te werk:

  1. Open het formulier in de preview-modus door de stappen te volgen voor de versie van InfoPath die u gebruikt:

    • InfoPath 2010 Klik op het tabblad Start op Voorbeeld.
    • InfoPath 2007 Klik op de standaardtoolbalk op Voorbeeld.
  2. Typ in het InfoPath-formulier het pad van het bestand dat u wilt bijvoegen in het tekstvak en klik op Bijvoegen.

    Opmerking Dubbelklik op het besturingselement Bestandsbijlage om te controleren of het bestand correct is gecodeerd. 

  3. Klik op Opslaan.

  4. Zoek het pad dat u hebt opgegeven in de code voor de sectie 'Knop Opslaan toevoegen aan het InfoPath-formulier' en controleer of het bestand in die map is opgeslagen. 

  5. Klik op Voorbeeld sluiten. Hiermee wordt de test beëindigd.