Alper Konuralp

Kartınızı Oluşturun
Google+
Follow @alperkonuralp

Archive for the ‘Microsoft.Net’ Category

Asp.Net MVC Veri Aktarım Elemanı

Merhaba, MVC ile site geliştiriyorsanız benim karşılaştığım durum ile sizde karşılaşabilirsiniz. Burada olay şöyle gelişiyor:

1. Kişi yeni veri giriş ekranında bir veri giriyor.
2. sistem verinin doğruluğundan emin olduktan sonra veriyi veri tabanına kaydediyor.
3. sonrada işlem listeleme sayfasına devrediliyor.

bu işleme kod olarak baktığımızda :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public class Ornek : Controller
    {
        public ActionResult Index()
        {
            var veriler = VeriKaynagi.VerileriAl();
            return View(veriler);
        }
        public ActionResult Yeni()
        {
            return View(new Veri());
        }

        [HttpPost]
        public ActionResult Ekle(Veri veri)
        {
            if (!ModelState.IsValid)
            {
                return View("Yeni", veri);
            }
            // veriyi veri tabanına kaydeden kodlar

            return RedirectToAction("Index");
        }
    }

Şimdi yapmamız gereken veri doğru olarak kaydedildiğine dair bir bilgiyi sayfaya göndermek istiyorum. Ama bunuda yapıyı bozmadan yapmam lazım. O zaman ilk aklıma ViewBag kullanmak geldi ve kodu şöyle düzelttim :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public class Ornek : Controller
    {
        public ActionResult Index()
        {
            var veriler = VeriKaynagi.VerileriAl();
            return View(veriler);
        }
        public ActionResult Yeni()
        {
            return View(new Veri());
        }

        [HttpPost]
        public ActionResult Ekle(Veri veri)
        {
            if (!ModelState.IsValid)
            {
                return View("Yeni", veri);
            }
            // veriyi veri tabanına kaydeden kodlar
            ViewBag.EkMesaj = "Veriler Başarıyla Kaydedilmiştir.";
            return RedirectToAction("Index");
        }
    }

Çok zekice gelmişti bana ama maalesef kod çalışmadı. Daha doğrusu çalıştı ama ViewBag.EkMesaj her durumda boş geldi. Böyle olunca da Böyle Gitmez Söz Google’da dedim ve bir arama yaptım. Bu tür konularda çoğunlukla karşıma çıkan Stack Overflow‘da aradığım cevabı buldum.
Burada ViewBag’in doğru nokta olmadığı ve bunun yerine TempData elemanının kullanılması gerektiği yazıyordu. Böylece özellikle Redirect işlemlerinde ilk sayfa ikinci sayfaya bir data aktarabiliyordu. İlgili link bu.

O zaman çözüm şöyle olacak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public class Ornek : Controller
    {
        public ActionResult Index()
        {
            var veriler = VeriKaynagi.VerileriAl();
            return View(veriler);
        }
        public ActionResult Yeni()
        {
            return View(new Veri());
        }

        [[HttpPost]]
        public ActionResult Ekle(Veri veri)
        {
            if (!ModelState.IsValid)
            {
                return View("Yeni", veri);
            }
            // veriyi veri tabanına kaydeden kodlar
            TempData.Add("EkMesaj", "Veriler Başarıyla Kaydedilmiştir.");
            return RedirectToAction("Index");
        }
    }

İyide ön tarafı nasıl yazarız derseniz… ben biraz atraksiyonlu yazdım. Adım adım bakalım. Önce mesajın gözükeceği yeri ayarlamamız lazım. genel geçer bir durum olsun diye ben bu elemanı master layout içine aldım. <body> tagından önceye şöyle bir kod ekledim:

1
2
    @if (TempData.ContainsKey("EkMesaj"))
    {<div id="dEkMesaj">@TempData["EkMesaj"]</div>}

