C# etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
C# etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

7 Mayıs 2015 Perşembe

C# Code for Downloading WeTransfer Files (https://www.wetransfer.com/)

I was doing an asp.net web application project and I needed to download files from WeTransfer. I have searched web but couldn't found any C# code about this topic. Then i found a Phyton code (Link: https://github.com/superalex/py-wetransfer) and convert it to C# by myself. Just dropping the dirty code here as in my project.(with some minor changes :)) You can clear and use the code as you wish.


using Newtonsoft.Json;

using Newtonsoft.Json.Linq;

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.IO;

using System.Net;

using System.Net.Http;

using System.Web;

using System.Web.UI;

 

private const string DOWNLOAD_URL_PARAMS_PREFIX = "downloads/";

private const int CHUNK_SIZE = 1024;

 

protected async void btnDownloadWeTransferFile_Click(object sender, EventArgs e)

        {

            if (string.IsNullOrWhiteSpace(txtFileLink.Text))

            {

                ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "Link is empty!" + "\");", true);

                return;

            }

 

            HttpClient client = new HttpClient();

            HttpResponseMessage response = await client.GetAsync(txtFileLink.Text);

            response.EnsureSuccessStatusCode();

            string responseUri = response.RequestMessage.RequestUri.ToString();

 

            if (!responseUri.Contains("www.wetransfer.com"))

            {

                ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "Make sure the file link is a WeTransfer file link!" + "\");", true);

                return;

            }

 

            string fileID = "", recipientID = "", securityHash = "";

 

            if (!responseUri.Contains(DOWNLOAD_URL_PARAMS_PREFIX))

            {

                ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "File link is in an unknown format!" + "\");", true);

                return;

            }

            else

            {

                string[] splittedLink = responseUri.Split(new string[] { DOWNLOAD_URL_PARAMS_PREFIX }, StringSplitOptions.RemoveEmptyEntries);

                if (splittedLink.Length < 2)

                {

                    ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "File link is in an unknown format!" + "\");", true);

                    return;

                }

                else

                {

                    string[] parameters = splittedLink[1].Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

                    if (parameters.Length < 2 || parameters.Length > 3)

                    {

                        ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "File link is in an unknown format!" + "\");", true);

                        return;

                    }

                    else

                    {

                        if (parameters.Length == 2)

                        {

                            fileID = parameters[0];

                            securityHash = parameters[1];

                        }

                        else

                        {

                            fileID = parameters[0];

                            recipientID = parameters[1];

                            securityHash = parameters[2];

                        }

                    }

                }

            }

 

            string directDownloadLink = "";

 

            WebClient wc = new WebClient();

            string jsonString = wc.DownloadString(string.Format("https://www.wetransfer.com/api/v1/transfers/{0}/download?recipient_id={1}&security_hash={2}&password=&ie=false", fileID, recipientID, securityHash));

 

            var stringData = (JObject)JsonConvert.DeserializeObject(jsonString);

            byte[] data = null;

            string fileName;

 

            if (stringData.GetValue("direct_link") != null)

            {

                directDownloadLink = stringData["direct_link"].Value<string>();

                directDownloadLink = HttpUtility.UrlDecode(directDownloadLink);

 

                int oIndex = directDownloadLink.IndexOf("filename=");

                string subStr = directDownloadLink.Substring(oIndex + 9);

                fileName = directDownloadLink.Substring(oIndex + 9, subStr.IndexOf(";")).Replace("\"", "");

 

                wc.UseDefaultCredentials = true;

 

                data = wc.DownloadData(directDownloadLink);

            }

            else

            {

                fileName = stringData["fields"]["filename"].Value<string>();

                NameValueCollection myNameValueCollection = new NameValueCollection();

                Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(stringData.GetValue("fields").ToString());

                foreach (var kvp in dict)

                {

                    myNameValueCollection.Add(kvp.Key.ToString(), kvp.Value.ToString());

                }

                data = wc.UploadValues(stringData["formdata"]["action"].Value<string>(), myNameValueCollection);

            }

 

            string filePath =  "C:\\" + fileName;

            if (File.Exists(filePath))

            {

                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);

                string fileNameExtension = Path.GetExtension(fileName);

                fileName = fileNameWithoutExtension + DateTime.Now.ToString("yyyyMMddHHmmssfff") + fileNameExtension;

            }

 

            using (FileStream fs = new FileStream(filePath, FileMode.Create))

            {

                fs.Write(data, 0, data.Length);

            }

 

            ClientScript.RegisterClientScriptBlock(GetType(), "alertMessage", "alert(\"" + "File downloaded successfully. File Name:" + fileName + "\");", true);

 

        }

