Makale Özeti

Bu yazımızda ASP.NET kullanarak gerçek zamanlı olarak bir Generic Handler üzerinden VCalendar dosyaları yaratmayı inceliyoruz.

Makale

Varsayalım ki web sitenizde belirli aktiviteleri paylaşıyorsunuz veya belki de toplantıları. İnsanların buluşma tarihlerini bir kenara not almalarını ve sonra da günü geldiğinde hatırlamalarını istiyorsunuz. Artık çoğu kullanıcının bir şekilde dijital ortamda takvim tuttuğunu varsayarsak neden onlara söz konusu aktivitelerini hızlı bir şekilde takvimlerine ekleme olanağı tanımlayalım? Şükür ki bu konuda genel geçer bir standart var; VCalendar!

VCalendar standardı çoğu dijital takvim uygulaması ile uyumlu bir standart. Yapacağımız örnekte bir Generic Handler (ashx) kullanacağız. Söz konusu handler bize VCalendar davetiye dosyaları oluşturarak verecek. Siz uygulamalarınızda ashx dosyasına QueryString üzerinden parametreler göndererek farklı VCalendar dosyaları oluşturabilirsiniz.

        context.Response.ContentType = "application/download"

İlk olarak yukarıdaki şekilde istemciye göndereceğimiz verinin download edilmesi gereken bir uygulama dosyası olduğunu belirtelim. Böylece istemcideki tarayıcı bir download penceresi açacaktır. VCalendar dosyaları vcs uzantılıdır, istemciye doğrudan gönderdiğimiz istemcide kullanıcı bunu ister Outlook ile açar ister farklı bir uygulama ile kullanır, karar tamamen kullanıcıya kalmış.

[VB]

        Dim BasTarih As Date = Date.Now

        Dim SonTarih As Date = Date.Now.AddDays(1)

        Dim Konum As String = "İstanbul - MS Binası"

        Dim Konu As String = "VCalendar Toplantısı"

        Dim Detay As String = "Toplantı VCalendar standartları görüşülecek. "