böylece mesaj geldiğinde böyle gözükecek. Bu elemanın görüntü özellikleri için css’e aşağıdakini ekledim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#dEkMesaj
{
    display: none;
    position: fixed;
    top: 0;
    left: 50%;
    margin: 0 0 0 -100px;
    width: 200px;
    background: yellow;
    color: black;
    border: 1px solid darkorange;
    border-top: 0;
    text-align: center;
}

iyi gidiyoruz ama daha bitmedi. Birde olayın atraksiyon tarafını halleden sevgili javascript kodumuz var. Doğal olarak jquery kullanıyoruz:

1
2
3
4
5
6
7
8
9
$(function () {
        if ($('#dEkMesaj').length &gt; 0) {
            $('#dEkMesaj')
                .css({"opacity": 0, "display":"block"}) // görünmez elemanı önce görünür ama görünmez yapıyoruz :D
                .animate({ opacity: 1 }, 500) // sonrada yarım saniyede görünür hale geliyor.
                .delay(3000) // 3 saniye görüntüde kalıyor
                .animate({ opacity: 0 }, 1000, function () { $('#dEkMesaj').hide(); }); // sonrada görüntüden 1 saniyede çıkıyor.
        }
    });

bu mudur? bence budur.
Kolay gele…

Gmail SMTP Ayarları

Gmail üzerinden  email göndermek için web.config veya app.config dosyalarında yapmanız gereken değişiklik aşağıdadır.

1
2
3
4
5
6
7
8
9
10
11
<system.net>
  <mailSettings>
    <smtp from="[E-mail adresiniz]@gmail.com" deliveryMethod="Network">
      <network host="smtp.gmail.com"
                      enableSsl="true"
                      userName="[E-mail adresiniz]@gmail.com"
                      password="[Şifreniz]"
                      port="587"/>
    </smtp>
  </mailSettings>
</system.net>

Ancak bu şekilde gmail üzerinden email gönderebiliyorsunuz.

NHibernate’te Char tipleri ile çalışmak

NHibernate string olarak tanımladığımız özellikleri veri tabanında nvarchar veya varchar2 gibi tiplerde oluşturuyor veya arıyor. ama benim bir projemde denk geldiği şekilde char türündeki bir tablo alanı ile çalışmak gerektiğinde ne yapabiliriz diye bir araştırma yaptığımda açıkçası biraz hayal kırıklığına uğradım. Nesnesel olarak olayı çözemiyoruz gibi. Bunun yerine sql düzeyinde bir çalışma yapmak lazım. Şöyle ki:

1
public virtual string TelephoneNumber {get; set; }

şeklinde tanımlanmış alanım için,

1
2
3
4
Map(x=> x.TelephoneNumber)
    .Length(4)
    .CustomSqlType(CHAR(10))
    .Nullable();

şeklinde bir mapping satırı yazmam gerekmekte. allahtan char tipi bütün veri tabanı sistemlerinde aynı kullanıma sahipte herhangi bir problem çıkarmadan çapraz platform çalışabiliyor.

NHibernate Fluent ile tek tablodan birden fazla nesne

Diyelim ki bir sınıftan türemiş birden fazla sınıfınız var. Ve bunları fluent arayüzünü kullanarak NHibernate içinde kullanmak istiyorsunuz. Bunun için öncelikle http://wiki.fluentnhibernate.org/Fluent_mapping adresini ziyaret edip, buradan bilgi edinebilirsiniz. Ancak maalesef yetersiz bir bilgiye sahip olacaksınız. Burada olay çok kısa ve yüzeysel olarak verilmiş. ben konuyu biraz daha ileri götürmek istiyorum. Öncelikle sınıflarımınızı tanımlayalım.

 

Önce temel sınıfımız. NHibernate bu sınıf için bir tablo üretecek.

1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class EKayit
{
    public virtual int KayitID { get; set; }

    public virtual KayitTipi KayitTipi { get; set; }

    public virtual string DosyaAdi { get; set; }

    public virtual byte[] Icerik { get; set; }

    public virtual string MimeType { get; set; }

}

 

