# Blog Roadmap

## 2020-09-08

### New

{% content-ref url="/pages/-MGf7eYmxUuWbpCtCg0z" %}
[EntityFramework Query Tagging](/2020/entityframework-query-tagging)
{% endcontent-ref %}

## 2020-05-02

### New

{% content-ref url="/pages/-M6LWOBZQbTsUJkkPJCn" %}
[Level101 — Ubuntu Sunucuya Docker Community Edition Kurulumu Nasıl Yapılır?](/2020/level101-ubuntu-sunucuya-docker-community-edition-kurulumu-nasil-yapilir)
{% endcontent-ref %}

{% content-ref url="/pages/-M6LWynt0Lhb7kt1Y2XT" %}
[Level101 — Amazon Üzerinde Ubuntu Sunucu Nasıl Açılır?](/2020/level101-amazon-uezerinde-ubuntu-sunucu-nasil-acilir)
{% endcontent-ref %}

## 2020-02-21

### New

{% content-ref url="/pages/-M0ZfbHkah8SC1dw7olO" %}
[\[Lvl101\] - Azure Üzerinde PostgreSql Kurulumu](/2020/azure-uzerinde-postgresql-kurulumu)
{% endcontent-ref %}

## 2019-12-12

### Updated

{% content-ref url="/pages/-LpxPmewiCXApT2wmryM" %}
[Asp.Net Core Api İle Graphql Projesi Oluşturmak](/post-2019/asp.net-core-api-ile-graphql-projesi-olusturmak)
{% endcontent-ref %}

## 2019-12-02

### Added

* [Datagrip AutoComplete Not Working](/post-2019/hotfix-datagrip-autocomplete-not-working)

## 2019-11-28

### Added

* [Kubernetes Dashboard UI Kurulumu Nasıl Yapılır?](/post-2019/kubernetes-dashboard-ui-kurulumu-nasil-yapilir)

## 2019-10-30

### Added

* [Git Self Sertifika Hatasının Çözümü](/post-2019/git-self-sertifika-hatasinin-coezuemue)

## 2019-10-01

### Added

* [Asp.Net Core Api İle Graphql Projesi Oluşturmak](/post-2019/asp.net-core-api-ile-graphql-projesi-olusturmak)


# EntityFramework Query Tagging

EntityFramework Core 2.2 ile birlikte hayatımıza giren query tagging özelliğini size anlatmaya çalışacağım.

Özellikle EF ile yazılan uygulamalarda, karmaşık LINQ sorguları ile yazdığımız sql çıktılarının takibi, karmaşıklığı ve performans sorunlarını hepimiz biliyoruz. Bu gibi durumlarda çıktıları kontrol etmemiz, özellikle EF’nin oluşturduğu sorguların execution planlarını ve performans metriklerini takip etmemiz zor olabiliyor.

> Alternatif Çözüm olarak APM ürünlerini kullanabilirsiniz.

Query Tagging, hem database yönetimi hem de log’lama sistemleri için sorgularımızı etiketleyerek, hızlıca erişebileceğimiz bir özelliktir.

Sorgularınızı yazarken; ne amaçla yapıldığını / yazıldığını belirten bir işaretleme (tagging) yapıyoruz.

Örneğin

* GetFirst50Products — Product tablosunda ilk 50 kaydı getiren sorgu
* GetAllUserRoles — Kullanıcı rollerinin tümünün çekildiği sorgu

Bunu yapabilmemiz için aşağıdaki gibi TagWith extension fonksiyonunu kullanabilirsiniz.

```
var first50Item = dataContext
    .Products
    .TagWith("Get First 50 Item")
    .OrderBy(p => p.CreateDate)
    .Take(50).ToList();
```

Sorgunun çıktısı ise bu şekilde olacaktır.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-MGf7ZARmnsjyex5hWUz%2F-MGf8VR2hr1CGz9-4Q2f%2F1*cni8QUeyJiyaOjrjpKaPxQ.png?alt=media\&token=8cff9a67-7575-42da-a79c-1a3667a60baf)

Sql Server üzerinde son çalıştırdığınız sql dizisine erişmek için aşağıdaki sorguyu kullanabilirsiniz.

```
SELECT deqs.last_execution_time AS [Time], dest.text AS [Query], dest.*
FROM sys.dm_exec_query_stats AS deqs
         CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
where text like '%-- Get First 50 Item%'
ORDER BY deqs.last_execution_time DESC
```

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-MGf7ZARmnsjyex5hWUz%2F-MGf8b8VcqaGWTvEIIHn%2F1*Oz5SPE_KB2bPEU9ZhZSDJg.png?alt=media\&token=8cfb3892-4773-4d48-9f92-9c1fd3b6583c)

**İlgili yazının uygulanışına aşağıdaki linkten erişebilirsiniz.**

{% embed url="<https://github.com/cagdaskarademir/efcore-query-tagging>" %}


# \[HOTFIX] Npm Self Sertifika Hatasının Çözümü

Npm repolarını yükleme yaparken veya erişim sağlamaya çalıştığınızda aşağıdaki gibi bir hata alabilirsiniz.

```
npm ERR! code SELF_SIGNED_CERT_IN_CHAIN
npm ERR! errno SELF_SIGNED_CERT_IN_CHAIN
npm ERR! request to https://registry.npmjs.org/xxx failed, reason: self signed certificate in certificate chain
```

Workaround çözüm olarak aşağıdaki kodu çalıştırabilirsiniz.

```
npm config set strict-ssl false
```


# Level101 — Ubuntu Sunucuya Docker Community Edition Kurulumu Nasıl Yapılır?

Merhaba Arkadaşlar

