Saturday, December 12, 2020

Infopath File attachment kontrolündeki dosyayı programsal olarak kaydetmek ve bu dosyayı mail ile göndermek

Formumuz’a bir adet File attachment kontrolu,bir adet Text Box kontrolü ve buton kontrolü ekliyoruz.


Buton kontrolüne tıklandığında textbox’a eklenen dosyanın adı tutulacak. İleriki aşamalarda Sharepoint Designer kullanılarak textbox’ta tutulan bu dosya adı ile ilgili dosyayı çağırıp göstereceğiz.

Buton Kontrolüne tıklandığında eklenen dosya binary olarak şifrelenir (encode) 

Bunun için infopath formumuzda  InfoPathAttachmentEncoder.cs adında yeni bir class oluştururuz.

 

InfoPathAttachmentEncoder.cs

using System;

using System.Text;

using System.IO;

using System.Security.Cryptography;

 

/// <summary>

/// InfoPathAttachment dosya verisini infopath’in dosya ekleme formatına çevirir.

 

/// </summary>

public class InfoPathAttachmentEncoder

{

    private string base64EncodedFile = string.Empty;

    private string fileName;

    private byte[] fileData;

 

    /// <summary>

    /// Creates an encoder to create an InfoPath attachment string.

    /// </summary>

    /// <param name="fileName"></param>

    /// <param name="fileData"></param>

    public InfoPathAttachmentEncoder(string fileName, byte[] fileData)

    {

        if (fileName == string.Empty)

            throw new ArgumentException("Must specify file name", "fileName");

 

        if (fileData.Length == 0)

            throw new ArgumentNullException("fileData","File is empty");

 

        this.fileName = fileName;

        this.fileData = fileData;

    }

 

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

 

        // This memory stream will hold the current file to be changed.

        MemoryStream msOld = new MemoryStream(fileData);

 

        // Get the file information.

        using (BinaryReader br = new BinaryReader(msOld))

        {

            string fileName = this.fileName;

 

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

            }

        }

 

        msOld.Close();

        msOut.Close();

 

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

    }

}

Yazılan dosyayı okuyabilmek için infopath formumuza InfoPathAttachmentDecoder.cs adında yeni bir class ekliyoruz.

 

InfoPathAttachmentDecoder.cs

using System;

using System.IO;

using System.Text;

 

namespace denemeimg

{

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

            }

      }    

}

Buton kontrolüne tıklandığı anda bu iki class eklenen dosyanın binary olarak yazılması ve okunması için çağrılır.

Şimdi buton kontrolümüzün altında çalışacak kodlarımızı yazalım.

  public void CTRL3_5_Clicked(object sender, ClickedEventArgs e)

        {

            XPathNavigator root = MainDataSource.CreateNavigator();

 

            // Eklenen Dosyayı alma

         

            XPathNavigator attachmentNode = root.SelectSingleNode("//my:eklenendosya", NamespaceManager);

            string base64Attachment = attachmentNode.Value;

 

            //InfoPathAttachmentDecoder class' kullanarak eklenen dosyayı binary Data olarak okuyoruz.

            InfoPathAttachmentDecoder decoder =new InfoPathAttachmentDecoder(base64Attachment);

            byte[] fileData = decoder.DecodedAttachment;

 

             root.SelectSingleNode("//my:dosyaadi", NamespaceManager).SetValue(decoder.Filename);

            string newFileName = root.SelectSingleNode("//my:dosyaadi", NamespaceManager).Value;

 

            //InfoPathAttachmentEncoder class'ı kullanarak eklenen dosyanın adını tutacagımız textbox kontrolunde dosyaadını şifreliyoruz

          

            InfoPathAttachmentEncoder encoder = new InfoPathAttachmentEncoder(newFileName, fileData);

 

            // File Attachment control'ünde eklenen dosyayı tutma

            attachmentNode.SetValue(encoder.ToBase64String());

         

            //Eklenen dosyanın Kayıt edileceği yer

            decoder.SaveAttachment(@"\\portalnew\KullaniciBilgileriIKResimler");

 

 

        }

 

Infopath Formumuzu çalıştırdığımızda


Attachment File controlüne tıkladığımızda ekleyecegimiz dosyayı seçeceğimiz Attach File dialog penceresi açılır ve ilgili dosyayı seçeriz.


Buton kontrolünün altında çalışan

decoder.SaveAttachment(@"\\portalnew\KullaniciBilgileriIKResimler");

kodu ile eklediğimiz dosyayı kaydedeceğimiz yeri gösteririz.Çünkü birazdan Sharepoint designer ile iş akışı düzenleyeceğiz.

 Her yeni infopath formunda eklenen bu dosyayı kullanıcılara göstereceğiz.

 SharePoint Designer ile Düzenleyeceğimiz iş akışı :

 Formda FormGiris adında yeni bir field yaratıp değerini 1 olarak set edeceğiz.


FormGiris=1  Sharepoint designer da ilgili iş akışı başlayarak ilgili kullanıcıya eklenen dosya gönderilir.

 Buton kontrolünün altına aşağıdaki kodu yazıyoruz.

MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:FormGiris", NamespaceManager).SetValue("1");

   //Açık olan pencereyi kapatıyoruz

       Application.ActiveWindow.Close();

Yeni bir form açtık ve Form’a dosya ekledik.Gönder butonu ile formu sharepointte ilgili form kitaplığına gönderdik.

Şimdi Sharepoint Designer kullanarak iş akışımızı tasarlıyoruz.

Infopath formumuzu yayınladıgımız form kitaplığında yeni bir form açalım ve iş akışımızın nasıl çalıştığına bakalım.

butonuna basıldığında dosyanın adı textbox kontrolüne cicek.jpg olarak yazılır ve FormGiris alanının değeri 1 olarak set edilir. Form sharepoint sitesinde yayınlandığı yere kaydedilir.Ve iş akışı ilgili kullanıcıya bu dosyayı mail yoluyla gönderir.

Form tasarlanırken Toolsà DataconnectionàGonder adında bir data bağlantısı oluşturduk.Burada formun doldurulduktan sonra saklanacağı yeri gösterdik.

FormGiris=1 ise kullanıcıya iş akışından dönen mail


Hazırlayan:Güler ONUK


 

No comments:

Post a Comment

Infopath Formlarında Dinamik Kontroller Yaratma

                                  Sharepoint Form Kitaplığında Klasörleme Bir sharepoint Form kitaplığında ki item kayıtlarının fazlalığı ...