Şimdide alt sınıflarımızı tanımlayalım.

1
2
3
4
5
public class ESesKayit : EKayit { }

public class EVideoKayit : EKayit { }

public class EDigerKayit : EKayit { }

 

birde dikkat ettiyseniz alt sınıfın tiplerini tutan bir enum tipimiz var. buda :

1
2
3
4
5
6
public enum KayitTipi  : byte
{
    Ses = 1,
    Video = 2,
    Diger = 4
}

şeklinde tanımlanmış olsun. Şimdi gelelim mapping sınıflarımıza. Önce EKayit ile başlıyoruz :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class EKayitMap : ClassMap<EKayit>
{
    public EKayitMap()
    {
        Table("TKayit");

        Id(x => x.KayitID)
            .Not.Nullable()
            .GeneratedBy.Native();

        DiscriminateSubClassesOnColumn<byte>("KayitTipi", (byte)KayitTipi.Ses)
            .CustomType<KayitTipi>()
            .Not.Nullable();

        Map(x => x.DosyaAdi)
            .Length(100)
            .Not.Nullable();

        Map(x => x.Icerik)
            .Not.Nullable()
            .Length(int.MaxValue)
            .LazyLoad();

        Map(x => x.MimeType)
            .Length(50)
            .Not.Nullable();
    }
}

Dikkat edilmesi gereken en önemli yer DiscriminateSubClassOnColumn tanımı. Burada yanlış tanımlama yaptığınızda şu türde hata mesajları alabiliyorsunuz :

 

1
2
[ArgumentException: Requested value 'CD.DataLayer.Entities.EKayit' was not found.]
[MappingException: Could not format discriminator value to SQL string of entity CD.DataLayer.Entities.EKayit]

 

Bu hataları alınca internette arayışa geçtim. sonunda http://stackoverflow.com/questions/326174/nhibernate-mapping-with-a-class-hierarchy-whose-base-class-is-abstract-and-the-d adresi aradığımı bulmamı sağladı.

 

Önce problemi anlatayım : Entity sınıfından da gördüğünüz gibi, KayitTipi alanını KayitTipi enum türünden tanımlamışım. Bu özel bir tip olduğu için burada nhibernate’e bu tipin neye karşılık geleceğini bildirmek gerekiyor. bunun için 2 yöntem var esasında. 1. yöntem  DiscriminateSubClassOnColumn metodunun jenerik halini kullanmak DiscriminateSubClassOnColumn<byte> şeklinde. böylece sisteme bu elemanın tipini bildiriyorsunuz. 2. yöntem ise DiscriminateSubClassOnColumn metoduna 2. parametreyi atamak. bu parametre yine jenerik metodun tipini belirlediği için esasında 1. yönteme çıkıyor olay. Ben yukarıda bunun ikisini bir arada kullandım.

Şimdi gelelim alt sınıfların mappinglerine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ESesKayitMap : SubclassMap<ESesKayit>
{
    public ESesKayitMap()
    {
        DiscriminatorValue((byte)KayitTipi.Ses);
    }
}

public class EVideoKayitMap : SubclassMap<EVideoKayit>
{
    public EVideoKayitMap()
    {
        DiscriminatorValue((byte)KayitTipi.Video);
    }
}

public class EDigerKayitMap : SubclassMap<EDigerKayit>
{
    public EDigerKayitMap()
    {
        DiscriminatorValue((byte)KayitTipi.Diger);
    }
}

 

Burada önemli olan kısım ise alt sınıfların ClassMap’ sınıfından değilde, SubclassMap sınıfından türetilmeleri. Ayrıca ayırıcı alanda hangi değerin olması gerektiği bu sınıfların yapıcılarında da verilmiş durumda. Tiplerin yine çevirildiğine dikkat edelim.

 

