Flutter'da AppBar'ın Yüksekliğini Ayarlama

AppBar'ın sabit bir yüksekliğe sahip olmasını istiyorsanız, yapmanız gereken tek şey toolbarHeight'i istenilen sonucu elde etmek için double tipinde bir değer atamak:

import 'package:flutter/material.dart';

class Homepage extends StatefulWidget {
  const Homepage({super.key});

  @override
  State<Homepage> createState() => _HomepageState();
}

class _HomepageState extends State<Homepage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        toolbarHeight: 12,
      ),
    );
  }
}
Devamını Oku »

Tarayıcı Eklenti Yapımı

Tarayıcı eklentileri, işimizi oldukça kolaylaştıran ve tarayıcı üzerinde çalışan mini programlardır. Bu yazıda bir tarayıcı eklentisi nasıl yapılır, onu öğreneceğiz. Uzun zamandır beni her seferinde 5-10 saniye yavaşlatan rutinleşmiş bazı durumlarım oluyor. Sorunu biraz daha açmak gerekirse. Özellikle bu blogu yazarken, yazdığım kodları yazı içerisine eklemem gerekiyor. Ancak html kodu yazı içine eklerken büyüktür(>), küçüktür(<) gibi karakterlerde sorun çıkıyor. Bunların sorun çıkarmaması için < karakterini '&lt;' şeklinde kaynak kodu içerisinde değiştirmem gerekiyor. Bu noktada bunları tek tek değiştirmek yerine bir tane converter yapabilirim diye düşündüm. Özellikle tarayıcı üzerinde blog yazdığım için bunu bir tarayıcı eklentisi olarak yapmak çok mantıklı geldi. Tabi kullandığım internet tarayıcısı Edge olduğu için eklentiyi onun üzerinde test edeceğim ancak yapacağım eklenti Chrome tarayıcıda da çalışacaktır.

Problemi bildiğimize göre eklenti yapımına geçebiliriz. Öncelikle masaüstünde eklenti için bir klasör oluşturuyorum. Daha sonrasında bu klasörü VS Code ile açıyorum.

İlk olarak manifest.json adında bir dosya oluşturulur. Bu dosya eklenti ayarlarının bulunduğu bir konfigürasyon dosyasıdır:
{
    "name": "Character Converter",
    "version": "0.0.0.1",
    "manifest_version": 3,
    "description": "An extension to convert characters"
}
Sıra eklentinin çalışacağı şablonu oluşturmaya geldi. template adında bir klasör oluşturulur ve bu klasör içinde index.html adında bir dosya oluşturulur.
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Converter</title>
    </head>
    <body>
        <div>
            test
        </div>
    </body>
</html>
Daha sonrasında bu sayfanın eklenti tarafından görülmesi ve çalıştırılması için manifest.json dosyasında aşağıdaki gibi ekleme yapılır:
{
    "name": "Character Converter",
    "version": "0.0.0.1",
    "manifest_version": 3,
    "description": "An extension to convert characters",
    "action": {
        "default_popup": "template/index.html"
    }
}
Şimdi bitmemiş bu eklentiyi test etmek için edge://extensions'ı açın ve Developer Mode'u aktif edin:
Tarayıcı Eklenti Yapımı
Load unpacked butonuna tıklayın ve oluşturduğumuz proje klasörünü seçin:
Eklenti Yükleme
Seçilme işlemi yapıldıktan sonra aşağıda olduğu gibi eklentimiz başarılı bir şekilde yüklenmiş olacak:
Yüklenen Eklenti
Ancak diğer eklentilerin yanında yeni eklediğimiz bu eklenti bulunmuyor olabilir. Eklentiyi görülür yapmak için aşağıdaki gibi yapalım:
Eklentiyi Görünür Kılma
Şimdi eklentimizi çalıştıralım:
Eklenti Demo

Yukarıda görüldüğü gibi eklenti başarılı bir şekilde çalıştırıldı. Şimdi sıra bu eklentiye biraz tasarım vermede. İlk olarak template klasörü içinde style.css adında dosya oluşturulur:
#content{
    width: 320px;
    height: 240px;
}
Daha sonrasında style.css dosyasını index.html içinde çağıralım ve ona uygun bazı düzenlemeler yapalım:
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Converter</title>
        <link rel="stylesheet" href="/template/style.css"/>
    </head>
    <body>
        <div id="content">
            <h1>Converter</h1>
            <p>Test</p>
        </div>
    </body>
</html>
Eklentiyi tekrar çalıştıralım:
Eklenti Çalıştırma
Tasarımı artık istediğimiz gibi style.css üzerinden ayarlayabiliriz. 

Bu yazdığımız eklentinin amacı içindeki textarea'ya yapıştırılan kodu, benim kullanmak istediğim hale dönüştürmesiydi. O sebeple index.html'de bir tane textarea ekleyeceğim. Ayrıca bir tane de buton ekleyeceğim. Bu butonun ismi Convert olacak. 
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Converter</title>
        <link rel="stylesheet" href="/template/style.css"/>
    </head>
    <body>
        <div id="content">
            <h1>Converter</h1>
            <textarea id="content-text"></textarea>
            <button id="convert-button">Convert it</button>
        </div>
    </body>
</html>
Daha sonrasında tasarımını oluşturalım basitçe:
#content{
    width: 320px;
    height: 240px;
    padding: 5px;
}

#content-text{
    width: 100%;
    resize: none;
    height: 100px;
}

#convert-button{
    width: 325px;
    height: 30px;
    margin-top: 10px;
    background-color: dimgrey;
    color:beige;
    cursor: pointer;
}
Tasarımı kontrol edelim:
Eklenti Tasarımı

