Üzerinde çalıştığım bir ASP.NET MVC Facebook uygulamasında controllerlar arasında veri taşırken problem yaşadım. Kişiye özel veriler uygulama açık durduğu sürece o kişi için erişilebilir olmalı. Bunun için Session kullandım. Bir Controller'ın Action'ı içinde atadığım Session değerine diğer bir Controller'ın Action'u içerisinden erişmeye çalıştım. Ama localde işe yarayan yöntem Server üzerinde çalışmadı. ViewBag, ViewData, TempData hiçbiri işe yaramıyor. MVC üzerinde Session yerine ne kullanabilirim? Kişiye özel verileri geçici olarak nerede tutabilirim?

soruldu: 28 Ağu '13, 02:50

emrekacan's gravatar image

emrekacan
813304450
cevap kabul oranı: 9%


Kendi yaptığım uygulamalarımda, kullanıcıya ePosta adresinden ulaşarak kullanının istediğim özelliğini uygulamanın her yerinde görebiliyorum. Bunu BaseController ile yapıyorum. Tüm controller sınıfları bu controller da türüyor.

public class BaseController : Controller
{
    private KullaniciServis kullaniciServis;

    public BaseController()
    {
        this.kullaniciServis = new KullaniciServis();
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // buradaki viewbag artık uygulamanın her yerinde geçerli
        ViewBag.AktifKullanici = kullaniciServis.AktifKullanici(KullaniciEposta);
        base.OnActionExecuting(filterContext);
    }

    protected bool KullaniciAktifMi
    {
        get
        {
            return System.Web.HttpContext.Current.User.Identity.IsAuthenticated;
        }
    }

    protected string KullaniciEposta
    {
        get
        {
            return KullaniciAktifMi ? System.Web.HttpContext.Current.User.Identity.Name : null;
        }
    }
}

yukarıdaki controller içerisinde bir ViewBag.AktifKullanici diye bir nesne var. Bu nesneyi uygulamanın herhangibir yerinde çağırabiliriz. Tabi controller sınıflarımız BaseController sınıfını kullanmalı. Örneğin;

public class HomeController : BaseController 
{
    // action methods...
}

Örneğin _LoginPartial.cshtml diye bir partial sayfamız olsun ve kullanıcıyı bu sayfada çağıralım.

@if (Request.IsAuthenticated)
{
    HaberSitesi.Domain.DomainModel.Kullanici kullanici = ViewBag.AktifKullanici;
    <ul>
        <li>
            @Html.ActionLink(kullanici.KullaniciAdi, "Profil", "Account", new { area = "" }, null)
        </li>
        <li>
            @Html.ActionLink("Çıkış", "Cikis", "Account", new { area = "" }, null)
        </li>
    </ul>
}
else
{
    <ul>
        <li>@Html.ActionLink("Kayıt Ol", "KayitOl", "Account")
        </li>
        <li>@Html.ActionLink("Giriş Yap", "GirisYap", "Account")
        </li>
    </ul>
}

Kullanıcı nesnesini istediğimiz sayfada elede edebiliyoruz, dolayısıyla istedigimiz anda login olan kullanıcının istedigimiz özelliğine ulaşabiliyoruz. Aşağıdaki açık kaynak proje içerisinden kodları inceleyebilirsiniz.

ÖRNEK UYGULAMA (AÇIK KAYNAK ASP.NET MVC HABER SİTESİ)

permanent link

cevaplandı: 28 Ağu '13, 03:35

AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

AliRıza Adıyahşi ♦
7.9k146288
cevap kabul oranı: 44%

Cevap için teşekkürler. Buda başka bir güzel cevap :)