Böylece işlemi bitirmiş olduk.

Entity Framework 4.1 Code First ile Ağaç Yapısındaki Tablolar

Entity Framework 4.1 Code First mimarisini kullanırken çalıştığınız projede karşınıza ağaç yapısında bir elemana ihtiyacı doğmuş olabilir. Ki benim başıma böyle bir durum geldi. Normal yollarla bu problemi çözmeye çalıştığınızda karşınıza büyük bir problem çıkabiliyor. O zaman nasıl bir çözüm yolu var diye araştırırken sevgili StackOverflow’da amcanın biri bu konuda bir soruyu cevaplayarak benimde problemimi çözmüş. Burada paylaşmak istedim. Konu şu : Self-referencing many-to-many relationship code first Entity Framework .

Şimdi önce isterseniz olayı bir anlatayım. Bildiğiniz gibi ağaç yapısı karşımıza hiyerarşik yapılarda çıkmakta. Mesela  kategoriler, organizasyon şemaları gibi. Bu tür yapıları veri tabanında tutarkende, tablolarımızda kendi kendine bağlı yapılar oluşturmak zorunda kalıyoruz. Sql açısından baktığınızda tablonuz içerisine tablonun Primary Key’i ile aynı tipte bir kolon daha yerleştirdiğinizde, ağaç yapısını hazırlamış oluyorsunuz. Ama bu işi Entity Framework ile nasıl modelleyeceğiz. Cevap biraz karmaşık olabilir.

using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;

    /// <summary>
    /// Category Entity
    /// </summary>
    [Table("TCategory", Schema = "Products")]
    [DataContract]
    public class ECategory
    {
        /// <summary>
        /// Gets or sets the category ID.
        /// </summary>
        /// <value>
        /// The category ID.
        /// </value>
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column(Order = 1)]
        [DataMember]
        public virtual int CategoryID { get; set; }

        /// <summary>
        /// Gets or sets the parent ID.
        /// </summary>
        /// <value>
        /// The parent ID.
        /// </value>
        [Column(Order = 2)]
        [DataMember]
        public virtual int? ParentID { get; set; }

        /// <summary>
        /// Gets or sets the name resource ID.
        /// </summary>
        /// <value>
        /// The name resource ID.
        /// </value>
        [Required]
        [Column(Order = 4)]
        [DataMember]
        public virtual string Name { get; set; }

        /// <summary>
        /// Gets or sets the sort order number.
        /// </summary>
        /// <value>
        /// The sort order number.
        /// </value>
        [Required]
        [Column(Order = 5)]
        [DataMember]
        public virtual int SortOrderNumber { get; set; }

        /// <summary>
        /// Gets or sets the timestamp.
        /// </summary>
        /// <value>
        /// The timestamp.
        /// </value>
        [Timestamp]
        [Column(Order = 7)]
        [DataMember]
        public virtual byte[] Timestamp { get; set; }

        /// <summary>
        /// Gets or sets the parent.
        /// </summary>
        /// <value>
        /// The parent.
        /// </value>
        [ForeignKey("ParentID")]
        public virtual ECategory Parent { get; set; }

        /// <summary>
        /// Gets or sets the children.
        /// </summary>
        /// <value>
        /// The children.
        /// </value>
        public virtual ICollection<ECategory> Children { get; set; }

    }

Yapımız böyle. Dikkat ederseniz yapı kendi içinde birbirine bağlanmış durumda. Böylece Ağaç yapısı tesis edilmiş oluyor. Bu yapıyı bu şekilde bırakırsanız o zaman maalesef ki veri girişinde hata ile karşılaşabiliyoruz. Çünkü ParentID’yi null içeremeyecek şekilde ayarlanmamış oluyor. Yani root elementi giremiyorsunuz. root olmayıncada hiç birşey olmuyor tabi. Bu problemi nasıl çözüyoruz. Şimdide buna bakalım. Öncelikle hatırlatmak isterim ki, Attribute’lar ile birçok ince ayarı yapmak mümkün değil bu yüzden bu ayarları yapabilmek için bize override edeceğimiz bir metod sunulmuş. Bu yapıyı kullanabilmek için yazdığımız DataContext sınıfı içerisinde yer alıyor. Şimdi ona bakalım.

