InfoPath 2010 veya InfoPath 2007'de Visual C# kullanarak program aracılığıyla dosya eklerini kodlama ve kodunu çözme

Özet

Microsoft® InfoPath® 2010 veya Microsoft Office InfoPath 2007'de, InfoPath form şablonuna dosya eklemek için Dosya Eki denetimini kullanabilirsiniz. Belirli durumlarda, Dosya Eki denetimine eklenmiş olan dosyayı kodlamak ve ardından kodunu çözmek isteyebilirsiniz. Bu durumda, Microsoft Visual C# kullanarak bir Kodlayıcı sınıfı ve Bir Kod Çözücü sınıfı oluşturabilirsiniz. Ardından Kodlayıcı sınıfını ve Kod Çözücü sınıfını kullanarak dosya ekini kodlayabilir ve kodunu çözebilirsiniz. Bu makalede, bir dosyayı forma ek olarak kodlayan ve dosya sistemine kaydetmek üzere ekin kodunu çözen bir InfoPath form şablonunun nasıl tasarlandığı açıklanır.  

InfoPath 2003'te bunun nasıl yapılacağı hakkında daha fazla bilgi için, Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:

892730 InfoPath'te Visual C# kullanarak program aracılığıyla dosya eki kodlama ve kodunu çözme

Daha Fazla Bilgi

Microsoft, belirli bir amaç için satılabilirlik ve/veya uygunluk zımni garantileri dahil ancak bunlarla sınırlı olmamak üzere açık veya zımni garanti vermeden, yalnızca illüstrasyon için programlama örnekleri sağlar. Bu makale, gösterilen programlama dilini ve yordamları oluşturmak ve hata ayıklamak amacıyla kullanılan araçları kullanmayı bildiğinizi varsayar. Microsoft destek ekipleri, belirli bir yordamın işlevselliğinin açıklanmasına yardımcı olabilir ancak gereksinimlerinizi karşılamaya yönelik olarak ek işlevsellik sağlamak veya yordamlar geliştirmek amacıyla bu örnekleri değiştirmezler.

Aşağıdaki örnekte şu adımları izleyeceksiniz:

  1. Visual C# projesi içeren bir form oluşturun.
  2. Encoderclass oluşturun.
  3. Bir Kod Çözücü sınıfı oluşturun.
  4. Kodu çağırmak için formu değiştirin.
  5. Formdaki kod işlemlerini test edin.

Visual C# projesi içeren bir form oluşturma

Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak bir form şablonu ve proje oluşturun.

InfoPath 2010

  1. InfoPath Designer'da boş bir form şablonu oluşturun ve Kaydet simgesine tıklayın.
  2. İstendiğinde, dosya adını yazın ve Kaydet'e tıklayın.
  3. **Geliştirici **sekmesine ve ardından Dil'e tıklayın.
  4. Form şablonu kod dili'nin altında C# öğesini seçin ve ardından Tamam'a tıklayın.

InfoPath 2007

  1. **Dosya **menüsünde Form Şablonu Tasarla'ya tıklayın.
  2. **Form Şablonu Tasarla **görev bölmesinde Boş 'a ve ardından Tamam'a tıklayın.
  3. Dosya menüsünde Kaydet'e tıklayın.
  4. İstendiğinde InfoPathAttachmentEncoding dosya adını yazın ve Kaydet'e tıklayın.
  5. Araçlar menüsünde Form Seçenekleri'ne tıklayın.
  6. **Form Seçenekleri **iletişim kutusundaki Kategori'nin altında Programlama'ya tıklayın.
  7. Programlama dili'nin altındaki Form şablonu kodu dili listesinde C# öğesini seçin ve ardından Tamam'a tıklayın.

Encoder sınıfı oluşturma

Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak bir Encoderclass oluşturun.

