Skip to content

4. [SimuPaie] uygulaması – sürüm 1 – ASP.NET

4.1. Introduction

Bir kullanıcının, bir belediyenin "Maison de la petite enfance" derneğine bağlı çocuk bakıcılarının maaş hesaplamalarını simüle etmesine olanak tanıyan bir .NET uygulaması yazmak istiyoruz.

'daki ASP.NET numaralı maaş hesaplama formu şu şekilde görünecektir:

Image

ASP.NET uygulaması aşağıdaki mimariye sahip olacaktır:

  • Uygulamaya yapılan ilk istekte, [System.Web.HttpApplication] türünden türetilen [Global] türünde bir nesne oluşturulur. Web uygulamasının [web.config] yapılandırma dosyasını işleyen ve veritabanındaki belirli verileri önbelleğe alan nesne budur (yukarıdaki işlem 0).
  • Uygulamanın tek sayfası olan [Default.aspx] sayfasına yapılan ilk istek (yukarıdaki işlem 1) sırasında, [Load] olayı işlenir. Burada, çalışanlar açılır menüsünün doldurulması işlemi gerçekleştirilir. Kombinasyon listesi için gerekli veriler, bu verileri önbelleğe almış olan [Global] nesnesinden istenir. Bu, yukarıdaki işlem 2’dir. İşlem 4, bu şekilde başlatılan sayfayı kullanıcıya gönderir.
  • [Default.aspx] sayfasında maaş hesaplama talebi (işlem 1) yapıldığında, [Load] olayı yeniden işlenir. Bu bir POST türü istek olduğu için herhangi bir işlem yapılmaz; zira [Pam_Load] işleyicisi, bu durumda hiçbir işlem yapmayacak şekilde yazılmıştır (IsPostBack boole değeri kullanılır). [Load] olayı işlendiğinde, ardından [Salaire] düğmesindeki [Click] olayı işlenir. Bu olay, [Global]'te önbelleğe alınmamış verilere ihtiyaç duyar. Bu nedenle olay işleyicisi bu verileri veritabanından ister. Bu, yukarıdaki 3. işlemdir. Ardından maaş hesaplaması yapılır ve 4. işlem sonuçları kullanıcıya gönderir.

4.2. Visual Web Developer 2008 projesi

  • dosyasında, [1] dosyasında, [Web / Application Web ASP.NET] türünde yeni bir proje
  • [2]'te, [Web / Application Web ASP.NET] türünde
  • [3]'te projeye bir ad verilir
  • [4]'te, projenin adını ve [5]'te konumunu belirtin. Proje için [c:\temp\pam-aspnet\pam-v1-adonet] adlı bir klasör oluşturulacaktır.
  • [5]'te, Visual Web Developer projesi
  • [6]'te, projenin özellikleri (projeye sağ tıklama / Özellikler / Uygulama).
  • [7]'e, projenin derlenmesi sonucu oluşturulacak derleme adı
  • [8]'te, proje sınıfları için kullanmak istediğimiz varsayılan ad alanı. [Default.aspx.cs] ve [Default.aspx.designer.cs] dosyalarında tanımlanan [_Default] sınıfı ise proje adından türetilen [pam_v1_adonet] ad alanında oluşturulmuştur. Bu ad alanını, bu iki dosyanın kodunda doğrudan değiştirebiliriz:

[Default.aspx.cs]


using System;
....