using System.Data.Entity;
using System.Linq;

    public class WebContext : DbContext
    {

        /// <summary>
        /// Gets or sets the categories.
        /// </summary>
        /// <value>
        /// The categories.
        /// </value>
        public DbSet<ECategory> Categories { get; set; }

        /// <summary>
        /// This method is called when the model for a derived context has been initialized, but
        /// before the model has been locked down and used to initialize the context.  The default
        /// implementation of this method does nothing, but it can be overridden in a derived class
        /// such that the model can be further configured before it is locked down.
        /// </summary>
        /// <param name="modelBuilder">The builder that defines the model for the context being created.</param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<ECategory>()
                .HasOptional(x => x.Parent)
                .WithMany(x => x.Children)
                .HasForeignKey(x => x.ParentID)
                .WillCascadeOnDelete(false);

            // modelBuilder.Entity<ECategory>()
                // .HasRequired(x => x.Children)
                // .WithMany()
                // .HasForeignKey(x => x.ParentID)
                // .WillCascadeOnDelete(false);

            base.OnModelCreating(modelBuilder);
        }

        #endregion Methods
    }

Dikkat ederseniz override ettiğimiz metod OnModelCreating. Adından da anlaşılıyor zaten :) . Şimdi burada ne oluyor, Sistem attribute’lardan bazı bilgileri alıp toparlıyor ama dediğim gibi bazı ayarlar attribute’lar ile yapılamadığı için biz tam bu noktada bu ayarları yapıyoruz. Mesela

            modelBuilder.Entity<ECategory>()
                .HasOptional(x => x.Parent)
                .WithMany(x => x.Children)
                .HasForeignKey(x => x.ParentID)
                .WillCascadeOnDelete(false);

satırında ECategory entity’sini alıp, bunun içindeki Children property’sini many to many bağlantısı ile konfigüre etmiş oluyoruz. Böylece herşey tam olarak istediğimiz şekilde oluyor.
Yorum satırı şeklindeki kısımda ise önceki ayarlar yer alıyor. Bu aradaki bağlantının one to many şeklinde olması ve cascade işleminin delete için uygulanmaması sağlanmış olmakta.

İzmir Yazılım Grubu
Google Groups
Subscribe to İzmir Yazılım Grubu
Email:
Visit this group
Mayıs 2012
Pts Sal Çar Per Cum Cts Paz
« Şub    
 123456
78910111213
14151617181920
21222324252627
28293031  
Yeni Downloadlar
StatPress
Visits today: 95
Sahip oldugum diger adresler :
3dmaxtraining.info
3dmaxtrainings.com
3dmaxtrainings.info
adobelearning.info
adobelearnings.info
adobetrainings.com
adobetrainings.info
autocadbootcamp.info
autocadexams.info
autodesklearning.info
autodesklearnings.com
autodesklearnings.info
ciscotrainings.info
egepro.com
elonunbahcesi.com
elonunbahcesi.info
flashbootcamp.info
flashexams.com
flashexams.info
konuralp.biz
konuralp.org
mayatutorial.info
mayatutorials.info
microsoftexams.info
microsofttrainings.info
proege.com
sharepointlearning.info
sharepointlearnings.com
sharepointlearnings.info
sharepointtutorial.info
silverlightbootcamp.info
silverlightlearning.info
silverlightlearnings.info
silverlighttraining.info
silverlighttrainings.com
silverlighttrainings.info
silverlighttutorial.info
silverlighttutorials.info
sirasende.info
urunbul.info
yagmurca.com
yagmurca.info