InfoPath 2010

  1. Geliştirici sekmesinin altında** Kod Düzenleyicisi **'ne tıklayarak Uygulamalar için Visual Studio Araçları (VSTA) düzenleyicisini başlatın.
  2. Proje menüsünde Yeni Öğe Ekle'ye tıklayın.
  3. Sınıf'ı seçmek için tıklayın.
  4. Ad alanında, adı InfoPathAttachmentEncoder.cs olarak değiştirin ve Kaydet'e tıklayın.
  5. Kod penceresinde, mevcut kodu aşağıdaki "Kodlayıcı kodu" bölümündeki kodla değiştirin.

InfoPath 2007

  1. Uygulamalar için Visual Studio Araçları (VSTA) düzenleyicisini başlatın. 
  2. **Proje Gezgini **bölmesinde InfoPathAttachmentEncoding'e sağ tıklayın, Ekle'ye ve ardından Yeni Öğe'ye tıklayın.
  3. Şablonlar bölümünde Sınıf'ı seçin, adı InfoPathAttachmentEncoder.cs olarak değiştirin ve Ekle'ye tıklayın.
  4. Kod penceresinde, aşağıdaki "Kodlayıcı kodu" bölümündeki kodu yapıştırın.

Kodlayıcı kodu

InfoPath 2010 veya InfoPath 2007'de aşağıdaki kodu kullanın:

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());
}
}
}

Kod Çözücü sınıfı oluşturma

Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak bir Decoderclass oluşturun.

InfoPath 2010

  1. Kod Düzenleyicisi'ndeki Proje menüsünde Yeni Öğe Ekle'ye tıklayın ve ardından Sınıf'ı seçmek için tıklayın.
  2. Ad alanında, adı InfoPathAttachmentDecoder.cs olarak değiştirin ve Kaydet'e tıklayın.
  3. Kod penceresinde, mevcut kodu aşağıdaki "Kod Çözücü kodu" bölümündeki kodla değiştirin. 

InfoPath 2007

  1. VSTA'da, **Proje Gezgini **bölmesinde InfoPathAttachmentEncoding'e sağ tıklayın, Ekle'ye ve ardından Yeni Öğe'ye tıklayın.
  2. Şablonlar bölümünde Sınıf'ı seçin, adı InfoPathAttachmentDecoder.cs olarak değiştirin ve Ekle'ye tıklayın.
  3. Kod penceresinde, aşağıdaki "Kod çözücü kodu" bölümünde yer alan kodu yapıştırın.

Kod çözücü kodu

InfoPath 2010 veya InfoPath 2007'de aşağıdaki kodu kullanın:

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; }
}
}
}

Formu değiştirme

InfoPath formuna Dosya Eki denetimi, Metin Kutusu denetimi ve Düğme denetimi ekleyin. Bunu yapmak için şu adımları uygulayın:

  1. Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak Denetimler görev bölmesini açın. 

    • InfoPath 2010:InfoPathAttachmentEncoding InfoPath form şablonunda, **Giriş **sekmesinin altında **Denetimler **galerisini genişletin.
    • InfoPath 2007:InfoPathAttachmentEncoding InfoPath form şablonunda, **Tasarım Görevleri **görev bölmesinde Denetimler'e tıklayın.
  2. Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak InfoPath formuna bir Dosya Eki denetimi ekleyin:

    • InfoPath 2010: Denetimler görev bölmesindeki Nesneler'in altında Dosya Eki'ne tıklayın.
    • InfoPath 2007: Denetimler görev bölmesinde, Dosya ve Resim altında Dosya Eki'ne tıklayın.
  3. **Dosya Eki **denetimine sağ tıklayın ve ardından Dosya Eki Özellikleri'ne tıklayın.

  4. **Dosya Eki Özellikleri **iletişim kutusunda** Alan Adı **kutusunaAttachmentField yazın ve Tamam'a tıklayın.

  5. Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak InfoPath formuna bir Metin Kutusu denetimi ekleyin:

    • InfoPath 2010: Denetimler görev bölmesindeki Giriş'in altında Metin Kutusu'na tıklayın.
    • InfoPath 2007: Denetimler görev bölmesindeki Standart'ın altında Metin Kutusu'na tıklayın.
  6. Metin Kutusu denetimine sağ tıklayın ve ardından Metin Kutusu Özellikleri'ne tıklayın.

  7. **Metin Kutusu Özellikleri **iletişim kutusunda, **Alan Adı **kutusunaAttachmentName yazın ve Tamam'a tıklayın.

  8. Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak InfoPath formuna Ekle düğmesi ekleyin:

    • InfoPath 2010: Denetimler görev bölmesindeki Nesneler'in altında Düğme'ye tıklayın.
    • InfoPath 2007: Denetimler görev bölmesindeki Standart'ın altında Düğme'ye tıklayın.
  9. Yeni Düğme denetimine sağ tıklayın ve ardından Düğme Özellikleri'ne tıklayın.

  10. **Düğme Özellikleri **iletişim kutusunda, **Etiket **kutusuna Ekle yazın, Kimlik kutusuna btnAttach yazın ve ardından Form Kodunu Düzenle'ye tıklayın.

  11. Kod penceresinin en üstüne gidin ve aşağıdaki kod satırını ekleyin:

    using InfoPathAttachmentEncoding;
    
  12. "Kodunuzu buraya yazın" bölümüne dönün ve aşağıdaki kodu ekleyin:

     //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());
     }              
    
    