[C#]

        System.DateTime BasTarih = System.DateTime.Now;

        System.DateTime SonTarih = System.DateTime.Now.AddDays(1);

        string Konum = "İstanbul - MS Binası";

        string Konu = "VCalendar Toplantısı";

        string Detay = "Toplantı VCalendar standartları görüşülecek. ";

 

Bir sonraki adımda yukarıdaki şekilde parametrelerimizi tanımlayalım. Bu parametreleri siz uygulamalarınızda veritabanına bağlayabilirsiniz. Yaratacağımız VCalendar dosyası buradaki bilgileri içerecek.

[VB]

        Dim BirStream As New IO.MemoryStream()

        Dim Yazici As New IO.StreamWriter(BirStream)

        Yazici.AutoFlush = True

[C#]

        System.IO.MemoryStream BirStream = new System.IO.MemoryStream();

        System.IO.StreamWriter Yazici = new System.IO.StreamWriter(BirStream);

        Yazici.AutoFlush = true;

VCalendar dosyaları özünde text (metin) bazlı dosyalardır. O nedenle aslında sunucu tarafında bir metin yaratarak Binary olarak istemciye göndereceğiz. Bu nedenle istemciye göndereceğimiz tüm içeriği oluştururken elimizde bir Stream ve StreamWriter olması gerekiyor. Söz konusu Stream herhangi bir konuma yazdırılmayacağı için havada bir MemoryStream yaratarak ilerliyoruz. Söz konusu StreamWriter'ın AutoFlush özelliğini True olarak aktardığımızda artık tüm içerik otomatik olarak Stream'e aktarılıyor olacak.

        Yazici.WriteLine("BEGIN:VCALENDAR")

        Yazici.WriteLine("PRODID:-//daron.yondem.com")

        Yazici.WriteLine("BEGIN:VEVENT")

Yukarıdaki VCalendar standartlarına uygun dosyamızı yaratmaya başladık. PRODID özelliğine aktardığınız değer çok önemli değil. Aslında bu VCalendar dosyasını yaratan programın adını içermesi yeterli.

[VB]

        Yazici.WriteLine("DTSTART:" & BasTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("DTEND:" & SonTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("LOCATION:" & Konum)

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" & Detay)

        Yazici.WriteLine("SUMMARY:" & Konu)

[C#]

        Yazici.WriteLine("DTSTART:" + BasTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("DTEND:" + SonTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("LOCATION:" + Konum);

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + Detay);

        Yazici.WriteLine("SUMMARY:" + Konu);

Gördüğünüz gibi neredeyse tüm parametrelerimizi burada dosyamıza ekledik. Önemli olan noktalardan biri tüm tarih bilgilerinin ilk olarak UniversalTime'a yani global olarak geçerli zaman dilimine uyarlanması gerektiği. İkincisi ise tarih dosyaya yazdırılırken uyulması gereken format. Sonraki satırlarda diğer parametrelerimizi de aktardıktan sonra devam edebiliriz.

[VB]

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" & Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

[C#]

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" & Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

Kodumuzun ilk satırında bu aktivitenin ne kadar önemli olduğuna dair bir değer aktardıktan sonra aktivite ile ilgili bir alarm ayarlıyoruz. PT30M ayarı ile aktiviteden yarım saat önce kullanıcının uyarılması gerektiğini belirtmiş olduk. Siz bu ayarları istediğiniz gibi değiştirebilirsiniz. Son olarak hem VEVENT gem de VCALENDAR'ı kapatarak dosyamızı sonlandırıyoruz.

[VB]

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs")

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString())

        context.Response.BinaryWrite(BirStream.ToArray())

[C#]

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs");

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString());

        context.Response.BinaryWrite(BirStream.ToArray());

Sıra geldi oluşturduğumuz dosyayı istemciye göndermeye. İlk olarak istemciye gönderdiğimiz HTTPResponse'a bazı header bilgileri eklememiz gerekiyor. Bunlardan ilki istemcinin aldığı dosyayı hangi isimle açacağı. Bizim örneğimizde dosya adı aktivite.vcs şeklinde yer alıyor. İkincisi ise oluşturduğumuz dosyanın boyutu. Son olarak Response.BinaryWrite ile elimizdeki Stream'i istemciye gönderiyoruz.

Eğer istemci bu adresi doğrudan açarsa karşısına bir VCalendar download penceresi gelecektir. Yarattığımız ashx dosyasını farklı aspx dosyaları içerisinde linkleyerek kullanıcıların linklere bastıklarında VCalendar dosyalarını indirebilmelerini sağlayabilirsiniz.

Generic Handler'ımızın son hali ile aşağıdaki şekilde;

[VB]

<%@ WebHandler Language="VB" Class="vcalendar" %>

 

Imports System

Imports System.Web

 

Public Class vcalendar : Implements IHttpHandler

 

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        context.Response.ContentType = "application/download"

 

        Dim BasTarih As Date = Date.Now

        Dim SonTarih As Date = Date.Now.AddDays(1)

        Dim Konum As String = "İstanbul - MS Binası"

        Dim Konu As String = "VCalendar Toplantısı"

        Dim Detay As String = "Toplantı VCalendar standartları görüşülecek. "

 

        Dim BirStream As New IO.MemoryStream()

        Dim Yazici As New IO.StreamWriter(BirStream)

        Yazici.AutoFlush = True

 

        Yazici.WriteLine("BEGIN:VCALENDAR")

        Yazici.WriteLine("PRODID:-//daron.yondem.com")

        Yazici.WriteLine("BEGIN:VEVENT")

 

        Yazici.WriteLine("DTSTART:" & BasTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("DTEND:" & SonTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("LOCATION:" & Konum)

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" & Detay)

        Yazici.WriteLine("SUMMARY:" & Konu)

 

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" & Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

 

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs")

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString())

        context.Response.ContentType = "application/download"

        context.Response.BinaryWrite(BirStream.ToArray())

    End Sub

 

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable

        Get

            Return False

        End Get

    End Property

 

End Class

[C#]

<%@ WebHandler Language="C#" Class="Handler" %>

 

using System;

using System.Web;

 

public class Handler : IHttpHandler {

 

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "application/download";

 

        System.DateTime BasTarih = System.DateTime.Now;

        System.DateTime SonTarih = System.DateTime.Now.AddDays(1);

        string Konum = "İstanbul - MS Binası";

        string Konu = "VCalendar Toplantısı";

        string Detay = "Toplantı VCalendar standartları görüşülecek. ";

 

        System.IO.MemoryStream BirStream = new System.IO.MemoryStream();

        System.IO.StreamWriter Yazici = new System.IO.StreamWriter(BirStream);

        Yazici.AutoFlush = true;

 

        Yazici.WriteLine("BEGIN:VCALENDAR");

        Yazici.WriteLine("PRODID:-//daron.yondem.com");

        Yazici.WriteLine("BEGIN:VEVENT");

 

        Yazici.WriteLine("DTSTART:" + BasTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("DTEND:" + SonTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("LOCATION:" + Konum);

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + Detay);

        Yazici.WriteLine("SUMMARY:" + Konu);

 

        Yazici.WriteLine("PRIORITY:3");

 

        Yazici.WriteLine("BEGIN:VALARM");

        Yazici.WriteLine("TRIGGER:-PT30M");

        Yazici.WriteLine("ACTION:DISPLAY");

        Yazici.WriteLine("DESCRIPTION:" + Konu);

        Yazici.WriteLine("END:VALARM");

 

        Yazici.WriteLine("END:VEVENT");

        Yazici.WriteLine("END:VCALENDAR");

 

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs");

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString());

        context.Response.BinaryWrite(BirStream.ToArray());

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }

 

}

Hepinize kolay gelsin.