namespace pam_v1
{
  public partial class _Default : System.Web.UI.Page
  {

[Default.aspx.designer.cs]


//------------------------------------------------------------------------------
// <otomatik olarak oluşturuldu>
//      Bu kod bir araç tarafından oluşturulmuştur.
//      Çalışma zamanı sürümü: 2.0.50727.3603
//
//      Bu dosyada yapılan değişiklikler hatalı çalışmaya neden olabilir ve
//      kod yeniden oluşturulursa kaybolacaktır.
// </auto-generated>
//------------------------------------------------------------------------------

namespace pam_v1 {
    
    
    public partial class _Default {
        
.........

[Default.aspx] dosyasının etiketleri de değiştirilmelidir:

  

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="pam_v1._Default" %>
...

Yukarıdaki Inherits özniteliği, [Default.aspx.cs] ve [Default.aspx.designer.cs] dosyalarında tanımlanan sınıfı belirtir. Burada pam_v1 ad alanı kullanılır.

4.2.1. [Default.aspx] formu

[Default.aspx] formunun görsel görünümü şöyledir:

Bileşenler şunlardır:

No
Tür
Ad
İşlev
1
DropDownList
ComboBoxEmployes
Çalışanların isim listesini içerir
2
TextBox
TextBoxHeures
Çalışılan saat sayısı – gerçek sayı
3
TextBox
TextBoxJours
Çalışılan gün sayısı – tam sayı
4
Düğme
ButtonSalaire
Maaş hesaplamasını talep eder
5
TextBox
TextBoxErreur
Kullanıcıya yönelik bilgilendirme mesajı
ReadOnly=true, TextMode=MultiLine
6
Etiket
LabelNom
(1) numaralı seçilen çalışanın adı
7
Etiket
LabelPrénom
(1) numaralı seçilen çalışanın adı
8
Etiket
LabelAdresse
Adres
9
Etiket
LabelVille
Şehir
10
Etiket
LabelCP
Posta kodu
11
Etiket
LabelIndice
Endeks
12
Etiket
LabelCSGRDS
Prim oranı CSGRDS
13
Etiket
LabelCSGD
Prim oranı CSGD
14
Etiket
LabelRetraite
Emeklilik katkı payı oranı
15
Etiket
LabelSS
Sosyal Güvenlik prim oranı
16
Etiket
LabelSH
(11) numaralı satırda belirtilen endeks için temel saatlik ücret
17
Etiket
LabelEJ
(11) numaralı endeks için günlük geçim ödeneği
18
Etiket
LabelRJ
(11) numaralı satırda belirtilen endeks için günlük yemek ödeneği
19
Etiket
LabelCongés
Temel maaşa uygulanacak ücretli izin ödenek oranı
20
Etiket
LabelSB
Temel maaş tutarı
21
Etiket
LabelCS
Ödenecek sosyal güvenlik primleri tutarı
22
Etiket
LabelIE
Bakılan çocuğun bakım ödeneği tutarı
23
Etiket
LabelIR
Bakılan çocuğun yemek yardımı tutarı
24
Etiket
LabelSN
Çalışana ödenecek net maaş

Form ayrıca iki adet [Panel] tipi alan içerir:

PanelErreurs
(5) numaralı bileşeni içerir: TextBoxErreur
PanelSalaire
(6) ila (24) numaralı bileşenleri içerir

[Panel] türündeki bir bileşen, [Panel].Visible adlı boole özelliği sayesinde programlama yoluyla görünür veya görünmez hale getirilebilir.

4.2.2. Girişlerin doğrulanması

Maaşı hesaplamak için kullanıcı:

  • [1]'te bir çalışanı seçer
  • [2]'te çalışılan saat sayısını girer. Bu sayı, 2 saat 30 dakika için 2,5 gibi ondalık olabilir.
  • [3]'te çalışılan gün sayısını girer. Bu sayı tam sayıdır.
  • [4] düğmesiyle maaşı sorgulayın

Kullanıcı, [2] ve [3] alanlarına hatalı veriler girdiğinde, kullanıcı başka bir giriş alanına geçtiği anda bu veriler doğrulanır. Bu nedenle, aşağıdaki ekran görüntüsü, kullanıcı [Salaire] düğmesine tıklamadan önce alınmıştır:

Yukarıdaki davranışın gerçekleşmesi için iki koşul gereklidir:

  • doğrulama bileşenlerinin EnableClientScript özelliğinin "true" olarak ayarlanmış olması gerekir:
  
