ASP.NET MVC Core 6 her Action'da sorgu yapmanın kolay yolu var mı?

Sinan Uğurlu

Kilopat
Katılım
30 Mayıs 2018
Mesajlar
495
Çözümler
11
Yer
Datacenter
Daha fazla  
Cinsiyet
Erkek
Meslek
Yazılım ve Ağ Altyapı Danış.
İyi forumlar, Basitçe sorum şöyle; Kullanıcı ile alakalı bazı sorgular yapmam lazım, bunu her Action'da tek tek farklı bir Action'a yönlendirmek yerine Global.asax gibi her Get ya da Post işlemi yapıldığında bu sorguyu yapmam lazım, bunun kolay bir yolu var mıdır? Şimdiden vakit ayırdığınız için teşekkürler.
 
Merhabalar, umarım cevap için fazla geç kalmamışımdır. Action'dan kastınız Controller üzerinde gerçekleştirmek mi? Yoksa Razor sayfaları üzerinde gerçekleştirmek mi?

Her ikisi için ortak çözüm bırakıyorum. Mantığı kullanarak çözebilirsiniz.

C#:
public class CustomPageModel : PageModel{
    public FooType FooData {get;set;}
    
    public CustomPageModel(/* Parametrelerinizi alabilrsiniz. */){
        GetFooData(fooParam);
    }
    
    public void GetFooData(object fooParam){
        var data = FooService.GetBar();
        FooData = data;
    }
}
C#:
public class IndexModel : CustomPageModel
{
    //Artık FooData'ya erişebilirsiniz. Ve CustomPageModel'i implemente eden her modele FooData otomatik olarak eklenir.
    
    public IndexModel() : base()
    {
        
    }
}
 
Merhabalar, umarım cevap için fazla geç kalmamışımdır. Action'dan kastınız Controller üzerinde gerçekleştirmek mi? Yoksa Razor sayfaları üzerinde gerçekleştirmek mi?

Her ikisi için ortak çözüm bırakıyorum. Mantığı kullanarak çözebilirsiniz.

C#:
public class CustomPageModel : PageModel{
    public FooType FooData {get;set;}
  
    public CustomPageModel(/* Parametrelerinizi alabilrsiniz. */){
        GetFooData(fooParam);
    }
  
    public void GetFooData(object fooParam){
        var data = FooService.GetBar();
        FooData = data;
    }
}
C#:
public class IndexModel : CustomPageModel
{
    //Artık FooData'ya erişebilirsiniz. Ve CustomPageModel'i implemente eden her modele FooData otomatik olarak eklenir.
  
    public IndexModel() : base()
    {
      
    }
}

Cevabınız için teşekkür ederim, ancak kodu analiz edemedim, Yapmak istediğim şöyle; Kullanıcı herhangibir controller'da herhangibir Action'u tetiklediğinde ben kullanıcı ile alakalı yada başka bir konuda belli sorgular yapmak istiyorum. Mesela kullanıcı şifre değiştirmiş tüm hesaplardan çıkış yapmış, benim bunu sorgulayıp oturumunu sonlandırmam lazım gibi. Bunu her Action'a yazmak yerine yada Action içerisine UserSorgu() şeklinde void komutu çağırmaktansa direkt sorgulayamam mı? Şimdiden teşekkürler.


Konu ile alakasız olarak cevabınızla aklıma geldi, mesela ben proje genelinde bir bilgiye ulaşabilirmiyim? Identity'de View kısmında @User.Identity.GetUserID() diyerek kullanıcı ID'sini getirebiliyorum, bunun gibi bir kısımda kullanıcı bilgilerini yada başka bilgileri atabilirmiyim?
 
Merhaba, Login olurken diğer bilgileri de Claim olarak atayabilirsiniz.
C#:
private ClaimsIdentity GetClaimsIdentity(User user)
        {
            var hours = 5;
            var expiredAt = DateTime.Now.AddHours(hours);
            var claims = new List<Claim> {
                new Claim(ClaimTypes.Email, user.Email),
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimTypes.GivenName, user.DisplayName),
                new Claim(ClaimTypes.Expired, expiredAt.ToString("HH:mm"))
            };

            var claimsIdentity = new ClaimsIdentity(claims, FooAuthenticationDefaults.AuthenticationScheme);
            return claimsIdentity;
        }
Örnek bu şekilde. Bunlara erişmek için de ClaimsPrincipalExtensions adında statik bir sınıf oluşturup içine şunları yazın:
C#:
public static string GetDisplayName(this ClaimsPrincipal claimsPrincipal)
        {
            return claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName).Value;
        }

        public static string GetEmail(this ClaimsPrincipal claimsPrincipal)
        {
            return claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email).Value;
        }

        public static string GetId(this ClaimsPrincipal claimsPrincipal)
        {
            return claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
        }

        public static IEnumerable<string> GetRoles(this ClaimsPrincipal claimsPrincipal)
        {
            return claimsPrincipal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value);
        }

Bunlar kaydettiğiniz tüm verileri getirmenize yardımcı olacak. Örnek:
C#:
var userEmail = HttpContext.User.GetEmail();
var userDisplayName = HttpContext.User.GetDisplayName();

Eğer sınıf olarak tutmak istiyorsanız doğrudan bir çözüm bunun için sunulmuyor fakat custom bir ClaimType tanımlayıp class verisini Json içinde tutup authorization sonrası class'ı çözebilirsiniz. Fakat güvenlik zafiyeti oluşturabilir.

Mesela kullanıcı şifre değiştirmiş tüm hesaplardan çıkış yapmış, benim bunu sorgulayıp oturumunu sonlandırmam lazım gibi. Bunu her Action'a yazmak yerine yada Action içerisine UserSorgu() şeklinde void komutu çağırmaktansa direkt sorgulayamam mı?
Normalde bu isteğiniz Business katmanı içinde yapılır. Interception mantığı ile rahatlıkla yapabileceğiniz bir şey.

Fakat Controller içindeyseniz size şöyle yardımcı olayım. ActionFilterAttribute kullanabilirsiniz.
C#:
public class UserCheckAttribute : ActionFlterAttribute{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var userRepository = context.HttpContext.RequestServices.GetRequiredService<[Size lazım olan servis]>();
        // Yapacağınız validasyonlar vs.
        if(problem){
            throw new Exception("Problem algılandı.");
            // Bu şekilde kesebilirsiniz. Ya da;
            // context.HttpContext.Request ile yönlendirebilir, custom response verebilirsiniz.
        }
    }
}

Sonrasında bu filtreyi uygulamak istediğiniz methodların başına Attribute olarak ekleyin.
C#:
public class HomeController : Controller {
    //...
   
    [UserCheck]
    public IActionResult Index()
    {
        //Metodun asıl gövdesi. Başka herhangi bir şeye ihtiyaç yok.
    }
}

Ayrıca filtreler sayesinde sadece method çalışmadan önce değil, çalıştıktan sonra da işleminizi gerçekleştirebilirsiniz. Hatta başarılı olduysa şunu yap, başarısız olduysa şunu yap gibisinden emirler verebilirsiniz.

Detaylar için bakınız.
Bağımlılık yükleme için bakınız.
 
Son düzenleme:

Geri
Yukarı