Bu Convert it isimli butona tıklanınca tetiklenmesi gerek. Bu tetiklenme yazacağımız JavaScript kodu tarafından algılanacak. JS tarafında ilk olarak html element'lerimize id sayesinde ulaşmamız gerek. Ancak öncesinde bir JavaScript dosyası oluşturalım template içinde ve daha sonrasında bu dosyayı index.html içinde çağıralım:
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Converter</title>
        <link rel="stylesheet" href="/template/style.css"/>
    </head>
    <body>
        <div id="content">
            <h1>Converter</h1>
            <textarea id="content-text"></textarea>
            <button id="convert-button">Convert it</button>
        </div>

        <script src="/template/script.js"></script>
    </body>
</html>
Daha sonrasında gerekli JS kodumu yazıyorum:
const contentText = document.getElementById("content-text");
const convertButton = document.getElementById("convert-button");

// butona tıklanınca fonksiyonu çalıştır
convertButton.onclick = function() {
    var characters = {
        "&" : "&amp;",
        "<" : "&lt;",
        ">" : "&gt;"
    };

    contentText.value = converter(characters);
}

// json object içinde verilen verilere göre dönüştürme yap
var converter = function(obj) {
    var textValue = contentText.value;

    for (var key in obj) {
        textValue = textValue.replaceAll(key, obj[key]);
    }

    return textValue;
}
Basit bir js kodu yazdım. Biraz incelerseniz neyin ne olduğunu rahatlıkla anlayabilirsiniz. Eklentiyi çalıştıralım:
Converter Test

Converter düzgün bir şekilde çalışıyor. Elbette daha gelişmiş bir versiyonunu yapmaya devam edeceğim, ancak yazının daha fazla uzamaması adına burada bitiriyorum. Zaten az çok nasıl eklenti yapılır onu yeterince göstermiş olduk: Bu konuda daha fazla ayrıntılı bilgi edinmek isterseniz şu bağlantıdan Extension concepts and architecture - Microsoft Edge Development | Microsoft Docs dokümentasyonu incelemenizi öneririm. İyi çalışmalar.

Devamını Oku »

ASP.NET Core ile Kayıt Silme

Kayıt silme işlemi yaparken, farklı bir yöntem izleyeceğim. Veri tabanından kayıtları silmek yerine isAktif adında bir property ekleyeceğim. Eğer isAktif true ise bu kelimeye kullanıcı tarafından erişilsin, değil ise erişilmesin.

Model klasöründe yer alan Kelime modelinde aşağıdaki eklemeyi yapıyorum ve daha sonrasında migration yapıp, veri tabanını güncelliyorum:

using System.ComponentModel.DataAnnotations;

namespace OgrenKelime.Models
{
    public class Kelime
    {
        [Key]
        public int Id { get; set; }
        public string? SKelime { get; set; }
        public string? SAnlam { get; set; }
        public DateTime DtKayitTarihi { get; set; } = DateTime.Now;
        public bool IsAktif { get; set; } = true;
    }
}
Migration ve db güncelleme:
PM> Add-Migration "3- IsAktif ekle"
PM> Update-Database
SQL Server Management Studio'dan kontrol sağlayalım:
Veri tabanı
Tabi var olan her kaydın IsAktif değeri false varsayılan olarak false(0) görünüyor. Ancak yeni bir kayıt eklersek IsAktif değerinin de True(1) olması gerekiyor. Örnek olarak bir tane kayıt ekleyelim ve veri tabanında nasıl kaydedildiğine bir bakalım:
Veri tabanı yeni kayıt
Bu noktadan itibaren kelime listeleme de bir düzenleme yapmamız gerekiyor. IsAktif değeri false olanlar kullanıcıya listelenmemeli. Sadece IsAktif değeri true olanlar kullanıcıya listelenmeli. KelimeController'da Get metotu olarak çalışan Listele() metodunda aşağıdaki değişiklik yapılır. Burada LINQ kullandık:
[HttpGet]
public async Task<IActionResult> Listele()
{
    return View(await _context.Kelimes.Where(x => x.IsAktif == true).ToListAsync());
}
Sonuca bakalım:
Kelime Listeleme