Ubuntu sunucuya docker kurulumu yapmak için aşağıdaki adımları izleyebilirsiniz.

Güncel SH dosyası üzerinden kurulumu kolaylıkla yapabilirsiniz.

Öncelikle yeni bir docker klasörü oluşturup [https://get.docker.com](https://get.docker.com/) içeriğini docker.sh dosyası olarak kaydediyoruz.

```
mkdir docker
cd docker
curl https://get.docker.com -o get-docker.sh
```

Kayıt edilen dosyamızı run ediyoruz.

```
sh get-docker.sh
```

Kurulumları başarıyla tamamladıktan sonra login olduğumuz kullanıcıya docker için izin veriyoruz.

```
sudo usermod -aG docker ${USER}
```

SSH client üzerinden session’ı kapatıp tekrar ssh ile bağlantı kurmanız gerekebilir. Exit komutuyla logout oluyoruz ve tekrar ssh ile login oluyoruz.

```
exit
```

Tebrikler kurulumu başarıyla tamamladınız.

```
docker -v
```

{% embed url="<https://youtu.be/89-FGB6r3FM>" %}

Alternative Ref : <https://link.medium.com/Xsb2Fzgla6>


# Level101 — Amazon Üzerinde Ubuntu Sunucu Nasıl Açılır?

Merhaba Arkadaşlar

Amazon üzerinde ubuntu sunucu kurulumu yapmak için aşağıdaki adımları izleyebilirsiniz.

Ec2 panele girip Launch Instance butonuna basılır.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXQBak2Gx4kBNnGft%2Fimage.png?alt=media\&token=6720c5c1-6156-451b-8343-5659e3856f2a)

Kurulum yapılacak linux distro versiyonu seçilir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXTvS_v2H2uhk9nh-%2Fimage.png?alt=media\&token=9af7a827-6f1f-4c4e-b743-3a03bcff6d18)

Makine özellikleri seçilir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXWQXwbXs8bwvCJ87%2Fimage.png?alt=media\&token=fe4754bd-51a6-41f5-8645-029d94f9ad59)

Yeni Key Pair ismi verilip, pem dosyası local’e indirilir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXZEa92BPszGVZco1%2Fimage.png?alt=media\&token=355649b5-4bec-4f43-ba62-74638f8c70b4)

Bağlantı yapılacak makineye sağ tıklanıp Connect butonuna basılır.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXazHHeTfN4et5Vyv%2Fimage.png?alt=media\&token=205889aa-4098-48cd-8018-678a9fcee6f4)

Pem dosyasının olduğu dizine gidilip Example adımında gösterilen şekilde SSH bağlantısı kurulur.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M6LWMLXcIcySSgtjgMr%2F-M6LXdNEA67NGNCNCILU%2Fimage.png?alt=media\&token=68d62a34-c388-4b74-b1f2-7562b72ea816)

Tebrikler başarıyla giriş yapıldı.


# \[Lvl101] - Azure Üzerinde PostgreSql Kurulumu

Azure Platformunda Database as a service olarak PostgreSql veritabanının nasıl kurulduğunu tecrübe edeceğiz.

Bu yazı dizimizde Azure platformunda PostgreSql veritabanının nasıl kurulacağını göreceğiz.

### Resource Group Oluşturulması

Bu örneğimiz için TutorialPostgreSqlRG adında bir tane Resource Group oluşturuyorum.

![ New Resource Group Ekranı](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZgktBgBp8Y4G0Oiww%2Fimage.png?alt=media\&token=518546f7-3233-4313-b493-7491eae843af)

{% hint style="info" %}
Resource Group, birden fazla ve farklı servislerinizi düzenli bir şekilde yönetmenizi sağlar.&#x20;
{% endhint %}

![Yeni Resource Group Oluşturulması](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZhL4UAynxJhDzgt6n%2Fimage.png?alt=media\&token=ec4dc517-0cf7-4c66-8fa1-cb350ecda48f)

### Veritabanının Oluşturulması

Azure PostgreSql veritabanı oluşturmak için "Azure Database for PostgreSQL" servisini "Single Server" olarak seçiyorum.

> Azure, yakın zamanda satın aldığı Citus Data firmasının Citus çözümüyle; daha büyük ve enterpise veritabanları yönetebilmeyi amaçlıyor.&#x20;
>
> Daha fazla bilgi için : <https://www.citusdata.com/>

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZhmhXOhpBR7nNykRu%2Fimage.png?alt=media\&token=19f4fd96-8158-4f8e-8270-835cba4ea853)

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZlcVAD4bgWSrBm7L5%2Fimage.png?alt=media\&token=7524d4af-ba04-4b29-b35a-8dcaec791dc8)

Yeni bir veritabanı tanımlamak için gereken Sunucu Adı ve Giriş Bilgilerini girdikten sonra; kurulum yapılacak servis makine tipini seçmeniz gerekmektedir.&#x20;

Şimdilik bu adım için en düşük paket olan Basic paketini seçiyorum.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0Zm6NRpgPOBFQxv4SN%2Fimage.png?alt=media\&token=4dbc6f7f-43d9-4aba-aa93-c5332dd8398b)

{% hint style="info" %}
Azure For PostgreSql veritabanı için varsayılan veritabanı adı "postgres"'dir.
{% endhint %}

### PostgreSql Veritabanına Nasıl Bağlanabilirim?

PostgreSql veritabanı gibi birçok veritabanını destekleyen DataGrip ürününü kullanıyorum.&#x20;

Daha Fazla Bilgi İçin : <https://www.jetbrains.com/datagrip/>

Ücretsiz bir versiyon olan DBeaver Community versiyonu da işinizi görecektir.