  • sayfayı görüntüleyen tarayıcı, bir sayfaya gömülü JavaScript kodunu çalıştırabilmelidir HTML.

İstemci tarayıcısı verilerin geçerliliğini kendisi kontrol etmezse, bu veriler ancak tarayıcı formdaki girdileri sunucuya gönderdiğinde kontrol edilecektir. Bu durumda, sunucuda bulunan ve tarayıcının isteğini işleyen kod, verilerin geçerliliğini kontrol edecektir. Unutulmamalıdır ki, istemci tarayıcısında görüntülenen sayfada aynı doğrulamayı yapan bir JavaScript kodu bulunsa bile bu doğrulama her zaman yapılmalıdır. Zira sunucu, kendisine gönderilen POST isteğinin gerçekten bu sayfadan geldiğinden ve dolayısıyla verilerin doğrulanmış olduğundan emin olamaz.

Doğrulayıcıların listesi şöyledir:

No.
Tür
Ad
Rol
25
RequiredFieldValidator
RequiredFieldValidatorHeures
[2] ve [TextBoxHeures] alanlarının boş olmadığını kontrol eder
26
RangeValidator
RangeValidatorHeures
[2] ve [TextBoxHeures] alanlarının [0, 200] aralığında bir gerçek sayı olup olmadığını kontrol eder
27
RequiredFieldValidator
RequiredFieldValidatorJours
[3] [TextBoxJours] alanının boş olmadığını kontrol eder
28
RangeValidator
RangeValidatorJours
[3] ve [TextBoxJours] alanlarının [0,31] aralığında bir tamsayı olup olmadığını kontrol eder

Yapılması gereken iş: [Default.aspx] sayfasını oluşturmak. Öncelikle, içlerinde bulunması gereken bileşenleri yerleştirebilmek için [PanelErreurs] ve [PanelSalaire] adlı iki konteyneri yerleştireceğiz.


4.2.3. Uygulamadaki öğeler

Okunduktan sonra, [cotisations], [employes] ve [indemnites] tablolarındaki satırlar, [Cotisations] türündeki nesnelere yerleştirilecektir; [Employe] ve [Indemnites] türündeki nesnelere aktarılacaktır; bu nesneler aşağıdaki gibi tanımlanmıştır:


namespace Pam.Entites
{
  public class Cotisations
  {
    // otomatik özellikler
    public double CsgRds { get; set; }
    public double Csgd { get; set; }
    public double Secu { get; set; }
    public double Retraite { get; set; }

    // yapıcılar
    public Cotisations()
    {
    }

    public Cotisations(double csgRds, double csgd, double secu, double retraite)
    {
      CsgRds = csgRds;
      Csgd = csgd;
      Secu = secu;
      Retraite = retraite;
    }

    // ToString
    public override string ToString()
    {
      return string.Format("[{0},{1},{2},{3}]", CsgRds, Csgd, Secu, Retraite);
    }
  }
}

namespace Pam.Entites
{
  public class Employe
  {
    // otomatik özellikler
    public string SS { get; set; }
    public string Nom { get; set; }
    public string Prenom { get; set; }
    public string Adresse { get; set; }
    private string Ville { get; set; }
    private string CodePostal { get; set; }
    private int Indice { get; set; }

    // üreticiler
    public Employe()
    {

    }

    public Employe(string ss, string nom, string prenom, string adresse, string codePostal, string ville, int indice)
    {
      SS = ss;
      Nom = nom;
      Prenom = prenom;
      Adresse = adresse;
      CodePostal = codePostal;
      Ville = ville;
      Indice = indice;
    }

    // ToString
    public override string ToString()
    {
      return string.Format("[{0},{1},{2},{3},{4},{5},{6}]", SS, Nom, Prenom, Adresse, Ville, CodePostal, Indice);
    }
  }
}

namespace Pam.Entites
{
  public class Indemnites
  {

    // otomatik özellikler
    public int Indice { get; set; }
    public double BaseHeure { get; set; }
    public double EntretienJour { get; set; }
    public double RepasJour { get; set; }
    public double IndemnitesCP { get; set; }

    // üreticiler
    public Indemnites()
    {

    }

    public Indemnites(int indice, double baseHeure, double entretienJour, double repasJour, double indemnitesCP)
    {
      Indice = indice;
      BaseHeure = baseHeure;
      EntretienJour = entretienJour;
      RepasJour = repasJour;
      IndemnitesCP = indemnitesCP;
    }

    // kimlik
    public override string ToString()
    {
      return string.Format("[{0}, {1}, {2}, {3}, {4}]", Indice, BaseHeure, EntretienJour, RepasJour, IndemnitesCP);
    }

  }
}

4.2.4. Uygulamanın yapılandırılması

Uygulamayı yapılandıran [Web.config] dosyası şu şekilde olacaktır:


<?xml version="1.0" encoding="utf-8"?>

<configuration>
    <configSections>
...
    </configSections>

  <connectionStrings>
    <add name="dbpamSqlServer2005" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\data\...\dbpam.mdf;User Id=sa;Password=msde;Connect Timeout=30;" providerName="System.Data.SqlClient"/>
  </connectionStrings>