10 Ekim 2014 Cuma

InvokeRequired nedir?

En basit anlamıyla; Bir windows kontrolünün metoduna, kontrolün yaratıldığı threadin dışında başka bir thread üzerinden erişilmeye çalışıldığında, erişim için bir invoke methoduna ihtiyaç duyup duymadığını belirten bir değerdir.

Eğer kontrol başka bir thread üzerinde yaratılmışsa true döner aksi halde false döner.

Windows Forms ta kontroller belli bir thread'e bağlıdır ve thread safe değillerdir. (Hayda thread safe ne yahu?)
Thread Safe: Bir kaynağa veya fonksiyona herhangi bir zamanda sadece bir tek threadin erişimini garanti etmek gibi diyebiliriz. Bir banka hesabı düşünün ToplamPara adında bir değişkeni olsun ve bu değişkenin değeri 100 olsun. 2 kişi aynı anda bu banka hesabı üzerinde işlem yapıyor diyelim. Birinci kişi 100 lira para çekmeye çalışsın diğer kişide 100 lira para yatırmaya çalışsın. Her ikisi de aynı anda işlem yapmaya çalıştığı için ekranda 100 lira değerini görüyor. Eğer hesapta bulunan toplam para değerine erişimi bir hizaya dizmez ise birinci kişi 100 lira çektiğinde ToplamPara değişkeninin değerini 0 (ToplamPara - 100 = 0) olarak değiştirir . İkinci kişi ise bu değişkeni 200(ToplamPara + 100 = 200) olarak değiştirir. Sonuçta hesabın ToplamPara değeri 200 olur ama doğrusu 100 olmalıydı. İşte bunun olmaması için iki kişinin ToplamPara değişkenine aynı anda erişimini engellemeliyiz. İşte Windows forms kontrolleri bunu sağlamayı garanti etmediği için thread safe değillerdir.

InvokeRequired property'sine ek olarak thread safe olan 4 tane method bulunmaktadır. Bunlar: Invoke, BeginInvoke, EndInvoke and CreateGraphics metodlarıdır.

Eğer kontrolün handle'ı henüz oluşturulmamışsa InvokeRequired, window handle'ı elinde bulunduran form veya window'u bulana kadar kontrolün parentlarını aramaya başlar. Eğer bulamazsa false değeri döner.
Bunun anlamı, ya kontrolün methoduna erişmek için Invoke kullanmaya gerek yoktur (kontrolün metoduna kontrolün yaratıldığı threadden ulaşılmaya çalışılmaktadır.) ya da kontrol başka bir thread üzerinde yaratılmıştır ama kontrolün handle ı henüz oluşturulmamıştır. (Bir de böyle bişey var malesef!)
Böyle kontrolün handle'ının henüz oluşturulmadığı durumlarda kontrolün property,metod ve eventlerine ulaşmaya çalışmayınız. Çünkü siz ulaşmaya çalıştığınızda handle henüz yeni oluşturuluyor olabilir.
Böyle durumlarda IsHandleCreated propertysinide kontrol etmeniz gerekmektedir. Handle henüz yaratılmamışsa, Invoke ya da BeginInvoke methodunu handle yaratılana kadar çağırmayınız. Bu senaryo çok fazla karşınıza çıkmaz eğer background threadi formun constructorunda oluşturmuyorsanız ya da yada formu göstermeden önce çağırmıyorsanız.