Daha Fazla Bilgi İçin : <https://dbeaver.io/>

### Connection (Bağlantı) Bilgilerinin Alınması

Veritabanı kurulumu bittiğinde aşağıdaki gibi bir ekran sizi karşılayacaktır.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZncQwSVwtbPNoYOqJ%2Fimage.png?alt=media\&token=2e52eaeb-693d-4966-83ca-da5eacc0519f)

Veritabanına istediğiniz bir IDE editörü üzerinden bağlanabilirsiniz. (Datagrip, DBeaver vs)

Bağlantı bilgileri için PostgreSql Dashboard ekranında sunucu bilgilerini ve kullanıcı adına erişebilirsiniz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZrDwrDwfeYpTuYbIp%2Fimage.png?alt=media\&token=83a9c6c0-159e-4875-83aa-8a0fef78d720)

{% hint style="info" %}
Azure, Database As A Service olarak verdiği hizmetlerinde siz izin vermediğiniz sürece erişimleri dış dünyaya kapalı şekilde sunar.

Özellikle Firewall ekranından erişmek istediğiniz makinelere izin vermeniz gerekmektedir.
{% endhint %}

Tüm bilgileri doğru girdiğinizde Ip Restriction'dan dolayı login olamayacaksın

![Varsayılan Olarak Veritabanı Dış Dünyaya Kapalı Gelmektedir](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0Zsh0XgcspsqyNq7yi%2Fimage.png?alt=media\&token=3ab9cfdf-43f2-4a41-97a0-3f42fc79452f)

Sol menüden Connection security ekranından kendi ip adresimizi "Add Client Ip" butonuyla eklememiz gerekmektedir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0Zt5Y8M2PdCCvli-1J%2Fimage.png?alt=media\&token=d1cea21a-f159-46f0-a352-dfb48c9323f2)

Connection Security ekranından Client Ip adresini başarıyla eklediğinizde; database ide editörümüzü kontrol edebiliriz.&#x20;

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-M0ZfCgQkRdV4zQm4m8z%2F-M0ZtKvQXOc9f9EPSMEB%2Fimage.png?alt=media\&token=6c5c47fa-8c60-4180-b61c-2eb3dd75d78e)


# \[HOTFIX] Datagrip AutoComplete Not Working

> Datagrip, JetBrains tarafından veritabanlarını yönetebilmek için ürettiği editördür.&#x20;
>
> Detaylı bilgiye  <https://www.jetbrains.com/datagrip/> ulaşabilirsiniz.

Çok uzun zamandır severek kullandığım JetBrains ürünü olan Datagrip uygulamasının upgrade sonrasında AutoComplete özelliğinin çalışmadığı farkettim.

Araştırmalarım sonrasında çalıştığım Data Source'un versiyondan dolayı bozulabildiğini öğrendim.&#x20;

Eğer View veya Table içerisinde yer alan kolonları göremiyorsanız, büyük ihtimal aynı sorunu yaşıyor olabilirsiniz.&#x20;

Data Source -> Database Tools -> Forget Cache Schema adımlarını uygulayarak belki probleminizi çözebilirsiniz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-Lv2RzXPS_e5s9FYlHqD%2F-Lv2TvS0d2hbeBn8dHC3%2Ftempsnip.png?alt=media\&token=3f005d54-034e-4ac2-ab1a-33dc4111c564)

Referans : <https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000138284/comments/115000200084>


# Kubernetes Dashboard UI Kurulumu Nasıl Yapılır?

Bu yazımızda; Kubernetes Community tarafından geliştirilmiş, varsayılan olarak kurulu gelmeyen Kubernetes Dashboard UI Kurulumunun nasıl yapılacağını tecrübe edeceğiz.&#x20;

Kubernetes Dashboard, Kubernetes cluster'ınız içerisinde uygulamalarınızı yönetebileceğiniz ve monitör edebileceğiniz web tabanlı bir uygulamadır.

### Dashboard Yaml Dosyasının Deploy Edilmesi

```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml
```

![Dashboard UI Yaml Dosyasının Deploy Edilmesi](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LuisVg1RzOjcVadBSh2%2F-LuitGgEyJoQda5b1AwY%2Fimage.png?alt=media\&token=a08e85f7-b0cc-4078-a8a6-442c28e2869b)

### Dashboard'a Giriş İçin Token Oluşturulması

```
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
```

![Admin Girişi İçin Token Oluşturulması](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LuisVg1RzOjcVadBSh2%2F-LuitR-YAvwUn6POxDvi%2Fimage.png?alt=media\&token=34544ec8-e753-4036-a4e0-0e9eff3aab79)

Type: kubernetes.io/service-account-token

alanında yer alan token ile başlayan hash kodu herhangi bir text editör üzerine kopyalayın. Sonrasında ihtiyacımız olacak.

### Dashboard Admin Sayfasına Erişim

```
kubectl proxy
```

Proxy oluşturduktan sonra aşağıdaki linki browser üzerinde açtığınızda dashboard admin sayfası karşınıza gelecektir.

Kopyaladığınız token değerini burada aşağıdaki gibi kullanabilirsiniz.

{% embed url="<http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/>" %}

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LuisVg1RzOjcVadBSh2%2F-Luiud7VFaLDr793pNKy%2Fimage.png?alt=media\&token=3c9c9904-2120-4dea-828f-052943feb1a2)

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LuisVg1RzOjcVadBSh2%2F-Luiv25zY3Ma2NFQ8Prm%2Fimage.png?alt=media\&token=79f70a13-1740-4803-9706-95835588f34f)

Kaynaklar:

<https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/>