  <appSettings>
    <add key="selectEmploye" value="select NOM,PRENOM,ADRESSE,VILLE,CODEPOSTAL,INDICE from EMPLOYES where SS=@SS"/>
    <add key="selectEmployes" value="select PRENOM, NOM, SS from EMPLOYES"/>
    <add key="selectCotisations" value="select CSGRDS,CSGD,SECU,RETRAITE from COTISATIONS"/>
    <add key="SelectIndemnites" value="select INDICE,BASEHEURE,ENTRETIENJOUR,REPASJOUR,INDEMNITESCP from INDEMNITES"/>
  </appSettings>

  <system.web>
        <!-- 
            Définissez compilation debug="true" pour insérer des symboles 
            de débogage dans la page compilée. Comme ceci 
            affecte les performances, définissez cette valeur à true uniquement 
            lors du développement.
        -->
        <compilation debug="false">
...
</configuration>
  • 9. satır: önceki SQL Sunucusuna bağlantı dizesini tanımlar
  • 13-16. satırlar: kodda sabit olarak yazılmalarını önlemek amacıyla uygulama tarafından kullanılan SQL sorgularını tanımlar.
  • 13. satır: SQL sorgusu yapılandırılmıştır. Parametre notasyonu SQL Sunucusuna özgüdür.

Yapılması gereken iş: Bu parametreleri [Web.config] dosyasına eklemek. 9. satır, [dbpam.mdf] veritabanının gerçek yoluna göre uyarlanacaktır.


4.2.5. Uygulamanın başlatılması

ASP.NET uygulamasının başlatılması, [Global.asax.cs] dosyası aracılığıyla gerçekleştirilir. Bu dosya şu şekilde oluşturulur:

  • [1] dosyasında, projeye yeni bir öğe eklenir
  • [2] dosyasında, varsayılan olarak [Global.asax] olarak adlandırılan genel uygulama sınıfı eklenir [3]
  • [4]'te, [Global.asax] dosyası ve ilişkili sınıf [Global.asax.cs]
  • [5]'te, [Global.asax]'in etiket yapısı görüntülenir

<%@ Application Codebehind="Global.asax.cs" Inherits="pam_v1.Global" Language="C#" %>

[pam_v1.Global] sınıfı, [Global.asax.cs] dosyasında tanımlanmıştır. Bizim sorunumuz için bu sınıf şu şekilde tanımlanacaktır:


using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using Pam.Entites;

namespace pam_v1
{
  public class Global : System.Web.HttpApplication
  {
    // --- uygulamanın statik verileri ---
    public static Employe[] Employes;
    public static Cotisations Cotisations;
    public static Dictionary<int, Indemnites> Indemnites = new Dictionary<int, Indemnites>();
    public static string Msg = string.Empty;
    public static bool Erreur = false;
    public static string ConnectionString = null;

    // uygulamanın başlatılması
    public void Application_Start(object sender, EventArgs e)
    {
...
      try
      {
        // oturum açma
        ConnectionString = ...
        using (SqlConnection connexion = new SqlConnection(ConnectionString))
        {
          connexion.Open();
          // çalışan listesi alınır ve statik tabloya aktarılır [Employes]
...
          // katkı payı oranları alınır ve statik değişken [Cotisations]'e aktarılır
...
          // tazminatları statik sözlük [Indemnites]'ten alınır
...
          // işlem başarıyla tamamlandı
          Msg = "Base chargée...";
        }
      }
      catch (Exception ex)
      {
        // hatayı not ediyoruz
        Msg = string.Format("L'erreur suivante s'est produite lors de l'accès à la base de données : {0}", ex);
        Erreur = true;
      }
    }
  }
}
  • 20. satır: [Application_Start] yöntemi, web uygulamasının başlatılması sırasında yürütülür. Bu yöntem yalnızca bir kez yürütülür.
  • 12-17. satırlar: Sınıfın genel ve statik alanları. Statik bir alan, sınıfın tüm örnekleri tarafından paylaşılır. Dolayısıyla, [Global] sınıfının birden fazla örneği oluşturulursa, hepsi [Employes] adlı aynı statik alanı paylaşır; bu alana [Global.Employes] ve c.a.d referansları aracılığıyla erişilebilir. [NomDeClasse].ChampStatique. [Global] bir sınıfın adıdır. Dolayısıyla bu bir veri türüdür. Bu ad keyfi olarak belirlenir. Sınıf her zaman [System.Web.HttpApplication]'ten türetilir.

[Global] sınıfımıza geri dönelim. Bu sınıfın alanlarını statik olarak tanımlamanın gerekli olup olmadığı sorusu akla gelebilir. Aslında, bazı durumlarda [Global] sınıfının birden fazla örneğine sahip olunabileceği görülmektedir; bu da, tüm bu örnekler tarafından paylaşılması gereken alanların statik hale getirilmesini haklı kılar.

Bir web uygulamasının farklı sayfaları arasında "uygulama" kapsamındaki verileri paylaşmanın başka bir yolu daha vardır. Böylece, çalışanlara ait Employes dizisi, Application_Start yordamında şu şekilde depolanabilir:


            Application.Add("employes",Employes);

[Application], varsayılan olarak tüm ASP.NET uygulamalarında, [Global.asax.cs] ile tanımlanan sınıfın bir örneğine yapılan bir referanstır. Application, her türden nesneyi depolayabilen bir kapsayıcıdır. Employes dizisi, web uygulamasının herhangi bir sayfasındaki kodda şu şekilde çağrılabilir:


            Employe[] employes=Application.Get["employes"] as Employe[];

Application konteyneri her türden nesneyi depoladığından, Object türünde bir nesne elde edilir ve bu nesnenin türü daha sonra dönüştürülmelidir. Bu yöntem her zaman kullanılabilir, ancak [Global] nesnesinin tiplendirilmiş statik alanları aracılığıyla veri paylaşmak, tip dönüştürme işlemlerini ortadan kaldırır ve derleyicinin geliştiriciye yardımcı olacak tip denetimleri yapmasını sağlar. Burada bu yöntem kullanılacaktır.

Tüm kullanıcılar tarafından paylaşılan veriler şunlardır:

  • 12. satır: Tüm çalışanların basitleştirilmiş listesini (SS, NOM, PRENOM) depolayacak olan [Employe] türündeki nesnelerden oluşan dizi
  • 13. satır: prim oranlarını depolayacak [Cotisations] türündeki nesne
  • 14. satır: Çalışanların çeşitli endekslerine bağlı tazminatları depolayacak sözlük. Bu sözlük, çalışanın endeksine göre indekslenecek ve değerleri [Indemnites] türünde olacaktır
  • satır 15: başlatma işleminin nasıl sonuçlandığını (başarılı mı yoksa hata mı) belirten bir mesaj
  • satır 16: Başlatma işleminin hata ile mi yoksa hatasız mı sonuçlandığını belirten bir boole değeri.
  • satır 17: veritabanına bağlantı dizesi.

Soru: [Application_Start] sınıfının kodunu tamamlayınız.


4.3. [Default.aspx] formundaki olaylar

4.3.1. [Page_Load] yordamı

[Default.aspx] formu yüklendiğinde, [Global.Employes] tablosundan (satır 12) çalışanların adlarını alır ve bunları [1] açılır listesine ekler:

  • [1] açılır listesi doldurulmuştur
  • TextBox ve [5], veritabanının doğru şekilde okunduğunu gösterir

Uygulamanın başlatılması sırasında başlatma hataları meydana gelirse, TextBox ve [5] kodları bunu gösterir:

Image


Soru: Uygulamanın başlatılması sırasında çalıştırıldığında yukarıdaki işleyişi sağlayan [Default.aspx] web sayfasındaki [Page_Load] prosedürünü yazınız.


4.3.2. Maaş hesaplaması

[4] düğmesine tıklandığında aşağıdaki yönetici çalıştırılır:


    protected void ButtonSalaire_Click(object sender, System.EventArgs e)

Bu yönetici, öncelikle [2] ve [3]'te yapılan girişlerin geçerliliğini kontrol eder. İkisinden biri hatalıysa, daha önce gösterildiği gibi hata bildirilir. [2] ve [3] girişleri doğrulanıp geçerli bulunduktan sonra, uygulama [1]'te seçilen kullanıcı hakkında ek verileri ve maaşını görüntülemelidir (bkz. 4.1. paragrafındaki ekran görüntüsü).


Soru: [ButtonSalaire_Click] prosedürünün kodunu yazınız.