Şimdi sıra silme işlemi yapacak olan bir action metodu yazmak:

        ...
        [HttpGet]
        public async Task<IActionResult> Sil(int? id)
        {
            if (id == null)
                return NotFound();

            Kelime? kelime = _context.Kelimes.FirstOrDefault(o => o.Id == id);

            if (kelime == null)
                return NotFound();

            kelime.IsAktif = false;
            await _context.SaveChangesAsync();

            return RedirectToAction("Listele");
        }
    }
}
Listeleme.cshtml dosyasına sil butonu ekleyelim:
@model IEnumerable<OgrenKelime.Models.Kelime>
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Kelime Listesi";
    Layout = "~/Views/_Layout.cshtml";
}
@{
    <h1>@ViewData["Title"]</h1>
    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">Kelime</th>
                <th scope="col">Anlamı</th>
                <th scope="col">Kayıt Tarihi</th>
                <th scope="col">İşlemler</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            { 
                <tr>
                    <td>@item.SKelime</td>
                    <td>@item.SAnlam</td>
                    <td>@item.DtKayitTarihi</td>
                    <td>
                        <a asp-action="Guncelle" asp-route-id="@item.Id">Güncelle</a>
                        <a asp-action="Sil" asp-route-id="@item.Id">Sil</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}
Projeyi çalıştırıp, test edelim ama daha öncesinde birkaç tane yeni kayıt eklersek daha iyi olur:
Kayıt silme
Oldukça başarılı bir şekilde çalıştı. Yapmak istediğimizi yaptık. Ancak tek yöntem bu değil. Proje çok büyük olmadığı için bu tarz bir yöntem uygulamak bana daha mantıklı geldi.

Devamını Oku »

C# Indexer Nedir?

Indexer, bir sınıf nesnesini array gibi kullanmamızı sağlar. Aynı zamanda struct'larda da indexer kullanabiliriz. Bir array tanımlarken o array'in ilgili indeksine nasıl değer atayıp, daha sonrasında o değeri kullanmak için indeks aracılığıyla o array üzerinden ulaşabiliyorsak, bunu indexer aracılığı ile sınıflarda da yapabiliriz. Şimdi bunu örnekle beraber anlamaya çalışalım.

İlk olarak Sınıf(eğitim odaları anlamındaki sınıf) ve Öğrenci olmak üzere iki tane class tanımlayalım. Sınıf adlı class'da indexer kullanacağım:

using System;

public class Ogrenci
{
    public int Numara {get; set;}
    public string Ad {get; set;}
    public string Soyad {get; set;}
}

public class Sinif
{
    private Ogrenci[] ogrenciler = new Ogrenci[30];
    
    public Ogrenci this[int i]
    {
        get { return ogrenciler[i]; }
        set { ogrenciler[i] = value; }
    }
}

public class HelloWorld
{
    public static void Main(string[] args)
    {
        Sinif sinif12b = new Sinif();
        sinif12b[0] = new Ogrenci() {
            Numara = 384,
            Ad = "Saltuk",
            Soyad = "Balaban",
        };
        
        // çıktı: Saltuk
        Console.WriteLine(sinif12b[0].Ad);
    }
}
Devamını Oku »

ASP.NET Core ile Kayıt Güncelleme

Bazı durumlarda kayıt güncellememiz gerekebilir. Örneğin, bir veri yanlış girilmiştir ve onu düzeltmemiz lazım. Bir önceki yazıyı okuduysanız ilk iki kaydın verileri boş, ancak biz ilgili alanları güncelleyerek o boşlukları giderebiliriz. 

İlk olarak KelimeController'da bir Guncelle adında iki tane action metot yazalım:

        [HttpGet]
        public async Task<IActionResult> Guncelle(int? id)
        {
            if (id == null)
                return NotFound();

            return View(await _context.Kelimes.FirstOrDefaultAsync(o => o.Id == id));
        }

        [HttpPost]
        public async Task<IActionResult> Guncelle(Kelime kelime)
        {
            if(kelime == null)
                return NotFound();


            Kelime? kayitliKelime = _context.Kelimes.FirstOrDefault(o => o.Id == kelime.Id);

            if (kayitliKelime != null)
            {
                kayitliKelime.SKelime = kelime.SKelime;
                kayitliKelime.SAnlam = kelime.SAnlam;

                await _context.SaveChangesAsync();
                return RedirectToAction("Listele");
            }

            return NotFound();
        }
    }
}
Get metotu olarak çalışacak Guncelle için bir tane view ekleyelim(Guncelle.cshtml). Ekle.cshtml dosyasındaki kodun aynısını bazı değişiklikler yaparak kullanıyorum:
@model OgrenKelime.Models.Kelime
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Kelime Güncelle";
    Layout = "~/Views/_Layout.cshtml";
}
@{
    <h1>@ViewData["Title"]</h1>
    <form method="post" action="Guncelle">
        <div class="row">
            <input hidden asp-for="Id" />
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimeyi yaz.." asp-for="SKelime">
            </div>
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimenin anlamı.." asp-for="SAnlam">
            </div>
            <div class="col">
                <button type="submit" class="btn btn-primary">Güncelle</button>
            </div>
        </div>
    </form>
}

Kayıtları listelerken aynı zamanda o satırların içerisine buton koyabiliriz(Listele.cshtml):

@model IEnumerable<OgrenKelime.Models.Kelime>
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Kelime Listesi";
    Layout = "~/Views/_Layout.cshtml";
}
@{
    <h1>@ViewData["Title"]</h1>
    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">Kelime</th>
                <th scope="col">Anlamı</th>
                <th scope="col">Kayıt Tarihi</th>
                <th scope="col">İşlemler</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            { 
                <tr>
                    <td>@item.SKelime</td>
                    <td>@item.SAnlam</td>
                    <td>@item.DtKayitTarihi</td>
                    <td>
                        <a asp-action="Guncelle" asp-route-id="@item.Id">Güncelle</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}
Testimizi yapalım:
MVC Kayıt Güncelleme

İşlem başarılı.
Devamını Oku »

ASP.NET Core ile Kayıt Listeleme

Bir önceki yazıda kayıt eklemeyi yapmıştık. Bu yazıda ise eklediğimiz kayıtların listelenmesini sağlayacağız. Yapacağımız işlem çok basit. Öncelikle KelimeController'da bir tane ActionMethod yazacağız. Yazacağımız bu metot bize bir kayıt listesi döndürecek. Daha sonrasında bu döndürülen liste view kısmında html table yapısı içerisinde for ile döndürülecek ve kullanıcıya sunulacak.

Öncelikle controller için gerekli action metodunu yazalım:

        ...

        [HttpGet]
        public async Task<IActionResult> Listele()
        {
            return View(await _context.Kelimes.ToListAsync());
        }
    }
}
Oluşturduğum action metodu üzerinden bir tane Listele.cshtml adında view oluşturuyorum:
@model IEnumerable<OgrenKelime.Models.Kelime>
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Kelime Listesi";
    Layout = "~/Views/_Layout.cshtml";
}
@{
    <h1>@ViewData["Title"]</h1>
    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">Kelime</th>
                <th scope="col">Anlamı</th>
                <th scope="col">Kayıt Tarihi</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>@item.SKelime</td>
                    <td>@item.SAnlam</td>
                    <td>@item.DtKayitTarihi</td>
                </tr>
            }
        </tbody>
    </table>
}
Projeyi çalıştırıp, Kelime/Listele endpoint'ine tarayıcı üzerinden girelim:
Kayıt Listeleme
İşlem başarılı, ilk iki kayıt önceki yazılarda eklemediğimiz bir namespace'den dolayı null olarak kayıt edilmişti. O yüzden ilk iki kaydın boş görünmesi normal. Bir sonraki yazıda bu kayıtların güncellenmesi nasıl yapılır, onu öğreneceğiz.
Devamını Oku »