<https://github.com/kubernetes/dashboard>


# \[HOTFIX] Git Self Sertifika Hatasının Çözümü

Üzerinde çalıştığınız git projeniz push veya pull etmek istediğinizde; aşağıdaki hatayı verebilir.

> fatal: unable to access 'xxxx': SSL certificate problem: self signed certificate in certificate chain

Bu hatayı aşağıdaki komutu çağırarak çözebilirsiniz.&#x20;

{% embed url="<https://gist.github.com/cagdaskarademir/a2d83886b301a695c4088a8a38a044d8>" %}


# Node.js Son Versiyona Nasıl Yükseltebilirim?

Eğer Node.js son versiyonu kurmak istiyorsanız aşağıdaki kodu kullanabilirsiniz.

{% embed url="<https://gist.github.com/cagdaskarademir/5910733ba102f293525fbe72a1cdca47>" %}


# MacOs Üzerine Docker Sql Server Nasıl Kurulur?

Docker üzerine Sql Server kurmak için aşağıdaki önergeleri izlemeniz yeterli olacaktır.

Bu yazıda size Sql Server 2019 Preview kurulumunu anlatacağım.

Mac'e kurulum yapmak için&#x20;

{% embed url="<https://gist.github.com/cagdaskarademir/338043a1740143e724f13189b4335211>" %}

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LqgXE5h_UynyaLXz2iW%2F-Lqghyd9wrx2Vnj3Ul2T%2Fimage.png?alt=media\&token=953a9377-2c48-46cf-a248-997ba0ab26f7)


# Asp.Net Core Api İle Graphql Projesi Oluşturmak

Bu yazı dizimiz de Asp.Net Core Api teması kullanarak graphql ile sql server veritabanina nasıl bağlantı kurabileceğimizi göreceğiz.

Kaynak Kodlara aşağıdaki repodan ulaşabilirsiniz.

{% embed url="<https://github.com/cagdaskarademir/tutorial-aspnetcore-graphql-sqlserver>" %}

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LpxbmvhpphwXxY5kCcO%2F-LpxcKpxyiMKsnleKT4K%2Fimage.png?alt=media\&token=977a7883-e157-4d4c-adbe-b05415ca747b)

## Makalenin Amacı

.Net Core Web Api ve GraphQL kullanarak SQL Server veritabanında select  işlemlerinin nasıl yapılacağını tecrübe edineceğiz.&#x20;

## Bilmeniz veya Öğrenmeniz Gereken Terimler

{% hint style="info" %}
Aşağıdaki terimler hakkında bilgi sahibi olmalısınız.
{% endhint %}

1. .Net Core Web Api Nedir?
2. .Net Core Web Api Projesi Nasıl Oluşturulur?
3. GraphQL Nedir?&#x20;
4. ObjectGraphType Nedir?&#x20;
5. Dapper Nedir?
6. SqlKata Nedir?

## Kullanılan Yan Teknolojiler

Orm tool olarak Dapper altyapısı kullanılarak hızlı bir şekilde sql kodu yazabileceğimiz SqlKata Query Generater kütüphanesini kullanacağız.

SqlKata kütüphanesine <https://sqlkata.com/> linki üzerinden erişebilirsiniz.&#x20;

Dökümantasyon ve örnekler için <https://sqlkata.com/docs> adresini ziyaret etmenizi öneririm.

## Katmanların Oluşturulması

### Web Projesinin Oluşturulması <a href="#web-projesinin-olusturulmasi" id="web-projesinin-olusturulmasi"></a>

a[sp.net](http://asp.net/) web api projesi oluşturuyoruz.‌

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-LvvZwrsWwDmI2NoQMII%2Fimage.png?alt=media\&token=8fcf023e-be90-4512-a817-95eb1e79283e)

Web Projemize aşağıdaki kütüphaneleri ekliyoruz.

```csharp
<PackageReference Include="GraphQL" Version="2.4.0" />
```

### Entity Projesinin Oluşturulması <a href="#entity-projesinin-olusturulmasi" id="entity-projesinin-olusturulmasi"></a>

Tablo setlerimizi yöneteceğimiz Entity katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_7UwVXCROxr743gO%2Fimage.png?alt=media\&token=e77addac-19dc-4cb2-9f9f-a813931ecd7d)

Referans Projesi olarak aşağıdaki projeyi ekliyoruz.

```csharp
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
```

### Common Katmanının Oluşturulması <a href="#common-katmaninin-olusturulmasi" id="common-katmaninin-olusturulmasi"></a>

‌Tüm katmanlarda kullanacağımız enum, const ve helper sınıfları için Common katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_NMdpTN8H4mQkyzV%2Fimage.png?alt=media\&token=553d2f4c-16ce-4ec9-b5cf-e711b4686cc3)

Projemize Newtonsoft.Json kütüphanesini ekliyoruz.

```csharp
 <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
```

### Business Katmanının Oluşturulması <a href="#business-katmaninin-olusturulmasi" id="business-katmaninin-olusturulmasi"></a>

İş süreçlerini kontrol edebileceğimiz Business katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_TjOf6PWCXj6Up3f%2Fimage.png?alt=media\&token=4118be7c-b8f0-4683-996e-41bf041b4cac)

### Model Katmanının Oluşturulması <a href="#model-katmaninin-olusturulmasi" id="model-katmaninin-olusturulmasi"></a>

Verilerimizi transfer edeceğimiz Model katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv__Z7Qr_XSjJSx8Bb%2Fimage.png?alt=media\&token=e0500878-e14d-42e4-a860-dbb9e3d2177c)

Referans Projesi olarak aşağıdaki projeyi ekliyoruz.