Bunun çözümü ya handle yaratılana kadar bekleyeceksiniz ya da Handle propertysini çağırarak zorla yaratılmasını sağlayacaksınız.

Umarım InvokeRequired nedir, anlayabilmiş ve anlatabilmişimdir.

24 Mayıs 2012 Perşembe

C# Reflection Field Example


You have a class with instance or static fields of any type in your C# program and want to loop through those fields and display their names and values. The System.Reflection namespace in the .NET Framework provides a powerful and maintainable way to enumerate fields and properties. We see how you can loop through fields using reflection.

Example

In the .NET Framework, every program is compiled into an assembly containing metadata, which is an abstract binary representation of the program's structure. This improves the options you have when executing your program, as you can explore the string data stored in the executable to access field and property names.
This example demonstrates a static class with four fields of type Int32 and String. It obtains the FieldInfo objects for those fields and then displays them in a public method.

This C# example program uses reflection on fields in a static class.
Program that uses reflection on fields [C#]

using System;
using System.Reflection;

static class ReflectionTest
{
    public static int Height;
    public static int Width;
    public static int Weight;
    public static string Name;

    public static void Write()
    {
 Type type = typeof(ReflectionTest); // Get type pointer
 FieldInfo[] fields = type.GetFields(); // Obtain all fields
 foreach (var field in fields) // Loop through fields
 {
     string name = field.Name; // Get string name
     object temp = field.GetValue(null); // Get value
     if (temp is int) // See if it is an integer.
     {
  int value = (int)temp;
  Console.Write(name);
  Console.Write(" (int) = ");
  Console.WriteLine(value);
     }
     else if (temp is string) // See if it is a string.
     {
  string value = temp as string;
  Console.Write(name);
  Console.Write(" (string) = ");
  Console.WriteLine(value);
     }
 }
    }
}

class Program
{
    static void Main()
    {
 ReflectionTest.Height = 100; // Set value
 ReflectionTest.Width = 50; // Set value
 ReflectionTest.Weight = 300; // Set value
 ReflectionTest.Name = "Perl"; // Set value
 ReflectionTest.Write(); // Invoke reflection methods
    }
}

Output

Height (int) = 100
Width (int) = 50
Weight (int) = 300
Name (string) = Perl

27 Temmuz 2011 Çarşamba

C# Generic Sınıflara Giriş #2

Generics Nedir

Generics size tip-güvenliği ve performansı düşünmeden generic sınıflar yapabilmenizi sağlar.Sunucuyu yanlızca bir kere generic sunucu olarak implement edersiniz, aynı zamanda istediğiniz tip için kullanabilrsiniz. Bunu yapabilmek için < ve > parantezlerinin içine kullanacağımız tipi yazarız. Mesela aşağıda bir generic stack yapısının nasıl olduğu  görülmektedir:


public class Stack
{
   T[] m_Items; 
   public void Push(T item)
   {...}
   public T Pop()
   {...}
}
Stack stack = new Stack();
stack.Push(1);
stack.Push(2);
int number = stack.Pop();
Kod Blok 2 generic stack yapısını göstermektedir.  Kod Blok 1 ile Kod Blok 2 yi karşılaştırın göreceksiniz ki, Stack tanımı haricindeki her yerde  Code block 1 deki object yerine Kod Blok 2, ye T yerleştirilmiştir:
public class Stack
{...}
Generic stack yapısını kullanırken compiler ı generic parametre olan T yerine hangi tipin kullanılacağını hem stack yapısını tanımlarken hemde başlatırken bilgilendirmemiz gerekiyor:

Stack stack = new Stack();
Compiler ve runtime geri kalan herşeyi yapar.
Kod Blok 2. Generic Stack Yapısı
public class Stack
{
   readonly int m_Size; 
   int m_StackPointer = 0;
   T[] m_Items;
   public Stack():this(100)
   {}
   public Stack(int size)
   {
      m_Size = size;
      m_Items = new T[m_Size];
   }
   public void Push(T item)
   {
      if(m_StackPointer >= m_Size) 
         throw new StackOverflowException();
      m_Items[m_StackPointer] = item;
      m_StackPointer++;
   }
   public T Pop()
   {
      m_StackPointer--;
      if(m_StackPointer >= 0)
      {
         return m_Items[m_StackPointer];
      }
      else
      {
         m_StackPointer = 0;
         throw new InvalidOperationException("Cannot pop an empty stack");
      }
   }
}

17 Haziran 2011 Cuma

C# Static Constructor

C# ta static constructor için performans değerlendirmesi: Microsoft ve birçok kod geliştirici static constructorların ciddi bir yük getirdiği konusunda uyarıyorlar. Static constructorlara aynı zamanda type initializer de denir, çünkü bunlar tiplere referans verirler, instancelara değil. Aşağıda C# dilinde static constructorlar için yapılan test bulunmaktadır. Hangisinin yararlı olduğuna karar verebilirsiniz.


Örnek

Aşağıda static contructoru bulunan ve bulunmayan olarak iki sınıf bulunmaktadır. Kullandığınız çoğu sınıfın static constructoru yoktur. Sonuca göre static constructorlar tipe her ulaştığınızda ciddi bir yavaşlamaya sebep oluyor.

Static Constructor a sahip bir class [C#]

/// /// Bu tip static constructora sahiptir.
/// 
static class HasStaticConstructor
{
    ///     /// Public field
    ///     public static int _test;

    ///     /// Static constructor public alanı initialize eder
    ///     static HasStaticConstructor()
    {
 _test = 1;
    }
}

Static Constructoru olmayan bir class [C#]

/// /// Bu tip static constructora sahip değildir.
/// 
static class NoStaticConstructor
{
    ///     /// Public field initialize edilir
    /// 
    public static int _test = 1;
}

Benchmark (Karşılaştırmalı Test) notları

Döngü: 1000000000
Detaylar:    _text alanı her döngüde erişilir.

Static constructor performans testi

Sınıf 1: Static constructoru olan
Zaman:    3208 ms

Sınıf 2: Static constructoru olmayan
Zaman:     319 ms

Özet

Static constructor kullanmak uygun olabilir, ama çok yavaşlar.Runtime bunları inline atamaları optimize edebildiği yolla optimize edecek kadar akıllı değil. Bazen lazy loading kullanmak uygun olabilir. ( Lazy Loading: bir değişkenin her erişildiğinde null kontrolü yapılıp eğer null ise initialize etmek).

21 Mayıs 2011 Cumartesi

Generic Kullanımı #1

Generic Kullanımı


Generic tipleri sınıflar ve struct lar için kullanabilirsiniz. İşte size faydalı bir generic point (nokta) yapısı:

public struct Point
{
   
   public T X;
   
   public T Y;
}


Generic nokta (point) yapısını integer koordinatlar için kullanabilirsiniz. Örneğin:

Point point;
point.X = 1;
point.Y = 2;


Veya double tipinde koordinatlar için:

Point point;
point.X = 1.2;
point.Y = 3.4;


Şimdiye kadar generic tiplerin temel kullanımını gördük. C# 2.0 ın bazı generice özel syntax yapısıda vardır. Mesela  default() operatörü kullanılan tipin default değerini döndürür. Örneğin stack yapısında listeden pop yapmak istediğimizde kullandımız Pop() methodunu inceleyelim ve stackın boş olduğu durumlarda default bir değer döndermek isteyelim:

public T Pop()
{
   m_StackPointer--;
   if(m_StackPointer >= 0)
   {
      return m_Items[m_StackPointer];
   }
   else
   {
      m_StackPointer = 0;
      return default(T);
   }
}

Referans tipleri için default değer null dır ve value tipleri için default değer 0 dır.

Çoklu Generic Tipleri

Örneğin aşağıdaki gibi bir generic bağlı liste düşünelim:

Kod Blok 3. Generic Bağlı Liste


class Node
{
   public K Key;
   public T Item;
   public Node NextNode;
   public Node()
   {
      Key      = default(K);
      Item     = defualt(T);
      NextNode = null;
   }
   public Node(K key,T item,Node nextNode)
   {
      Key      = key;
      Item     = item;
      NextNode = nextNode;
   }
}

public class LinkedList
{
   Node m_Head;
   public LinkedList()
   {
      m_Head = new Node();
   }
   public void AddHead(K key,T item)
   {
      Node newNode = new Node(key,item,m_Head.NextNode);
      m_Head.NextNode = newNode;
   }
}

Bağlı liste düğümleri (node) depolar:

class Node
{...}


Her bir düğüm bir anahtar (Generic tip parametresi K) ve bir değer tutar (Generic tip parametresi T). Aynı zamanda her bir düğüm bir sonraki düğüme referans verir. Bağlı listeler generic tip parametreleri K ve T ile tanımlanır:

public class LinkedList
{...}


Bu sayede AddHead() gibi generic methodlar ortaya çıkar:

public void AddHead(K key,T item);


Ne zaman generic tipinde bir değişken tanımladığınızda, kullanacağınız tipleri belirlemek zorundasınız. Ama belirlenen tip argümanları kendileride bir generic tip olabilirler. Örneğin, bağlı liste m_Head adında Node tipinde bir değişkene sahip. Bu listedeki ilk elemana referans veriyor. Aynı zamanda generic tipler olan K ve T ile tanımlanmış.


Node m_Head;


Bir düğümün instance ını oluştururken argümanların tipini belirtmelisiniz., bunun içinse bağlı listenin generic tiplerini kullanabilirsiniz:


public void AddHead(K key,T item)
{
   Node newNode = new Node<K,T>(key,item,m_Head.NextNode);
   m_Head.NextNode = newNode;
}

Not olarak söyleyelim liste ile node aynı isimlerde generic tipler kullanıyor. Bu sadece okunabilirliği kolaylaştırma açısından bu şekilde yazılmıştır. Aşağıdaki şekillerdede kullanılabilir:

public class LinkedList
{...}


Veya:

public class LinkedList
{...}


Listenin örnek kullanımı olarak key ler için integer value lar için string kullanmak istersek:


LinkedList list = new LinkedList();
list.AddHead(123,"AAA");


İsteyen başka şekillerdede kullanabilir:


LinkedList list = new LinkedList();
list.AddHead(DateTime.Now,"AAA");   


Bazen alias kullanmak faydalı olabilir.Bu şekilde bir kullanım sizi kod tekrarından kurtarabilir.

Kod Blok 4. Generic tip alias


using List = LinkedList;

class ListClient
{
   static void Main(string[] args)
   {
      List list = new List();
      list.AddHead(123,"AAA");
   }
}

2 Mayıs 2011 Pazartesi

C# Generic Sınıflara Giriş #1

Giriş

Generic sınıflar C# 2.0 'ın en güçlü özelliğidir. Generic sınıflar size type-safe veri yapıları tanımlamanızı sağlar. Bu size  yüksek performans ve kaliteli kod yazmanızı sağlar. Çünkü yazdığınız kodu başka tip verilere uygun olarak tekrardan yazmadan kullanabilmenizi sağlar. Konsept olarak C++ taki templatelere benzer ama uygulama ve yapabilecekleri açısından oldukça farklıdır. Bu makalede bu yapının faydaları, neden ihtiyaç olduğu ve nasıl kullanılacağı konusuna   bir başlangıç yapılacaktır.

Generic Sınıflar Problem Aşaması

Klasik Push() ve Pop() metodları sağlayan bir stack veri yapısını düşünün. Genel amaçlı bir stack veri yapısı geliştirirken, onu değişik tiplerde verileri tutmak için kullanmak istersiniz. C# 1.1 de, Object tabanlı stack kullanmak zorundaydınız.


public class Stack
{
   object[] m_Items; 
   public void Push(object item)
   {...}
   public object Pop()
   {...}
}


Kod Blok 1 Object-tabanlı stack yapısının nasıl gerçekleştirildiğini gösteriyor. çünkü Object .Net in en temel veri tipidir. Ve bu sayede istenilen tipte veriler tutabilirsiniz stack veri yapısında. Örneğin integer bir değer için:


Stack stack = new Stack();
stack.Push(1);
stack.Push(2);
int number = (int)stack.Pop();

Kod Blok 1. Object-Tabanlı bir stack yapısı
public class Stack
{
   readonly int m_Size; 
   int m_StackPointer = 0;
   object[] m_Items; 
   public Stack():this(100)
   {}   
   public Stack(int size)
   {
      m_Size = size;
      m_Items = new object[m_Size];
   }
   public void Push(object item)
   {
      if(m_StackPointer >= m_Size) 
         throw new StackOverflowException();       
      m_Items[m_StackPointer] = item;
      m_StackPointer++;
   }
   public object Pop()
   {
      m_StackPointer--;
      if(m_StackPointer >= 0)
      {
         return m_Items[m_StackPointer];
      }
      else
      {
         m_StackPointer = 0;
         throw new InvalidOperationException("Boş stacktan pop yapamazsınız");
      }
   }
}
Ama Object-Tabanlı çözümde 2 problem karşımıza çıkmaktadır. İlk olarak performans sorunu. Dğer tipindeki veri tiplerini kullanırken, önce onu boxing ile object ye çevirip (boxing) stack a atmak daha sonrada onu istediğiniz değer tipine çevirmeniz (unboxing) gerekir. Boxing ve unboxing kendi başına bir performans sorunudur aynı zamanda daha fazla garbage collection manasınada gelir.Referans tipi veriler kullanırkende büyük sıkıntı yaratır. Çünkü bu tipleride Object tipinden  asıl tipe çevirmeniz gerekmektedir:
Stack stack = new Stack();
stack.Push("1");
string number = (string)stack.Pop();
İkinci (ve daha önemli olanı) is tip güvenliğidir. Çünkü derleyici size Object tipinden herhangi bir değeri cast yapabilmenize izin verir. Böylece derlenme zamanı tip güvenliğini kaybedersiniz. Örneğin aşağıdaki kod derlenme sırasında sorun çıkartmaz ama çalışma sırasında hata alırsınız:

Stack stack = new Stack();
stack.Push(1);
//Aşağısı derleme sırasında sorun çıkarmaz ama çalışırken hata alırsınız.
string number = (string)stack.Pop();
Bu problemleri tip-özel stack yaparak aşabilirsiniz. Mesela integer değerler için  IntStack kullanabilirsiniz:

public class IntStack
{
   int[] m_Items; 
   public void Push(int item){...}
   public int Pop(){...}
} 
IntStack stack = new IntStack();
stack.Push(1);
int number = stack.Pop();
String değerler için StringStack:

public class StringStack
{
   string[] m_Items; 
   public void Push(string item){...}
   public string Pop(){...}
}
StringStack stack = new StringStack();
stack.Push("1");
string number = stack.Pop();
Ama bu şekilde performans ve tip-güvenlik problemlerini çözmek bizi üçüncü bir probleme götürür — verimlilik. Tip-Özel veri yapıları yazmak can sıkıcı, aynı şeylerin tekrardan yazılması ve hata eğilimli bir yapıdır. Bir veri yapısındaki hatayı düzeltirken, diğer tipler için tanımlı yapılarıda düzeltmeniz gerekir. Sonuç olarak C# 1.1 geliştiricileri Object-tabanlı veri yapılarının pratik olmadığı ve kullanım özelliğinin kalmadığı sonucuna vardılar.