ASP.NET Core ile Kayıt Ekleme

Gerekli Entity Framework Core kurulumunu önceki yazıda yapmıştık. Bu yazıda ise kayıt ekleme için gerekli ilk controller'i yazacağız. Kelimes adında bir tane tablomuz vardı. Bu tabloya kayıt eklenmiş mi daha sonrasında kontrol edeceğiz.

İlk olarak Kelime adında bir controller oluşturuyorum (KelimeController.cs). Sonrasında ise Ekle adında bir action method yazıyoruz, bu method HttpGet kullanacak:

using Microsoft.AspNetCore.Mvc;

namespace OgrenKelime.Controllers
{
    public class KelimeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public IActionResult Ekle()
        {
            return View();
        }
    }
}
Oluşturulan bu method için Ekle adında(Ekle.cshtml) boş bir view oluşturalım. Views klasörü içinde Kelime/Ekle.cshtml olarak dosyamız görülecektir.

Kullanıcının kayıt eklemesi için bir arayüz oluşturmamız lazım. Kayıt ekleme formunu bootstrap ile basit bir şekilde oluşturalım:
@model OgrenKelime.Models.Kelime

@{
    <h1>Kelime Ekle</h1>
    <form method="post" action="Ekle">
        <div class="row">
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimeyi yaz" name="kelime" asp-for="SKelime">
            </div>
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimenin anlamını gir" name="anlam" asp-for="SAnlam">
            </div>
            <div class="col">
                <button type="submit" class="btn btn-primary">Kaydet</button>
            </div>
        </div>
    </form>
}
Şimdi HttpPost metodunu yazalım. Bu metot içerisinde veri tabanına kayıt işlemi sağlanacak. Tabi bunu yapabilmek için DbContext kullanmamız gerek. Kayıt işlemi bittikten sonra Diğer Ekle metoduna redirect sağlanacak:

İlk olarak bir constructor metodu yazalım:

using Microsoft.AspNetCore.Mvc;
using OgrenKelime.Models;

namespace OgrenKelime.Controllers
{
    public class KelimeController : Controller
    {
        private readonly DataContext _context;
        public KelimeController(DataContext _context)
        {
            this._context = _context;
        }
        ...
Ekle metodunu yazmadan evvel Kelime model yapısına bazı önemli eklemeler yapmak istiyorum. Öncelikle Id property'sini PK olarak tanımlamak ve sonrasında kayit esnasında o an hangi tarih ise o tarih kaydedilsin.
using System.ComponentModel.DataAnnotations;

namespace OgrenKelime.Models
{
    public class Kelime
    {
        [Key]
        public int Id { get; set; }
        public string? SKelime { get; set; }
        public string? SAnlam { get; set; }
        public DateTime DtKayitTarihi { get; set; } = DateTime.Now; 
    }
}
Bu değişiklilerden sonra veri tabanı için migration ve güncelleme yapmamız gerek. Package Manager Console'u açalım ve :
PM> Add-Migration "2- kelime"
PM> Update-Database
SQL Server Management Studio üzerinden kontrol edersek değişiklik başarılı şekilde gerçekleştirildi:
ASP.NET Core Kayıt Ekleme
Şimdi metotu yazmaya başlayabiliriz:
...

namespace OgrenKelime.Controllers
{
    public class KelimeController : Controller
    {
        private readonly DataContext _context;
        
        ...
        
        [HttpGet]
        public IActionResult Ekle()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Ekle(Kelime kelime)
        {
            Kelime yeniKelime = new Kelime()
            {
                SKelime = kelime.SKelime,
                SAnlam = kelime.SAnlam
            };

            await _context.Kelimes.AddAsync(yeniKelime);
            await _context.SaveChangesAsync();

            return RedirectToAction("Ekle");
        }
    }
}
Artık ekleme eylemini test edebiliriz. Projeyi çalıştırıp, https://localhost:[portnumber]/Kelime/Ekle adresine gidelim. Aşağıdaki gibi ilk kaydımızı ekleyelim:

ASP.NET Core Kayıt Ekleme
Bakalım veri tabanına kayıt eklenmiş mi, kontrol edelim.
ASP.NET Core Kayıt Ekleme
Kayıt geldi ancak Kelime ve Anlam değerleri null olarak görülüyor. Muhtemelen html tarafından kaynaklı bir durum ve asp-for bildirimi çalışmıyor:
@model OgrenKelime.Models.Kelime
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    <h1>Kelime Ekle</h1>
    <form method="post" action="Ekle">
        <div class="row">
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimeyi yaz" asp-for="SKelime">
            </div>
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimenin anlamını gir" asp-for="SAnlam">
            </div>
            <div class="col">
                <button type="submit" class="btn btn-primary">Kaydet</button>
            </div>
        </div>
    </form>
}
Bu işlemden sonra tekrar deneyelim:
ASP.NET Core Kayıt Ekleme
Eklediğimiz son veri başarılı bir şekilde eklenmiş. 

Tasarım kısmında bir terslik var, çünkü layout tanımlamadık:
@model OgrenKelime.Models.Kelime
@addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Kelime Ekle";
    Layout = "~/Views/_Layout.cshtml";
}
@{
    <h1>Kelime Ekle</h1>
    <form method="post" action="Ekle">
        <div class="row">
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimeyi yaz" asp-for="SKelime">
            </div>
            <div class="col">
                <input type="text" class="form-control" placeholder="Kelimenin anlamını gir" asp-for="SAnlam">
            </div>
            <div class="col">
                <button type="submit" class="btn btn-primary">Kaydet</button>
            </div>
        </div>
    </form>
}