```csharp
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
```

### Repository Katmanının Oluşturulması <a href="#repository-katmaninin-olusturulmasi" id="repository-katmaninin-olusturulmasi"></a>

Veritabanı işlemlerini yönetebildiğimiz data katmanımız olan Repository katmanını oluşturuyoruz.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LvvZNAUK2Ej3lTIz3_M%2F-Lvv_hcrvDYk2uyqwKkJ%2Fimage.png?alt=media\&token=7b1f4b87-c152-4bb7-8c79-c537d64b3b6d)

Repository katmanına aşağıdaki referansları ekleyin.

```aspnet
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
<PackageReference Include="SqlKata" Version="1.1.7" />
<PackageReference Include="SqlKata.Execution" Version="1.1.7" />
```

Referans projesini olarak aşağıdaki kütüphaneleri ekliyoruz.

{% code title="CK.Tutorial.GraphQlApi.Repository.csproj" %}

```aspnet
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Common\CK.Tutorial.GraphQlApi.Common.csproj" />
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Entity\CK.Tutorial.GraphQlApi.Entity.csproj" />
<ProjectReference Include="..\CK.Tutorial.GraphQlApi.Model\CK.Tutorial.GraphQlApi.Model.csproj" />
```

{% endcode %}

## Common Layer

### Extension Dosyalarının Oluşturulması

Array değişkenlerimize yardımcı olması için aşağıdaki extension'ı yazıyoruz.

```csharp
using System.Linq;

namespace CK.Tutorial.GraphQlApi.Common.Extension
{
    public static class ArrayExtension
    {
        public static bool AnyItem(this string[] value)
        {
            return value != null && value.Any();
        }
    }
}
```

Primitive değişkenlerimize yardımcı olmak için aşağıdaki extension'ı yazıyoruz.

```csharp
using System;

namespace CK.Tutorial.GraphQlApi.Common.Extension
{
    public static class PrimitiveExtension
    {
        public static bool IsNotNullOrEmpty(this string value)
        {
            return !string.IsNullOrEmpty(value);
        }

        public static bool IsNotNull(this bool? value)
        {
            return value != null;
        }
        
        public static bool IsTrue(this bool? value)
        {
            return value != null && value == true;
        }
        
        public static byte ConvertToByte(this bool? value)
        {
            if (value ==null )
            {
                throw new ArgumentException("Boolean Item must be convertible");
            }

            return (byte) (value.Value ? 1 : 0);
        }
    }
}
```

### Common Model Dosyalarının Oluşturulması

Kullanıcılardan parametrik olarak alacağımız veriler için base request sınıfı oluşturuyoruz.

```csharp
namespace CK.Tutorial.GraphQlApi.Common.Model
{
    public class RequestBase
    {
        public int DefaultPage { get; } = 1;
        public int DefaultPageSize { get; } = 10;
        public string[] Columns { get; set; }
        public int? PageSize { get; set; }
        public int? Page { get; set; }
    }
}
```

GraphQL için aşağıdaki model dosyamızı oluşturuyoruz.

```csharp
using System.Text;

namespace CK.Tutorial.GraphQlApi.Common.Model
{
    public class GraphQlQuery
    {
        public string OperationName { get; set; }
        public string NamedQuery { get; set; }
        public string Query { get; set; }
        public string Variables { get; set; }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.AppendLine();
            if (!string.IsNullOrWhiteSpace(OperationName)) builder.AppendLine($"OperationName = {OperationName}");
            if (!string.IsNullOrWhiteSpace(NamedQuery)) builder.AppendLine($"NamedQuery = {NamedQuery}");
            if (!string.IsNullOrWhiteSpace(Query)) builder.AppendLine($"Query = {Query}");
            if (!string.IsNullOrWhiteSpace(Variables)) builder.AppendLine($"Variables = {Variables}");

            return builder.ToString();
        }
    }
}
```

## Entity Katmanı

### Company Entity

```csharp
namespace CK.Tutorial.GraphQlApi.Entity
{
    public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsActive { get; set; }
    }
}
```

### Product Entity

```csharp
using CK.Tutorial.GraphQlApi.Common.Enum;

namespace CK.Tutorial.GraphQlApi.Entity
{
    public class Product
    {
        public int Id { get; set; }
        public int CompanyId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int ProductTypeId { get; set; }
        public Status Status { get; set; }
    }
}
```

## Model Katmanı

### Search Company Database Transfer Object&#x20;

Kullanıcıdan aldığımız verileri alt katmanlara aşağıdaki veri deseniyle göndereceğiz.

```csharp
using CK.Tutorial.GraphQlApi.Common.Model;

namespace CK.Tutorial.GraphQlApi.Model.Request
{
    public class SearchCompany : RequestBase
    {
        public int? Id { get; set; }
        public string Name { get; set; }
        public bool? IsActive { get; set; }
    }
}
```

## Repository Katmanı

### ‌IRepositoryBase Interface Oluşturulması

Repository sınıflarımız için generic base bir Interface tanımlıyoruz.

{% code title="IRepository.cs" %}

```csharp
‌using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public interface IRepositoryBase<TEntity>
    {
        QueryFactory QueryFactory { get; }
    }
}
```

{% endcode %}

## RepositoryBase Sınıfının Oluşturulması <a href="#repositorybase-sinifinin-olusturulmasi" id="repositorybase-sinifinin-olusturulmasi"></a>

Oluşturacağımız Entity Repository'leri için RepositoryBase sınıfını, IRepositoryBase interface'i üzerinden oluşturuyoruz.

{% code title="RepositoryBase.cs" %}