InfoPath formuna Kaydet düğmesi ekleme

  1. InfoPathAttachmentEncoding form şablonuna dönün.

  2. Kullanmakta olduğunuz InfoPath sürümünün yönergelerini kullanarak Kaydet düğmesi ekleyin:

    • InfoPath 2010: Denetimler görev bölmesindeki Nesneler'in altında Düğme'ye tıklayın.
    • InfoPath 2007: Denetimler görev bölmesindeki Standart'ın altında Düğme'ye tıklayın.
  3. Yeni Düğme denetimine sağ tıklayın ve ardından Düğme Özellikleri'ne tıklayın.

  4. **Düğme Özellikleri **iletişim kutusunda** Etiket **kutusuna Kaydet yazın, **Kimlik **kutusuna btnSave yazın ve ardından Form Kodunu Düzenle'ye tıklayın.

  5. Aşağıdaki kodu ekleyin:

     //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");
     }                                              
    
    

Not

Bu kodda, ekin kaydedildiği klasörün yolu yer tutucusu dosyayı kaydetmek istediğiniz konumu gösterir.

Kaydet simgesine tıklayın ve VSTA'yı kapatın.

Formu test edin

Bu formun dosya ekleyebilmesi için önce InfoPath form şablonunun tam olarak güvenilir olması gerekir. Bundan emin olmak için aşağıdaki eylemlerden birini gerçekleştirin:

  • Form şablonu dosyasını (.xsn) dijital olarak imzalamak için kod imzalama sertifikası kullanın. Bunu yaptığınızda, kullanıcılardan formu açtıklarında forma güvenmeleri istenir. Bu, formun tam olarak güvenilir olmasını sağlar. Bu nedenle, Visual C# kodunuz için Tam Güven izinleri verilir.
  • Yüklenebilir bir şablon oluşturun.

Form şablonunun tam olarak güvenilir olduğundan emin olduktan sonra, bunu test etmelisiniz. Bunu yapmak için şu adımları uygulayın:

  1. Kullanmakta olduğunuz InfoPath sürümüne yönelik adımları izleyerek formu Önizleme modunda açın:

    • InfoPath 2010 Giriş sekmesinin altında Önizleme'ye tıklayın.
    • InfoPath 2007 Standardtoolbar'da Önizleme'ye tıklayın.
  2. InfoPath formunda, metin kutusuna eklemek istediğiniz dosyanın yolunu yazın ve Ekle'ye tıklayın.

    Not Dosyanın doğru kodlandığını doğrulamak için Dosya Eki denetimine çift tıklayın. 

  3. Kaydet'e tıklayın.

  4. "InfoPath formuna Kaydet düğmesi ekle" bölümü için kodda sağladığınız yolu bulun ve dosyanın bu klasöre kaydedildiğinden emin olun. 

  5. Önizlemeyi Kapat'a tıklayın. Bu işlem testi sonlandırır.