Sonuca bakalım:
ASP.NET Core Kayıt Ekleme
Elbette daha fazla düzenlemeye ihtiyaç var, bu da artık sonraki yazılara kaldı.
Devamını Oku »

Entity Framework Core Kurulumu

Entity Framework Core, veritabanı üzerinden kolayca işlemler yapmamızı sağlayan bir teknolojidir. İlk başta ihtiyacımız olan nuget paketleri yüklememiz gerek. Nuget package manager üzerinden aşağıdaki paketleri indirip, kuralım:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools 
Resimde olduğu gibi her iki paketi yükleyin.
Entity Framework Core Kurulumu
Artık bir DbContext sınıfı oluşturabiliriz. Peki DbContext sınıfı nedir? Yapacağımız web uygulaması ile veri tabanı arasında iletişim kurmamız sağlayacak olan yapıdır. Örneğin, veri tabanında bir belirli bir tabloya veri eklemek istersek, bunu uygulama kodu içerisinde DbContext sınıfından üretilen bir nesne aracılığıyla yapabilmemiz mümkün olacaktır.

Models klasörü içerisinde bir tane DataContext.cs adında bir sınıf oluşturuyorum:
using Microsoft.EntityFrameworkCore;

namespace OgrenKelime.Models
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions options) : base(options)
        {
        }
    }
}
Ancak daha bir model oluşturmadık. Hatırlarsanız yazı serisinin başında yabancı dil kelime öğrenme üzerine bir uygulama yapacağımızı söylemiştim. Buna göre Kelime adında bir model oluşturmam gerek. Bu modelin bir id'si, kelime isminin kendisi ve o kelimenin anlamı olacak. Şimdilik üç tane property yeterli gibi ancak ileride muhtemelen bu modeli güncelleyeceğiz. Yine Models klasöründe Kelime adında bir model (Kelime.cs) oluşturalım:
namespace OgrenKelime.Models
{
    public class Kelime
    {
        public int Id { get; set; }
        public string? SKelime { get; set; }
        public string? SAnlam { get; set; }
        public DateTime DtKayitTarihi { get; set; }
    }
}
Oluşturduğumuz bu model aslında veri tabanında yer alacak olan tabloyu temsil etmektedir. Modeli tanımladığımıza göre artık DbContext içerisinde tablo olarak tanımlama yapabiliriz:
using Microsoft.EntityFrameworkCore;

namespace OgrenKelime.Models
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<Kelime> Kelimes { get; set; }
    }
}
Uygulamamızın oluşturduğumuz DbContext'den daha haberi yok. O sebeple ilk olarak veri tabanına bağlantı sağlamamız gerek. Bilgisyarınızda MsSQL server kurulu olması lazım ben developer edition'u daha öncesinden kurmuştum, ayrıca SQL Server Managment Studio'u da kurmanız gerekiyor.
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "TempConnectionString": "Server=localhost;Database=ogrenkelimedb;Trusted_Connection=True;"
  }
}
Program.cs dosyamızı açalım:
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using OgrenKelime.Models;

var builder = WebApplication.CreateBuilder(args);

// mvc service
builder.Services.AddControllersWithViews();

builder.Services.AddDbContext<DataContext>(options => 
    options.UseSqlServer(builder.Configuration.GetConnectionString("TempConnectionString")));
    ...
Sonraki adımımız ef migration'ları çalıştırmak ve yeni veri tabanımızı oluşturmak. VS'den package manager console'u açıp, aşağıdaki komutları sırasıyla girelim:
PM> Add-Migration "first migration"
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 6.0.6 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer:6.0.6' with options: None
To undo this action, use Remove-Migration.
Proje dizinini incelerseniz Migrations adında bir klasör gelmiş olacak. İlk tablomuzu başarılı bir şekilde oluştuğunu migration dosyası içinde görebiliriz: 
EF Migration