```csharp
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public class RepositoryBase<TEntity> : IRepositoryBase<TEntity>
    {
        public RepositoryBase(QueryFactory queryFactory)
        {
            QueryFactory = queryFactory;
        }

        public QueryFactory QueryFactory { get; set; }
    }
}
```

{% endcode %}

### ‌ICompanyRepository Interface Oluşturulması

{% code title="ICompanyRepository.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public interface ICompanyRepository
    {
        Task<IEnumerable<Company>> GetCompanies(SearchCompany request);
        Task<Company> GetCompany(SearchCompany request);
    }
}
```

{% endcode %}

### CompanyRepository Sınıfının Oluşturulması

{% code title="CompanyRepository.cs" %}

```csharp
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Common.Extension;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Repository
{
    public class CompanyRepository : RepositoryBase<Company>, ICompanyRepository
    {
        private readonly QueryFactory _queryFactory;
        private const string TableName = "Company";

        public CompanyRepository(QueryFactory queryFactory) : base(queryFactory)
        {
            _queryFactory = queryFactory;
        }

        public async Task<IEnumerable<Company>> GetCompanies(SearchCompany request)
        {
            var query = _queryFactory
                .Query(TableName)
                .When(request.Columns.AnyItem(),
                    q => q.Select(request.Columns))
                .When(request.IsActive.IsNotNull(), q => q.Where("IsActive", request.IsActive.ConvertToByte()))
                .OrderBy("Id")
                .ForPage(request.Page ?? request.DefaultPage, request.PageSize ?? request.DefaultPageSize)
                .GetAsync<Company>();

            return await query.ConfigureAwait(false);
        }

        public async Task<Company> GetCompany(SearchCompany request)
        {
            var query = _queryFactory
                .Query(TableName)
                .When(request.Columns.AnyItem(),
                    q => q.Select(request.Columns))
                .When(request.Id.HasValue, q => q.Where("Id", request.Id))
                .When(request.Name.IsNotNullOrEmpty(), q => q.WhereContains("Name", request.Name))
                .When(request.IsActive.IsNotNull(), q => q.Where("IsActive", request.IsActive.ConvertToByte()))
                .OrderBy("Id")
                .FirstOrDefaultAsync<Company>();

            return await query.ConfigureAwait(false);
        }
    }
}

```

{% endcode %}

## Business Katmanı

‌Company Entity'sinin iş süreçlerini yazmak için ICompanyService adında bir interface oluşturuyoruz.&#x20;

Şimdilik iki tane metod yazacağız.&#x20;

### ICompanyService Oluşturulması

{% code title="ICompanyService.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using SqlKata.Execution;

namespace CK.Tutorial.GraphQlApi.Business
{
    public interface ICompanyService
    {
        Task<IEnumerable<Company>> GetCompanies(SearchCompany request);
        Task<Company> GetCompany(SearchCompany request);
    }
}
```

{% endcode %}

### CompanyService Sınıfının Oluşturulması

ICompanyService üzerinden CompanyService adında yeni bir sınıf oluşturuyoruz.

{% code title="CompanyService.cs" %}

```csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using CK.Tutorial.GraphQlApi.Entity;
using CK.Tutorial.GraphQlApi.Model.Request;
using CK.Tutorial.GraphQlApi.Repository;

namespace CK.Tutorial.GraphQlApi.Business
{
    public class CompanyService : ICompanyService
    {
        private readonly ICompanyRepository _companyRepository;

        public CompanyService(ICompanyRepository companyRepository)
        {
            _companyRepository = companyRepository;
        }
        
        public Task<IEnumerable<Company>> GetCompanies(SearchCompany request)
        {
            return _companyRepository.GetCompanies(request);
        }

        public Task<Company> GetCompany(SearchCompany request)
        {
            return _companyRepository.GetCompany(request);
        }
    }
}
```

{% endcode %}

## Web - Graphql Katmanı

GraphQL Schema adını verdiğimiz referans bir root sınıfından oluşur.&#x20;

Schema sınıfına Resolver bir tane QUERY referans gösterilir..

Query dosyaları ise GraphType'lardan beslenerek dinamik sorgular oluşturacağımız bir yapı kurmamızı sağlar.

Kısacası Schema > Query > GraphTypes olarak tanımlayabiliriz.

Retail adında bir tane Root Schema sınıfımızı aşağıdaki gibi tanımlıyoruz.

RetailSchema sınıfının TutorialQuery adında bir sorgulama sınıfını çözümlediğini bildiriyoruz.

### Schema Sınıfının Oluşturulması

{% code title="RetailSchema.cs" %}

```csharp
using CK.Tutorial.GraphQlApi.Web.Query;
using GraphQL;

namespace CK.Tutorial.GraphQlApi.Web.Schema
{
    public class RetailSchema : GraphQL.Types.Schema
    {
        public RetailSchema(IDependencyResolver resolver) : base(resolver)
        {
            Query = resolver.Resolve<TutorialQuery>();
        }
    }
}
```

{% endcode %}

### Company Graph Type Sınıfının Oluşturulması

Entity sınıflarımızın field alanlarını kullanarak graphql için sorgulanabilir tipler oluşturuyoruz.

Aşağıdaki örneğimizde Company Entity dosyasımızı referans göstermiş ve field alanları için Type tanımlamalarını yapmış olduğumuzu göreceksiniz.&#x20;

Örneğin Name alanı için ikinci parametre olan IsNullable alanını True vererek, bu field için null alabilen bir field düzenlemiş olduk. Diğer override parametrelerini kullanarak TYPE tipinide değiştirmeniz veya belirtmeniz mümkündür.

{% code title="CompanyGraphType.cs" %}