(28 Ağu '13, 05:37) emrekacan emrekacan's gravatar image

Benim yazdığım belki biraz zor gibi görünüyor olabilir ama, yapısal olarak sonradan işinizi cok kolaylaştırabilir. @ucuncubayram, hocamın tavsiyesi ile aynı işi yapıyor, ama ilerde tüm proje için ortak kullanılan ve oturum boyunca elinizde tutmanız gerek veriler (kullanıcıya gore yetkilendirilmiş nesneler, mesela menu, kategori, gibi...) oldukca, tek yapmanız gerek BaseController a bu verileri eklemek olacak. Bundan dolayı bu yapıyı bir düşünün derim. Ayrıca bir kaç tane açık kaynak, proje inceleyerekte fikir edinebilirsiniz.

(28 Ağu '13, 05:46) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

ViewBag.AktifKullanici = kullaniciServis.AktifKullanici(KullaniciEposta); satırı sanırısam veritabanı üzerine sorgu atıyor; kullanıcı tarafından yapılan her istekle birlikte bu sorgunun çalıştırılması perfomans yonunde kucuk de olsa bir olumsuzluk gibi duruyor. Cozum en azından bu sorgu icin veritabanı katmanında cache'leme olabilir.

(28 Ağu '13, 17:03) gturedi gturedi's gravatar image

@gturedi, haklısınız. Kullanıcı adından baska veriler tutmak için ya boyle kullanacaksınız(performans konusunda gozle gorulur bir etki olacagını sanmıyorum, ama dediginiz gibi cache işlemi uygulanırsa daha iyi olur) ya da veritabanından cektikten sonra, tum veriyi tek bir object olarak, uygulama tarafındaki bir cache nesnesinde tutmak.Yani sizin önerinizden sonra , @ucuncubayram hocamın kodları ile bu kodlar birleştirilebilir gibi geldi bana.

(29 Ağu '13, 00:03) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

Veritabanı ve kullanıcı sistemini kullanmadığım için kodları değiştirdim.Ama yine işe yaramadı.

    protected override void OnActionExecuting
    (ActionExecutingContext filterContext)
    {
        ViewBag.ImageID = imageID;
        base.OnActionExecuting(filterContext);
    }

private int imageID;

public int ImageID
    {
        get { return ViewBag.ImageID; }
        set { imageID = value; }
    }

Sanırım birşeyler daha eksik.

(29 Ağu '13, 01:05) emrekacan emrekacan's gravatar image

Öncelikle, imageId nereden geliyor. Kullanıcıya baglı birşey mi? Kullanıcıya baglı ise kullanıcılarınız sisteme giriş yaptıgında nasıl bir authentication kullanıyorsunuz? Form.Authentication mı kullanıyorsunuz? sizin yazdıgınız kod da ImageID ye viewBag den deger atıyorsunuz, viewBag nesnesine ise private olarak tanımladıgınız ve hic bir degeri olmayan imageID yi atıyorsunuz.

(29 Ağu '13, 01:21) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

Authentication işlemini facebook üzerinden yapıyorum. Uygulamada Home Controllerın oyna Action'ında atama yapıyorum. Başka bir Controller üzerindende erişmeye çalışıyorum.

https://gist.github.com/emrehit/6375087

Bu şekilde kullanıyorum.

(29 Ağu '13, 01:30) emrekacan emrekacan's gravatar image

debug ettiniz mi? image.ID null gelmiyor degil mi? Veri nereden gelirse gelsin eger veri varsa ve bunu ViewBag nesnesine atarsanız görmeniz lazım. dediginiz gibi Başka bir sıkıntı olabilir.

(29 Ağu '13, 01:33) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

Dediğiniz gibi bir tane base Class oluşturdum. İçerisinede Session'a veri atıp veri alan iki tane fonksiyon yazdım. Normalde ayrı controllerlarda tanımayan sistem base class üzerinden session'u tanıdı. Sorunu bu şekilde çözdüm. Herkese yardımları için teşekkür ederim. Kolay gelsin.

(30 Ağu '13, 07:22) emrekacan emrekacan's gravatar image
9 yorumdan 5 tanesi gösteriliyor hepsini göster

Veri kaydederken bunu deneyebilirsin,

HttpContext.Cache["key"]= object;

sonra da veriyi alırken

object = (ObjectType)HttpContext.Cache["key"];
permanent link

cevaplandı: 28 Ağu '13, 03:17

ucuncubayram's gravatar image

ucuncubayram
1.4k122840
cevap kabul oranı: 11%

Sonunda :) Teşekkürler. Birşey daha sorayım. Bu cache kişiye özel değil mi? Yani aynı anda giren kişilerin verilerinin karışma ihtimali yok demi?

(28 Ağu '13, 04:42) emrekacan emrekacan's gravatar image

key olarak kullanıcı adını tutarsan ve bu kullanıcıya ait verileri de object olarak saklarsan karışmaz. Çünkü key değerine göre çekeceksin nesneleri. Ben sadece session benzeri bir seçenek istediğin için bunu önerebildim.

(28 Ağu '13, 05:43) ucuncubayram ucuncubayram's gravatar image

Şöyle bi sıkıntı var o zamanda. Kullanıcı IDsinide Session'da tutuyordum :) Ali beyin önerisini deneyeyim bide

(28 Ağu '13, 07:44) emrekacan emrekacan's gravatar image

Cache kullanmam için o anda giriş yapan kullanıcıya özel birşeyler olmalı elimde? Böyle birşeyler var mı kullanabileceğim?

(29 Ağu '13, 01:02) emrekacan emrekacan's gravatar image

Login için nasıl bir mekanizma kullandığın da önemli tabi. Asp.net Membership mekanizmasını kullanıyorsan Login işleminden sonra zaten HttpContext.User.Identity.Name şeklinde kullanıcı adını alabilirsin.

(29 Ağu '13, 05:44) ucuncubayram ucuncubayram's gravatar image
Cevabınız
toggle preview

Bu soruyu takip et

E-Posta üzerinden:

Üyelik girişi yaptıktan sonra abonelik işlemlerini yapabilirsiniz

RSS üzerinden:

Cevaplar

Cevaplar ve Yorumlar

Yazı Formatlama

  • *italic* ya da _italic_
  • **bold** ya da __bold__
  • link:[text](http://url.com/ "başlık")
  • resim?![alt text](/path/img.jpg "başlık")
  • liste: 1. Foo 2. Bar
  • temel HTML etiketleri de kullanılabilir

Bu sorunun etiketleri:

×81
×7

Soruldu: 28 Ağu '13, 02:50

Görüntüleme: 3,487 kez

Son güncelleme: 30 Ağu '13, 07:22

powered by BitNami OSQA