Sonrasında ikinci komutu girelim. Bu komut sayesinde oluşturuğumuz migration'u kullanarak veri tabanını güncelliyoruz:
PM> Update-Database
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 6.0.6 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer:6.0.6' with options: None
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (351ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      CREATE DATABASE [ogrenkelimedb];
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (155ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') ≶> 5
      BEGIN
          ALTER DATABASE [ogrenkelimedb] SET READ_COMMITTED_SNAPSHOT ON;
      END;
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [__EFMigrationsHistory] (
          [MigrationId] nvarchar(150) NOT NULL,
          [ProductVersion] nvarchar(32) NOT NULL,
          CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
      );
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [MigrationId], [ProductVersion]
      FROM [__EFMigrationsHistory]
      ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Migrations[20402]
      Applying migration '20220712131011_first migration'.
Applying migration '20220712131011_first migration'.
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [Kelimes] (
          [Id] int NOT NULL IDENTITY,
          [SKelime] nvarchar(max) NULL,
          [SAnlam] nvarchar(max) NULL,
          [DtKayitTarihi] datetime2 NOT NULL,
          CONSTRAINT [PK_Kelimes] PRIMARY KEY ([Id])
      );
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
      VALUES (N'20220712131011_first migration', N'6.0.6');
Done.
Bu işlemden sonra SQL Server Management Studio'dan yeni veri tabanımızın ve eklediğimiz Kelimes tablosunun başarılı bir şekilde oluşturulmuş olduğunu görebiliriz. 
SSMS Test
Devamını Oku »

MySQL Root Parola Sıfırlama

Öncelikle mysql-init.txt adında bir text dosyası oluşturun ve aşağıdaki sql komutunu içerisine ekleyin.
ALTER USER 'root'@'localhost' IDENTIFIED BY 'sifre1234';
Sonrasında bu dosyayı C diskine kopyalayın ve konumu şu şekilde elimizde olsun C:\mysql-init.txt 

Eğer services.msc üzerinde MySQL80 servisinin durumu "Running" ise durdurun. CMD'yi yönetici olarak açın ve aşağıdaki komutla ile istenen dizine girin:
cd "C:\Program Files\MySQL\MySQL Server 8.0\bin"
Devamında ise aşağıdaki komutu çalıştırarak root şifresini başarılı bir şekilde sıfırlayın.
mysqld --init-file=C:\\mysql-init.txt
Eğer bu komut işe yaramazsa aşağıdaki komutu deneyin.
mysqld --defaults-file="C:\\ProgramData\\MySQL\\MySQL Server 8.0\\my.ini" --init-file=C:\\mysql-init.txt
İşlem bittikten sonra services.msc kısmından MySQL80'i tekrar çalıştırmayı unutmayın.
Devamını Oku »

ASP.NET Core ile Proje Oluşturma

Visual Studio 2022 kullanacağım. Create a New Project diyelim. Normalde hazır şekilde MVC kurulu şekilde projemizi başlatabiliriz. Ancak ben boş bir ASP.NET Core web uygulaması oluşturmayı tercih ediyorum. Bunun sebebi, yapılacak uygulamanın yapısını daha temelden görüp neyin ne olduğunu daha iyi kavramak için.

ASP.NET Core ile Proje Oluşturma

Daha sonrasında projeyi adlandıralım.

ASP.NET Core ile Proje Oluşturma

Hedef olarak .NET 6.0'ı seçelim. Hem yeni teknolojiye ayak uydurmuş oluruz.

ASP.NET Core ile Proje Oluşturma

Artık boş projemiz oluşturuldu. Önceden ASP.NET Core ile proje yaptıysanız startup.cs adlı bir dosya olduğunu bilirsiniz, artık yok. Program.cs dosyasında basit bir endpoint oluşturulmuş ve "Hello World!" string değeri döndürüyor.

ASP.NET Core ile Proje Oluşturma

Wev sayfaların dinamikliği için razor kullanacağız diye bahsetmiştim. O sebeple Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation paketini indirmeliyiz. En güncel halini nuget package manager üzerinden kuralım. Kurduktan sonra Program.cs dosyasında aşağıdaki eklemeler ve değişiklikler yapılır:

var builder = WebApplication.CreateBuilder(args);

// mvc service
builder.Services.AddControllersWithViews();


var app = builder.Build();

// alınan hataları görmek için ekledik
app.UseDeveloperExceptionPage();
// controller'a bağlı default route builder'i aktif ettik.
app.MapDefaultControllerRoute();

app.Run();
Sonrasında ise static dosyaların bulunacağı bir klasöre ihtiyacımız var. Bunun adı wwwroot klasörüdür. Eklemek için projeye sol tıklanır ve wwwroot adında bir klasör eklenir. Ancak işimiz tam bitmedi. Static dosyaları projede kullanabilmemiz için program.cs dosyasında middleware eklememiz gerek:
var builder = WebApplication.CreateBuilder(args);

// mvc service
builder.Services.AddControllersWithViews();


var app = builder.Build();

// alınan hataları görmek için ekledik
app.UseDeveloperExceptionPage();

// statik dosyaları kullan.
app.UseStaticFiles();

// controller'a bağlı default route builder'i aktif ettik.
app.MapDefaultControllerRoute();

app.Run();
Şimdi sıra projede MVC yapısını oluşturmaya geldi. Models, Controllers ve Views adında üç tane klasör oluşturuyoruz proje içinde: 

ASP.NET Core ile Proje Oluşturma
İlk controller'i ekleyelim. Peki controller nedir? Controller basitçe açıklamak gerekirse HTTP requestleri ele alan bir yapıdır. Örneğin, HomeController içinde Aciklama adında bir action metodunun çalışması için Home/Aciklama request'i verilmesi lazım. Benim basitçe anladığım böyle bir şey. Hadi bir tane oluşturalım.

Controllers klasörüne sağ tıkla ve Add butonu ile Controller'i seç. Sonrasında MVC Controller - Empty seç ve TestController.cs adında bir dosya oluştur. İlk controller başarılı bir şekilde eklendi.

ASP.NET Core ile Proje Oluşturma
Oluşturduğumuz contoller'a sağ tıklayın ve Add View ile devam edin:

Sonrasında hiçbir şeyi değiştirmeden Add butonuna tıklayın. Bu süreçte biraz bekleyebilirsiniz:

ASP.NET Core ile Proje Oluşturma
Daha sonrasında h1 etiket içeriğini değiştirdim. 

ASP.NET Core ile Proje Oluşturma
Projeyi çalıştıralım ve projemize bağlanalım. Muhtemelen This localhost page can’t be found gibi bir hata alacaksınız. Şimdi url adresinize /Test ekleyip öyle devam edin:

ASP.NET Core ile Proje Oluşturma
Layout sayfamızıda eklememiz gerek. Layout sitenin sabit kısımlarını içeren bir yapıdır. View klasörüne sağ tıklayın ve add view yapın. Sonrasında Razor View - Empty seçeneğini seçip ekleyin. Sonraki ekranda ise Razor Layout'u seçin.

ASP.NET Core ile Proje Oluşturma



Views klasöründe _Layout.cshtml adlı bir dosya oluşmuş olacak.

ASP.NET Core ile Proje Oluşturma



Projeye bootstrap eklemek istiyorum. Bunun için npm kullanacağım. Proje dizinine npm Configuration file'ı dahil edelim:

ASP.NET Core ile Proje Oluşturma
{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "bootstrap": "5.1.3"
  }
}
Bootstrap'i yukarıdaki gibi ekledim. Kaydettikten belli bir süre sonra dependencies klasöründe npm klasörü ve istediğimiz kütüphane yüklenmiş olacaktır. Eğer görmüyorsanız dosyaları muhtemelen daha projeye dahil etmemiş olmanızdandır. O sebeple Show All Files butonuna tıklarsak, proje dizininde node_modules klasörünü projeye dahil edelim. Yükleme tamam ancak bunu kullanmamız için Program.cs üzerinde bir ayar yapmamız lazım:
...
// alınan hataları görmek için ekledik
app.UseDeveloperExceptionPage();

// statik dosyaları kullan.
app.UseStaticFiles();

app.UseStaticFiles(
        new StaticFileOptions()
        {
            FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, @"node_modules")),
            RequestPath = "/staticfiles"
        }
    );