```csharp
using System;
using CK.Tutorial.GraphQlApi.Business;
using CK.Tutorial.GraphQlApi.Entity;
using GraphQL.Types;

namespace CK.Tutorial.GraphQlApi.Web.Types
{
    public class CompanyGraphType : ObjectGraphType<Company>
    {
        public CompanyGraphType()
        {
            Name = "Company";
            Field(x => x.Id).Description("Şirket Benzersiz No");
            Field(x => x.Name, true).Description("Şirket Adı");
            Field(x => x.IsActive, true).Description("Şirket Aktif mi?");
        }
    }
}
```

{% endcode %}

## TutorialQuery Sınıfının Oluşturulması

Bu örneğimizde 2 tane sorgulama endpoint'i oluşturacağız.

Birinci endpoint; "company" adını verdiğimiz, CompanyGraphType kullanarak sorgu yapabileceğimiz,&#x20;

* companyId
* companyName
* isActive

parametrelerinden oluşan ve return type değeri COMPANY entity sınıfımızdır. &#x20;

İkinci endpoint; "companies" adını verdiğimiz ve return tipi List\<Company> olan sınıfımızdır.

{% code title="TutorialQuery.cs" %}

```csharp
using System.Collections.Generic;
using CK.Tutorial.GraphQlApi.Business;
using CK.Tutorial.GraphQlApi.Model.Request;
using CK.Tutorial.GraphQlApi.Web.Extensions;
using CK.Tutorial.GraphQlApi.Web.Types;
using GraphQL.Types;

namespace CK.Tutorial.GraphQlApi.Web.Query
{
    public class TutorialQuery : ObjectGraphType
    {
        public TutorialQuery(ICompanyService companyService)
        {
            #region Company

            Field<CompanyGraphType>(
                name: "company",
                arguments: new QueryArguments(new List<QueryArgument>
                {
                    new QueryArgument<IntGraphType>
                    {
                        Name = "companyId"
                    },
                    new QueryArgument<StringGraphType>
                    {
                        Name = "companyName"
                    },
                    new QueryArgument<BooleanGraphType>
                    {
                        Name = "isActive"
                    }
                }),
                resolve: delegate (ResolveFieldContext<object> context)
                {
                    var columns = context.GetMainSelectedFields();

                    var companyId = context.GetArgument<int?>("companyId");
                    var companyName = context.GetArgument<string>("companyName");
                    var isActive = context.GetArgument<bool?>("isActive");

                    var request = new SearchCompany
                    {
                        Id = companyId,
                        Name = companyName,
                        IsActive = isActive,
                        Columns = columns
                    };
                    return companyService.GetCompany(request);
                });

            Field<ListGraphType<CompanyGraphType>>(
                "companies",
                arguments: new QueryArguments(new List<QueryArgument>
                {
                    new QueryArgument<ListGraphType<IntGraphType>>
                    {
                        Name = "companyIds"
                    },
                    new QueryArgument<ListGraphType<StringGraphType>>
                    {
                        Name = "companyNames"
                    },
                     new QueryArgument<BooleanGraphType>
                    {
                        Name = "isActive"
                    },
                    new QueryArgument<IntGraphType>
                    {
                        Name = "page"
                    },
                    new QueryArgument<IntGraphType>
                    {
                        Name = "pageSize"
                    }
                }),
                resolve: delegate (ResolveFieldContext<object> context)
                {
                    var columns = context.GetMainSelectedFields();
                    var companyIds = context.GetArgument<int?[]>("companyIds");
                    var companyNames = context.GetArgument<string[]>("companyNames");
                    var isActive = context.GetArgument<bool?>("isActive");

                    var page = context.GetArgument<int?>("page");
                    var pageSize = context.GetArgument<int?>("pageSize");

                    var request = new SearchCompanies()
                    {
                        Ids = companyIds,
                        Names = companyNames,
                        IsActive = isActive,
                        Page = page,
                        PageSize = pageSize,
                        Columns = columns
                    };
                    return companyService.GetCompanies(request);
                });

            #endregion
        }
    }
}
```

{% endcode %}

## Build & Run & Test

### Create Database

Öncelikle yeni bir SQL SERVER veritabanı açmalısınız.

Sonrasında database klasörü içerisinde yer alan create-table.sql dosyasını çalıştırmalısınız.

{% code title="create-table.sql" %}

```sql
-- auto-generated definition
create table Company
(
    Id       int identity
        constraint Company_pk
            primary key nonclustered,
    Name     nvarchar(200) not null,
    IsActive bit default 1 not null
)
go

create unique index Company_Id_uindex
    on Company (Id)
go


```

{% endcode %}

Sizlerin projeyi test edebilmesi için; database klasörünün içerisinde yer alan bulk-data.sql dosyasını oluşturdum, bu dosyayı çalıştırabilirsiniz.&#x20;

Projenin AppSettings dosyasını kendi connectionString değerlerinize göre güncellemesiniz.

{% code title="appsettings.json" %}

```
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "SqlServerDatabaseConnection": "Server=localhost;Database=GraphQLSample;User Id=sa;Password=Aa123456;"
  }
}

```

{% endcode %}

### DotNet Restore & Build & Run

Aşağıdaki komutları çalıştırıp projeyi ayağa kaldırabilirsiniz.

```
dotnet restore
dotnet build
dotnet run
```

### UI PlayGround&#x20;

Tarayıcınızdan <https://localhost:5001/ui/playground> adresine gitmek istediğinizde; sorgularınızı test edebileceğiniz bir arayüze erişebilmeniz gerekmektedir.

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LsJMcO3Q17Gb-t25imO%2F-LsJSx0RA55kGPCaKww8%2Fimage.png?alt=media\&token=c214bcbd-6494-4930-adb4-5434929cc066)

### Hello GraphQL For .Net

Aşağıdaki sorguyu yazdığınızda çıktısını almalısınız.

```
query {
  company(companyId:5) {
    id
    name
    isActive
  }
}
```

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-LsJMcO3Q17Gb-t25imO%2F-LsJTbH_EAsAmJfOTf9x%2Fimage.png?alt=media\&token=4ca199c1-e4f9-490b-9f48-74949fe803d0)


# Reset Identity Seed After Deleting Records in SQL Server

&#x20;Truncate edemediğiniz tabloları **Delete** komutuyla silerseniz, **Unique Identity** numaralarınız en son sildiğiniz kayıt üzerinden devam edecektir. Resetlemek için aşağıdaki betiği kullanabilirsiniz.

{% embed url="<https://gist.github.com/cagdaskarademir/22b757c58761795afbd01a704b2155b4>" %}


# Synchronous operations are disallowed.

Asp.net Core 3.0 üzerinde AllowSynchronousIO değeri False ise aşağıdaki gibi bir hata fırlatacaktır.&#x20;

Eğer aşağıdaki gibi "Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead." mesajını alırsanız;

```csharp
System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)
   at System.IO.StreamReader.ReadSpan(Span`1 buffer)
   at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append)
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at GraphQL.Server.Transports.AspNetCore.GraphQLHttpMiddleware`1.Deserialize[T](Stream s)
   at GraphQL.Server.Transports.AspNetCore.GraphQLHttpMiddleware`1.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

```

Program.cs dosyası içerisinde&#x20;

```
 .ConfigureKestrel((context, options) =>
                        {
                            options.AllowSynchronousIO = true;
                        });
```

satırını eklemeniz yeterli olacaktır.

{% code title=".net core 3.0 - program.cs" %}

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace CK.Tutorial.GraphQlApi.Web
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>()
         
               .ConfigureKestrel((context, options) =>
                        {
                            options.AllowSynchronousIO = true;
                        });
                });
    }
}
```

{% endcode %}

Reference : <https://github.com/aspnet/AspNetCore/issues/7644>


# Bootbox.js Nedir, Nasıl Kullanılır?

![](https://3110286875-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LpwSt0BdhhtnMy9YmXA%2F-Lv2VKcOOOnNOiLZNfgR%2F-Lv2YIfaACbUYQ7kW7I7%2F0_HSnxfjU15yjd4Hre.png?alt=media\&token=cb7a9ffa-5b7e-4024-883e-e1589f1383f7)

Bootboxjs, Bootstrap Modal dialog pencerelerini kolay bir şekilde oluşturabilmemizi sağlayan çok kullanışlı bir kütüphanedir. Normalde bir modal ekranı oluşturmak için modal ekranına uygun bir DOM nesnesi oluşturmamız veya gizleyebilmemiz için DOM nesnesini gizlememiz gerekirken, Bootboxjs ile bu işlemleri tek bir satır kod ile yapabiliyoruz.

Bootboxjs, bize 4 farklı template seçeneği sunuyor.&#x20;

* Alert
* Confirm
* Prompt
* Custom

## Kütüphane Bilgileri <a href="#id-0924" id="id-0924"></a>

Kütüphaneye [http://bootboxjs.com/ ](http://bootboxjs.com/)adresinden ulaşabilirsiniz.

Kaynak kodlarına ise githup üzerinden aşağıdaki adresinden ulaşabilirsiniz.

{% embed url="<https://github.com/makeusabrew/bootbox>" %}

## Template Örnekleri

### Alert Dialog (Mesaj Ekranları)

Alert diyaloglarını göstermek için

{% embed url="<https://gist.github.com/cagdaskarademir/e8d9517cdc86e4e0cacd84b40f9a4118>" %}

### Confirm (Onaylama Ekranları)

Onay diyalog ekranlarını göstermek için

{% embed url="<https://gist.github.com/cagdaskarademir/92ef8d932a53269b1656f91ec73eb51c>" %}

### Prompt (Veri Ekranları)

Bazen kullanıcıdan parametreler için veriler almamız gerekebilir. Bu ekranlar için kullanabileceğimiz kod

{% embed url="<https://gist.github.com/cagdaskarademir/df7ea63a69fc4a45a2364eef22016e95>" %}

### Custom (Özel Ekranlar)

Asıl önemli ve eğlenceli olan bölüme geldik. Bootstrap Modal bize ne kadar esneklik veriyorsa aynı şekilde Bootbox.js’de aynı özellikleri kolay bir şekilde kullanmamızı sağlıyor.

Özel diyaloglar oluşturmak için aşağıdaki kodu kullanabiliriz.

{% embed url="<https://gist.github.com/cagdaskarademir/54bbbd8d5a305daf8e6aa63c46c0f221>" %}


# Less Secure Apps — Gmail Smtp Üzerinden Mail Gönderme Hatası

Gmail kullanarak smtp protokolünden eposta göndermek istediğinizde, authentication hatası alabilirsiniz. Çünkü Google, bağlantı yapacağınız bilgisayarı veya bağlantıyı “Less Secure Apps” kategorisinde sınıflandırıyor olabilir.

Eposta gönderirken aşağıda ki mesaja benzer bir hata alırsanız;

> The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required. Learn more at- at …

&#x20;Google hesabınızı üçüncü parti uygulamalar üzerinden erişimine açmanız gerekebilir. Bunun için [Az güvenli uygulamaların hesabınıza erişmesine izin verme](https://support.google.com/accounts/answer/6010255?hl=en) yazısını okuyabilirsiniz.