...
Şimdi çalışıyor mu diye bir test yapalım. Test içerisinde yer alan index view'de layout'u tanımlayalım:

@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/_Layout.cshtml";
}

<h1>Index</h1>
Sonrasında projeyi çalıştıralım:
ASP.NET Core ile Proje Oluşturma
Başarılı bir şekilde eklenmiş. Bu yazı fazlasıyla uzun oldu o yüzden burada sonlandırıyorum. Zaten genel olarak projemizin geliştirileceği alanı temel olarak yapmış olduk.
Devamını Oku »

ASP.NET Core ile Web Uygulaması Yapımı

Uzun zamandır aklımda olan bir web üzerinde gerçekleştirmek istiyordum. Ancak kendimi web geliştirme tarafında çok yetkin bulmadığım için pek bir girişimde bulunmamıştım. Hazır boş vaktim varken bu olaya el atmak ve bir yazı serisi oluşturmak istedim. Bu yazı serisi projeden kaynaklı çok uzun sürebilir ve ek olarak kesinlikle belirli bir web geliştirme böyle yapılır iddiası yoktur. Eğer yazı serisini takip edecekseniz bunu şimdiden bilmeniz yararınıza olur.

Projede ASP.NET Core, MySQL kullanacağım, arayüz kısmında ise hangi framework'u kullanacağıma daha emin değilim o yüzden şimdilik klasik olarak razor ile yoluma devam edeceğim. Yapacağım uygulama yabancı dil kelime öğrenme üzerine olacak. Seri ilerledikçe bu uygulamayı ne kadar geliştirebileceğiz göreceğiz. Çünkü doğaçlama ilerleyeceğim. Seriye başlayalım:

  1. ASP.NET Core ile Proje Oluşturma
  2. Entity Framework Core Kurulumu
  3. Kayıt Ekleme
  4. Kayıt Listeleme
  5. Kayıt Güncelleme
  6. Kayıt Silme


Devamını Oku »

Kivy ile Android Uygulama Geliştirme

Kivy sayesinde Python ile uygulama geliştirebilirsiniz. Uygulamayı geliştirmeye başlamadan önce Kivy framework'u yüklü olmalı:

pip install kivy
***[pip kurulumu için https://packages.msys2.org/package/mingw-w64-x86_64-python-pip] MinGW üzerinden Python kullandığım için msys2 package manager üzerinden kurulumu yaptım. Kurulum yöntemi Python'u cihazınıza nasıl yüklediğinize bağlı olarak değişiklik gösterebilir.***


Kivy Kurulum Hatası Aldıysanız Okuyun

Muhtemelen kivy kurarken hata alacaksınız. Benim gibi 😑. Uzun, kırmızı renkli satırlar.. 15 dakikalık bir inceleme sonucunda aynı şekilde farklı Python framework'leri kurmak istediğim zaman da başarısız sonuçlar elde edildiğini farkettim. Yani anlayacağınız Python'un kendisi tam olarak sizden istenildiği şekilde bilgisayarınızda kurulu değil. Böyle gecekondu gibi kurulmuş bilgisayarınıza. Tam ve sağlıklı bir kurulum için Download Python | Python.org verilen bağlantıyı kullanın. Msys2 üzerinden cihazınıza Python falan yüklemeyin. Msys2 iyidir tabi orası ayrı. Bu notu ekliyorum çünkü bu yüzden hata alan kişilere yardımcı olabilir.

Küçük Bir Uygulama Testi

Oluşturduğum bir klasörde iki ayrı python dosyası oluşturdum. Bu dosyaların ismi main.py ve testapp.py. Böyle yapma sebebim alışkanlıktan dolayı, siz tüm kod işlemlerini direkt main.py dosyası üzerinden de yapabilirsiniz:
testapp.py
from kivy.app import App
from kivy.uix.label import Label

class TestApp(App):
    def build(self):
        return Label(text="Pop şarkısı")
main.py
from kivy.app import App
from kivy.uix.label import Label

class TestApp(App):
    def build(self):
        return Label(text="Pop şarkısı")
CMD üzerinden proje dizininde olmak üzere ".\main.py" komutunu çalıştırdım ve şu şekilde bir sonuç elde ettim:
kivy ilk uygulama

Farkedileceği üzere uygulama tasarım kısmı yine kod tarafında yapılmaktadır. Bu ileri seviye bir uygulama için dezavantajdır. Çünkü kodu iyice karmaşıklaştırır. Bu yüzden tasarım tarafı .kv uzantılı dosyalar üzerinden yönetilecektir:

testapp.kv adında bir dosya oluşturulur aynı dizin içinde:
#:kivy 2.1

<boxLayout>:
    orientation: "vertical"

    Label:
        text: "pop"

    Button:
        text: "tıkla"
Sonrasında testapp.py dosyasında aşağıdaki değişiklik yapılır:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout

class TestApp(App):
    def build(self):
        return BoxLayout()
Şimdi çalıştıralım:
kivy tasarım
Burada ciddi bir uygulama yapmayacağım zaten internet üzerinde bir sürü kaynak bu konu hakkında mevcut. Şimdi sırada bu uygulamayı Android üzerinde çalıştırmak. Uygulamanın derlemesi için de Linux gerekli. Sıkıntı yok, Windows Subsystem var. Microsoft Store'dan Ubuntu Subsystem'i kurmanız yeter. Bu sayede cross-platform uygulamaları rahatlık geliştirebiliyoruz. Buradan itibaren şu bağlantıdaki anlatıma göre ilerleyeceğim https://buildozer.readthedocs.io/en/latest/installation.html. Subsystem'i açın ve sırasıyla rehberde olan talimatları yerine getirin. Ancak ben daha farklı bir yol izleyeceğim, Google Colab denilen bir platform kullanacağım. Bu platform size ücretsiz olarak bir nevi bilgisayar donanımı tahsil ediyor. Yani Windows bilgisayarınız üzerinden internet tarayıcısı aracılığıyla Python kodlarınızı compile edebiliyorsunuz. Google hesabınız açık olacak şekilde https://colab.research.google.com/notebooks/intro.ipynb bu adrese girin:
  • Dosya -> Yeni Not Defteri'ne tıklayın. Python kodlarını çalıştıracağımız yeni bir sayfa açılacak.
  • Açılan sayfada bağlantı sağlandıktan sonra bize yer açılmış oldu. Artık kodlarımızı bu tahsil edilen geçici alana yükleyebiliriz. Sol tarafta yer alan Dosyalar sekmesini açın ve dosya yükleme butonuna tıklayın. Dosya seçim ekranı açıldıktan sonra gerekli python kod dosyalarını tek tek seçin ve yükleyin.
  • Daha sonrasında kod satırı yer alan kısımdan aşağıdaki komutları sırasıyla çalıştırın:
komut1- !pip install buildozer

komut2- !pip install cython==0.29.19

komut3- !sudo apt-get install -y \
    python3-pip \
    build-essential \
    git \
    python3 \
    python3-dev \
    ffmpeg \
    libsdl2-dev \
    libsdl2-image-dev \
    libsdl2-mixer-dev \
    libsdl2-ttf-dev \
    libportmidi-dev \
    libswscale-dev \
    libavformat-dev \
    libavcodec-dev \
    zlib1g-dev

komut4- !sudo apt-get install -y \
    libgstreamer1.0 \
    gstreamer1.0-plugins-base \
    gstreamer1.0-plugins-good

komut5- !sudo apt-get install build-essential libsqlite3-dev sqlite3 bzip2 libbz2-dev zlib1g-dev libssl-dev openssl libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libncursesw5-dev libffi-dev uuid-dev libffi6

komut6- !sudo apt-get install libffi-dev

komut7- !buildozer init

komut8- !buildozer -v android debug

komut9- !buildozer android clean
Ünlemle başlayan her komutu sırasıyla Kod satırına ekleyin ve üçgen butonuna tıklayın. Her işlem bitiminde yeni komut çalıştırmak için +Kod butonuna tıklayın ve sonraki komutu yapıştırıp, üçgen butona tıklayarak çalıştırın. Yeni komutu çalıştırmadan önce önceki komutun çalışmasının bittiğinden emin olun. Tüm komutların çalışması bittiğinde .apk dosyası oluşturulmuş olacaktır. Ancak bu işlem çok uzun sürebilir yani en azından 30 dakikanızı alabilir. Ayrıca Google Colab kullanımının belli bir sınırlaması var öğrendiğim kadarıyla ancak benim işimi gördü.
Devamını Oku »

REST API Nedir?

REST API, web uygulaması üzerinden sunucu ile iletişim kurmamıza olanak sağlar.

Açılımı, REpresentational State Transfer.

REST bir mimaridir ve bu mimariyi kullanan uygulama ve servislere RESTFUL API denir.

REST API ile yaptığımız işlemleri CRUD üzerinden tanımlayabiliriz. (Create, Read, Update ve Delete). Bu işlemler REST API'da HTTP metotları kullanılarak gerçekleştirilmektedir. Bu metotlar:

  • POST (create)
  • GET (read)
  • PUT (update)
  • DELETE (delete)
HTTP protokolüne Request olarak yukarıdaki işlemlerden biri seçilir. Aynı zamanda değişiklik yapılacak nokta belirtilir ve yapılan işleme göre gerekli parametre eklenir. Bunun sonucunda eğer Request sunucu tarafından doğrulanırsa buna uygun sonuç response olarak döndürülür. Örneğin bir veriyi güncellemek istersek PUT işlemi kullanılarak güncellenmek istenen nokta id ile belirtilir ve verilen parametre ile güncellenmesi için request gönderilir. Eğer sunucu bu request'i sorunsuz hallederse response olarak 200 (OK) durum kodunu geri döndürür. Yani güncelleme başarıyla gerçekleşti. Request durumuna göre çeşitli HTTP durum kodları mevcuttur.

Devamını Oku »