Skip to content

11. [SimuPaie] uygulaması – sürüm 7 – ASP.NET / çoklu görünüm / çoklu sayfa


Önerilen okumalar: referans [1], WEB ile geliştirme, ASP.NET 1.1 paragraf: Örnekler


Şimdi, daha önce incelediğimiz üç katmanlı ASP.NET uygulamasına işlevsel olarak özdeş olan [pam-v4-3tier-nhibernate-multivues-monopage] sürümünü inceliyoruz, ancak bu sürümün mimarisini şu şekilde değiştiriyoruz: önceki sürümde görünümler tek bir ASPX sayfası ile uygulanırken, burada üç ASPX sayfası ile uygulanacaktır.

Önceki uygulamanın mimarisi şu şekildeydi:

Burada bir MVC mimarisi (Model – Görünüm – Denetleyici) söz konusudur:

  • [Default.aspx.cs], denetleyici kodunu içerir. [Default.aspx] sayfası, istemciyle iletişim kuran tek unsurdur. İstemciden gelen tüm istekleri bu sayfa üzerinden alır.
  • [Saisies, Simulation, Simulations, ...], görünümleri temsil eder. Bu görünümler, [Default.aspx] sayfasındaki [View] bileşenleri tarafından burada uygulanmaktadır.

Yeni sürümün mimarisi ise şu şekilde olacaktır:

  • Yalnızca [web] katmanı değişmektedir
  • Görünümler (kullanıcıya sunulan içerik) değişmez.
  • Önceki sürümde tamamen [Default.aspx.cs] içinde bulunan denetleyici kodu artık birkaç sayfaya dağıtılmıştır:
    • [MasterPage.master]: Farklı görünümlerde ortak olan öğeleri bir araya getiren bir sayfa: menü seçeneklerini içeren üst başlık
    • [Formulaire.aspx]: Simülasyon formunu sunan ve bu formda gerçekleşen eylemleri yöneten sayfa
    • [Simulations.aspx]: Simülasyon listesini gösteren ve bu sayfada gerçekleşen işlemleri yöneten sayfa
    • [Erreurs.aspx]: Uygulamanın başlatılmasında bir hata oluştuğunda görüntülenen sayfa. Bu sayfada gerçekleştirilebilecek herhangi bir işlem yoktur.

Burada çoklu denetleyicili bir MVC mimarisi olduğu söylenebilir; oysa önceki sürümün mimarisi tek denetleyicili bir MVC mimarisiydi.

Bir istemciden gelen isteğin işlenmesi aşağıdaki adımlara göre gerçekleşir:

  1. Müşteri, uygulamaya bir istek gönderir. Bu istek, iki [Formulaire.aspx, Simulations.aspx] sayfasından birine yönlendirilir.
  2. İstenen sayfa bu talebi işler. Bunu yapmak için, [métier] katmanının yardımına ihtiyaç duyabilir; veritabanıyla veri alışverişi yapılması gerekiyorsa, bu katman da [dao] katmanına ihtiyaç duyabilir. Uygulama, [métier] katmanından bir yanıt alır.
  3. Bu yanıt uyarınca, uygulamaya (3) müşteriye gönderilecek görünümü (= yanıt) seçer ve müşteriye ihtiyaç duyduğu bilgileri (şablonu) sağlar (4).
  4. Yanıt, müşteriye gönderilir (5)

11.1. Uygulamanın görünümleri

Kullanıcıya sunulan farklı görünümler şunlardır:

  • - Simülasyon formunu gösteren [VueSaisies] görünümü

Image

  • - Simülasyonun ayrıntılı sonucunu görüntülemek için kullanılan [VueSimulation] görünümü:

Image

  • - müşteri tarafından yapılan simülasyonların listesini veren [VueSimulations] görünümü

Image

  • - Müşterinin simülasyonu olmadığını veya artık simülasyonu kalmadığını gösteren [VueSimulationsVides] görünümü:

Image

  • Uygulamanın başlatılmasında bir hata olduğunu gösteren [VueErreurs] görünümü:

Image

11.2. Çoklu denetleyici ortamında görünümlerin oluşturulması

Önceki sürümde, tüm görünümler tek bir [Default.aspx] sayfasından oluşturuluyordu. Bu sayfa iki bileşen ([MultiView]) içeriyordu ve görünümler, bu iki bileşene ([MultiView]) ait bir veya iki bileşenin ([View]) bir araya gelmesiyle oluşturuluyordu.

Görünüm sayısı az olduğunda verimli olan bu mimari, farklı görünümleri oluşturan bileşenlerin sayısı arttığında sınırlarına ulaşır: zira, tek bir [Default.aspx] sayfasına yapılan her istekte, bu sayfanın tüm bileşenleri örneklenir; oysa kullanıcıya yanıt oluşturmak için bunlardan sadece bazıları kullanılacaktır. Böylece her yeni istekle birlikte gereksiz bir iş yükü ortaya çıkar ve sayfanın toplam bileşen sayısı fazla olduğunda bu durum performans açısından dezavantaj yaratır.

Buna bir çözüm, görünümleri farklı sayfalara dağıtmaktır. Burada da bunu yapıyoruz. Görünüm oluşturmanın iki farklı durumunu inceleyelim:

  1. istek P1 sayfasına yapılır ve bu sayfa yanıtı oluşturur
  2. P1 sayfasına istek gönderilir ve bu sayfa, yanıtı oluşturması için P2 sayfasına başvurur

11.2.1. Durum 1: Tek denetleyici / tek görünüm sayfası

Durum 1'de, önceki sürümdeki tek denetleyici mimarisine geri dönülür; burada [Default.aspx] sayfası, P1 sayfasıdır:

  1. istemci, P1 sayfasına bir istek gönderir (1)
  2. P1 sayfası bu isteği işler. Bunu yapmak için, [métier] katmanının (2) yardımına ihtiyaç duyabilir; veritabanıyla veri alışverişi yapılması gerekiyorsa, bu katman da [dao] katmanına ihtiyaç duyabilir. Uygulama, [métier] katmanından bir yanıt alır.
  3. Bu yanıt uyarınca, uygulamaya (3) müşteriye gönderilecek görünümü (= yanıt) seçer ve ona (4) ihtiyaç duyduğu bilgileri (şablonu) sağlar. Burada, P1 sayfasında görüntülenecek [Panel] veya [View] bileşenlerini seçmek ve bunların içerdiği bileşenleri başlatmak söz konusudur.
  4. Yanıt, istemciye gönderilir (5)

İşte incelenen uygulamadan alınmış iki örnek:

[page Formulaire.aspx]

  • [1]'te: kullanıcı, [Formulaire.aspx] sayfasını talep ettikten sonra,
  • [2] örneğinde: [Formulaire.aspx] sayfası bu talebi işledi ve [1] sayfasında görüntülenmemiş olan [View] bileşenini görüntüleyerek yanıtı kendisi oluşturdu

[page Simulations.aspx]

  • [1]'te: Kullanıcı, [Simulations.aspx] sayfasını talep ettikten sonra, bir simülasyonu kaldırmak istiyor
  • [2]: [Simulations.aspx] sayfası bu talebi işledi ve yeni simülasyon listesini yeniden görüntüleyerek yanıtı kendisi oluşturdu.
2

11.2.2. Durum 2: 1. sayfa denetleyici, 2. sayfa denetleyici / görünüm

Durum 2, çeşitli mimarileri kapsayabilir. Biz şu mimariyi seçeceğiz:

  1. İstemci, P1 sayfasına bir istek gönderir (1)
  2. P1 sayfası bu isteği işler. Bunu yapmak için, [métier] katmanının (2) yardımına ihtiyaç duyabilir; veritabanıyla veri alışverişi yapılması gerekiyorsa, bu katman da [dao] katmanına ihtiyaç duyabilir. Uygulama, [métier] katmanından bir yanıt alır.
  3. Bu yanıt uyarınca, uygulamaya (3) müşteriye gönderilecek görünümü (= yanıt) seçer ve ona (4) ihtiyaç duyduğu bilgileri (şablonu) sağlar. Burada, oluşturulacak görünümün P1 sayfası yerine P2 sayfası tarafından oluşturulması gerekiyor. (3) ve (4) numaralı işlemleri gerçekleştirmek için P1 sayfasının iki seçeneği vardır:
    • [Server.Transfer(" P2.aspx ")] işlemi ile P2 sayfasına yürütme aktarımı yapmak. Bu durumda, P2 sayfası için tasarlanan şablonu [Context.Items[" clé "]=valeur] isteği bağlamına veya kullanıcının oturumuna [Session.[" clé "]=valeur] oturumuna yerleştirebilir. Böylece P2 sayfası oluşturulacak ve örneğin Load olayının işlenmesi sırasında, [valeur=(Type)Context.Items[" clé "]] veya [valeur=(Type)Session[" clé "]] işlemleriyle, duruma göre, burada Type, anahtara atanan değerin türüdür. Modeldeki değerlerin müşterinin gelecekteki bir talebi için saklanmasına gerek yoksa, Context bağlamı aracılığıyla değerlerin aktarılması en uygun yöntemdir.
    • [Response.Redirect(" P2.aspx ")] işlemiyle müşterinin P2 sayfasına yönlendirilmesini isteyin. Bu durumda, P1 sayfası, P2 sayfasına yönelik şablonu oturuma yerleştirecektir; çünkü Context istek bağlamı her isteğin sonunda silinir. Ancak burada, yönlendirme, müşterinin P1 adresine yaptığı ilk isteğin sona ermesine ve aynı müşteriden bu kez P2 adresine ikinci bir isteğin gönderilmesine neden olacaktır. Arka arkaya iki istek söz konusudur. Oturumun, istekler arasında "hafıza"yı korumak için kullanılan yöntemlerden biri olduğu bilinmektedir. Oturum dışında başka çözümler de vardır.
  4. P2'in devreye girme şekli ne olursa olsun, daha sonra yine 1. duruma geri dönülür: P2, işleyeceği bir istek almıştır (5) ve yanıtı kendisi oluşturacaktır (6, 7). Ayrıca, P2 sayfasının, isteği işledikten sonra kontrolü P3 sayfasına devredeceğini ve bunun böyle devam edeceğini de düşünebiliriz.

İşte incelenen uygulamadan alınmış bir örnek:

  • [1] sayfasına yönlendirilir: [Formulaire.aspx] sayfasını isteyen kullanıcı, simülasyon listesini görmek istediğinde
  • [2] sayfasında: [Formulaire.aspx] sayfası bu talebi işler ve istemciyi [Simulations.aspx] sayfasına yönlendirir. Kullanıcıya yanıtı veren bu son sayfadır. Müşterinin kendini yönlendirmesini istemek yerine, [Formulaire.aspx] sayfası müşterinin isteğini [Simulations.aspx] sayfasına aktarabilirdi. Bu durumda [2] sayfasında, [1] sayfasında görülenle aynı URL görüntülenirdi. Nitekim, bir tarayıcı her zaman en son istenen URL'yi gösterir:
    • [1] sayfasında talep edilen eylem, [Formulaire.aspx] sayfasına yöneliktir. Tarayıcı, bu sayfaya POST adresini gönderir.
    • Eğer [Formulaire.aspx] sayfası isteği işledikten sonra [Server.Transfer(" Simulations.aspx ")] ile [Simulations.aspx] sayfasına yönlendirirse, aynı istek kapsamında kalınır. Tarayıcı daha sonra, POST'in gerçekleştiği [Formulaire.aspx]'ten gelen URL'i, [2] olarak görüntüler.
    • Eğer [Formulaire.aspx] sayfası isteği işledikten sonra [Response.Redirect(" Simulations.aspx ")] aracılığıyla [Simulations.aspx] sayfasına yönlendirirse, tarayıcı ikinci bir istek, yani GET'i [Simulations.aspx]'e gönderir. Tarayıcı daha sonra [2] sayfasında, [Simulations.aspx]'ten URL'e yönlendirilen ve GET'in gerçekleştiği sayfayı görüntüler. Yukarıdaki [2] ekran görüntüsü de bunu göstermektedir.

11.3. [web] katmanının Visual Web Developer projesi

[web] katmanının Visual Web Developer projesi şu şekildedir:

  • [1]'te şunlar bulunur:
    • uygulamanın [Web.config] yapılandırma dosyası – [pam-v4-3tier-nhibernate-multivues-monopage] uygulamasınınkiyle aynıdır.
    • [Default.aspx] sayfası – kullanıcıyı [Formulaire.aspx] sayfasına yönlendirmekle yetinir
    • [Formulaire.aspx] sayfası, kullanıcıya simülasyon formunu sunar ve bu formla ilgili işlemleri gerçekleştirir
    • [Simulations.aspx] sayfası – kullanıcıya simülasyon listesini gösterir ve bu sayfayla ilgili işlemleri gerçekleştirir
    • [Erreurs.aspx] sayfası, kullanıcıya web uygulamasının başlatılması sırasında karşılaşılan bir hatayı bildiren bir sayfa sunar.
  • [2] sayfasında ise proje referansları gösterilir.

Yeni projenin mimarisine geri dönelim:

[pam-v4-3tier-nhibernate-multivues-monopage] projesine kıyasla, yalnızca görünümler değişmiştir. Bu nedenle yeni proje, bu projenin bazı dosyalarını devralmaktadır:

  • [Web.config] yapılandırma dosyası
  • [pam-dao-nhibernate, pam-metier-dao-nhibernate, Spring.Core, NHibernate] tarafından referans verilen DLL dosyaları
  • [Global.asax] genel uygulama sınıfı
  • [images, ressources, pam] klasörleri

Geliştirilmekte olan projeyle tutarlılık sağlamak için, görünümlerin ve genel uygulama sınıfının ad alanının [pam-v7] olmasını sağlayacağız:

  

11.4. Sayfaların sunum kodu

11.4.1. [MasterPage.master] ana sayfası

11.1. paragrafta sunulan uygulama görünümleri, Visual Studio'da Master Page olarak adlandırılan bir ana sayfada faktörlere ayrılabilecek ortak kısımlara sahiptir. Örneğin, aşağıda yer alan ve sırasıyla [Formulaire.aspx] ile [Simulations.aspx] sayfaları tarafından oluşturulan [VueSaisies] ve [VueSimulationsVides] görünümlerini ele alalım:

Bu iki görünümün ortak noktası, üst çubuktur (Başlık ve Menü seçenekleri). Kullanıcıya sunulacak tüm görünümler için durum böyledir: hepsi aynı üst çubuğa sahip olacaktır. Farklı sayfaların aynı sunum parçasını paylaşması için aşağıdakiler de dahil olmak üzere çeşitli çözümler mevcuttur:

  • bu ortak parçayı bir kullanıcı bileşenine yerleştirmek. Bu, ASP.NET 1.1 sürümünde kullanılan başlıca teknikti
  • Bu ortak parçayı bir Ana sayfaya yerleştirmek. Bu teknik, ASP.NET 2.0 sürümüyle ortaya çıkmıştır. Burada kullandığımız teknik budur.

Bir web uygulamasında Ana Sayfa oluşturmak için şu adımları uygulayabilirsiniz:

  • projeye sağ tıklayın / Yeni öğe ekle / Ana sayfa:

Bir ana sayfa eklendiğinde, web uygulamasına varsayılan olarak üç dosya eklenir:

  • [MasterPage.master]: Ana sayfanın sunum kodu
  • [MasterPage.master.cs]: Ana sayfanın kontrol kodu
  • [Masterpage.Master.designer.cs]: ana sayfanın bileşenlerinin bildirimi

Visual Studio tarafından [MasterPage.master] dosyasında oluşturulan kod şöyledir:


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MasterPage.master.cs" Inherits="pam_v7.MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <asp:ContentPlaceHolder id="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
        
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>
  • 1. satır: <%@ Master ... %> etiketi, sayfayı bir Ana Sayfa olarak tanımlamak için kullanılır. Sayfanın kontrol kodu, CodeBehind özniteliği ile tanımlanan dosyada bulunur ve sayfa, Inherits özniteliği ile tanımlanan sınıfı miras alır.
  • 12-18. satırlar: Ana sayfanın formu
  • 14-16. satırlar: Uygulamamızda [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarından birini içerecek boş bir kapsayıcı. Müşteri, yanıt olarak her zaman aynı sayfayı, yani Ana sayfayı alır; bu sayfada [ContentPlaceHolder1] konteyneri, [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarından biri tarafından sağlanan HTML akışını alacaktır. Dolayısıyla, istemcilere gönderilen sayfaların görünümünü değiştirmek için Ana sayfanın görünümünü değiştirmek yeterlidir.
  • 8-9. satırlar: "alt" sayfaların <head>...</head> başlığını özelleştirebileceği boş bir konteyner.

Bu kaynak kodun görsel gösterimi (Tasarım sekmesi) aşağıda (1) numaralı şekilde sunulmuştur. Ayrıca, [Standard] araç çubuğundaki [ContentPlaceHolder] bileşeni (2) sayesinde istenilen sayıda konteyner eklenebilir.

Visual Studio tarafından [MasterPage.master.cs]'te oluşturulan kontrol kodu şöyledir:


using System;

public partial class MasterPage : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}
  • 3. satır: [MasterPage.master] sayfasındaki <%@ Master ... %> yönergesinin [Inherits] özniteliği tarafından referans verilen sınıf, [System.Web.UI.MasterPage] sınıfından türetilmiştir

Yukarıda, ana sayfanın Load olayını yöneten Page_Load yönteminin varlığını görüyoruz. Ana sayfa, kendi içinde başka bir sayfa içerecektir. Her iki sayfanın Load olayları hangi sırayla gerçekleşir? Bu genel bir kuraldır: Bir bileşenin Load olayı, o bileşeni barındıran konteynerin olayından önce gerçekleşir. Dolayısıyla burada, ana sayfaya eklenmiş sayfanın Load olayı, ana sayfanın kendi olayından önce gerçekleşecektir.

'de, önceki [MasterPage.master] sayfasını ana sayfa olarak kullanan bir sayfa oluşturmak için şu şekilde ilerleyebilirsiniz:

  • [1]'te: ana sayfaya sağ tıklayın, ardından [Ajouter une page de contenu] seçeneğini seçin
  • [2]'e: Varsayılan bir sayfa, burada [WebForm1.aspx] oluşturulur.

[WebForm1.aspx] sunum kodu şöyledir:


<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.Master" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="pam_v7.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>
  • 1. satır: Page yönergesi ve öznitelikleri
    • MasterPageFile: yönergeyle tanımlanan sayfanın ana sayfa dosyasını belirtir. ~ işareti proje klasörünü belirtir.
    • Diğer parametreler, bir web sayfasında olağan olan parametrelerdir: ASP
  • 2-3. satırlar: <asp:Content> etiketleri, ContentPlaceHolderID özniteliği aracılığıyla ana sayfanın <asp:ContentPlaceHolder> yönergeleriyle tek tek ilişkilendirilir. Yukarıdaki 2-3. satırlar arasına yerleştirilen bileşenler, yürütme sırasında ana sayfanın ID ContentPlaceHolder1 kapsayıcısına yerleştirilecektir.

Bu şekilde oluşturulan [WebForm1.aspx] sayfasını yeniden adlandırarak, [MasterPage.master]'i ana sayfa olarak kullanan farklı sayfalar oluşturulabilir.

[SimuPaie] uygulamamız için ana sayfanın görsel görünümü şu şekilde olacaktır:

No.
Tür
Ad
Rol
A
Panel (yukarıdaki pembe)
başlık
sayfa başlığı
B
Panel (yukarıda sarı renkli)
içerik
sayfa içeriği
1
LinkButton
LinkButtonFaireSimulation
simülasyon hesaplamasını talep ediyor
2
LinkButton
LinkButtonEffacerSimulation
giriş formunu sil
3
LinkButton
LinkButtonVoirSimulations
daha önce yapılmış simülasyonların listesini gösterir
4
LinkButton
LinkButtonFormulaireSimulation
giriş formuna geri döner
5
LinkButton
LinkButtonEnregistrerSimulation
mevcut simülasyonu simülasyon listesine kaydeder
6
LinkButton
LinkButtonTerminerSession
geçerli oturumu sonlandırır

İlgili kaynak kodu şöyledir:


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MasterPage.master.cs" Inherits="pam_v7.MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title>Application PAM</title>
</head>
<body background="ressources/standard.jpg">
  <form id="form1" runat="server">
  <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
  <asp:UpdatePanel runat="server" ID="UpdatePanelPam" UpdateMode="Conditional">
    <ContentTemplate>
      <asp:Panel ID="entete" runat="server" BackColor="#FFE0C0">
        <table>
          <tr>
            <td>
              <h2>
                Simulateur de calcul de paie</h2>
            </td>
            <td>
              <label>
                &nbsp;&nbsp;&nbsp</label>
              <asp:UpdateProgress ID="UpdateProgress1" runat="server">
                <ProgressTemplate>
                  <img alt="" src="images/indicator.gif" />
                  <asp:Label ID="Label5" runat="server" BackColor="#FF8000"
                             EnableViewState="False" Text="Calcul en cours. Patientez ....">
                        </asp:Label>
                </ProgressTemplate>
              </asp:UpdateProgress>
            </td>
            <td>
              <asp:LinkButton ID="LinkButtonFaireSimulation" runat="server"
                         CausesValidation="False">| Faire la simulation<br />
                    </asp:LinkButton>
              <asp:LinkButton ID="LinkButtonEffacerSimulation" runat="server"
                         CausesValidation="False">| Effacer la simulation<br />
                    </asp:LinkButton>
              <asp:LinkButton ID="LinkButtonVoirSimulations" runat="server"
                     CausesValidation="False">| Voir les simulations<br />
                    </asp:LinkButton>
              <asp:LinkButton ID="LinkButtonFormulaireSimulation" runat="server"
                         CausesValidation="False">| Retour au formulaire de simulation<br />
                    </asp:LinkButton>
              <asp:LinkButton ID="LinkButtonEnregistrerSimulation" runat="server"
                         CausesValidation="False">| Enregistrer la simulation<br />
                    </asp:LinkButton>
              <asp:LinkButton ID="LinkButtonTerminerSession" runat="server"
                         CausesValidation="False">| Terminer la session<br />
                    </asp:LinkButton>
            </td>
          </tr>
        </table>
        <hr />
      </asp:Panel>
      <div>
        <asp:Panel ID="contenu" runat="server" BackColor="#FFFFC0">
          <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
          </asp:ContentPlaceHolder>
        </asp:Panel>
      </div>
    </ContentTemplate>
  </asp:UpdatePanel>
  </form>
</body>
</html>
  • 1. satır: Ana sayfanın sınıf adı not edilir: MasterPage
  • 8. satır: Sayfa için bir arka plan resmi tanımlanır.
  • 9-64. satırlar: form
  • 10. satır: Ajax efektleri için gerekli olan ScriptManager bileşeni
  • 11-63. satırlar: AJax konteyneri
  • 12-62. satırlar: Ajax ile işlenmiş içerik
  • satır 13-55: Panel bileşeni [entete]
  • 57-60. satırlar: [contenu] Panel bileşeni
  • 58-59. satırlar: ID bileşeni, [ContentPlaceHolder1] bileşeni, bu bileşen [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfasını içerecektir

Bu sayfayı oluşturmak için, [entete] paneline, [pam-v4-3tier-nhibernate-multivues-monopage] sürümündeki [Default.aspx] sayfasının [VueEntete] görünümüne ait ASPX kodunu ekleyebiliriz; bu, 8.5.2. paragrafında açıklanmıştır.

11.4.2. [Formulaire.aspx] sayfası

Bu sayfayı oluşturmak için 11.4.1. paragrafında açıklanan yöntemi izleyeceğiz ve bu şekilde oluşturulan [WebForm1.aspx] sayfasını [Formulaire.aspx] olarak yeniden adlandıracağız. Oluşturulmakta olan [Formulaire.aspx] sayfasının görsel görünümü şu şekilde olacaktır:

[Formulaire.aspx] sayfasının görsel yapısı iki öğeden oluşur:

  • [1] sayfasında, [ContentPlaceHolder1] (2) konteynerini içeren ana sayfa
  • [2] sayfasında ise [ContentPlaceHolder1] konteynerine yerleştirilmiş bileşenler. Bunlar, önceki uygulamadakilerle aynıdır.

Bu sayfanın kaynak kodu şöyledir:


<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
  CodeBehind="Formulaire.aspx.cs" Inherits="pam_v7.PageFormulaire" Title="Simulation de calcul de paie : formulaire" %>

<%@ MasterType VirtualPath="~/MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  <div>
    <table>
      <tr>
        <td>
          Employé
        </td>
        <td>
          Heures travaillées
        </td>
        <td>
          Jours travaillés
        </td>
        <td>
        </td>
      </tr>
...
</asp:Content>
  • 1. satır: Page yönergesi ve MasterPageFile özniteliği
  • 4. satır: Ana sayfanın kontrol sınıfı, genel alanlar ve özellikler sunabilir. Bunlara, Master.[champ] veya Master.[propriété] sözdizimi ile kapsüllenmiş sayfalar üzerinden erişilebilir. Sayfanın Master özelliği, ana sayfayı [System.Web.UI.MasterPage] türünde bir örnek olarak belirtir. Dolayısıyla örneğimizde aslında (MasterPage)(Master) yazılması gerekir.[champ] veya (MasterPage)(Master).[propriété]. 4. satırdaki MasterType yönergesini sayfaya ekleyerek bu tür dönüşümünü önleyebiliriz. Bu yönergenin VirtualPath özniteliği, ana sayfa dosyasını belirtir. Böylece derleyici, ana sayfa sınıfı (burada [MasterPage] türü) tarafından sunulan genel alanları, özellikleri ve yöntemleri tanıyabilir.
  • 5-22. satırlar: Ana sayfanın [ContentPlaceHolder1] konteynerine eklenecek içerik.

Bu sayfayı, 8.5.3 numaralı paragrafta açıklanan [VueSaisies] görünümünün içeriğini ve 8.5.4 numaralı paragrafta açıklanan [VueSimulation] görünümünün içeriğini (6-21. satırlar) içerik olarak kullanarak oluşturabiliriz.

11.4.3. [Simulations.aspx] sayfası

Bu sayfayı oluşturmak için 11.4.1. paragrafta açıklanan yöntemi izleyeceğiz ve bu şekilde oluşturulan [WebForm1.aspx] sayfasını [Simulations.aspx] olarak yeniden adlandıracağız. Oluşturulmakta olan [Simulations.aspx] sayfasının görsel görünümü şöyledir:

[Simulations.aspx] sayfasının görsel yapısı iki öğeden oluşur:

  • [1] numaralı ana sayfa ve bunun [ContentPlaceHolder1] numaralı kapsayıcısı
  • [2] sayfasında ise [ContentPlaceHolder1] konteynerine yerleştirilmiş bileşenler bulunmaktadır. Bu bileşenler, önceki uygulamadakilerle aynıdır.

Bu sayfanın kaynak kodu şöyledir:


<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
  CodeBehind="Simulations.aspx.cs" Inherits="pam_v7.PageSimulations" Title="Pam : liste des simulations" %>

<%@ MasterType VirtualPath="~/MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  <asp:MultiView ID="MultiView1" runat="server">
    <asp:View ID="View1" runat="server">
      <h2>
        Liste de vos simulations</h2>
      <p>
        <asp:GridView ID="GridViewSimulations" runat="server" ...>
...
        </asp:GridView>
      </p>
    </asp:View>
    <asp:View ID="View2" runat="server">
      <h2>
        La liste de vos simulations est vide</h2>
    </asp:View>
  </asp:MultiView><br />
</asp:Content>

Bu sayfayı, 5-21. satırlardaki içeriğe, 8.5.5. paragrafında açıklanan [VueSimulations] görünümünün içeriğini ve 8.5.6. paragrafında açıklanan [VueSimulationsVides] görünümünün içeriğini ekleyerek oluşturabiliriz.

11.4.4. [Erreurs.aspx] sayfası

Bu sayfayı oluşturmak için 11.4.1 paragrafında açıklanan yöntemi izleyeceğiz ve bu şekilde oluşturulan [WebForm1.aspx] sayfasını [Erreurs.aspx] olarak yeniden adlandıracağız. Oluşturulmakta olan [Erreurs.aspx] sayfasının görsel görünümü şöyledir:

[Erreurs.aspx] sayfasının görsel yapısı iki öğeden oluşur:

  • [1] numaralı ana sayfa ve onun [ContentPlaceHolder1] numaralı kapsayıcısı
  • [2] sayfasında, [ContentPlaceHolder1] konteynerine yerleştirilmiş bileşenler. Bunlar, önceki uygulamadakilerle aynıdır.

Bu sayfanın kaynak kodu şöyledir:


<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
  CodeBehind="Erreurs.aspx.cs" Inherits="pam_v7.PageErreurs" Title="Pam : erreurs" %>

<%@ MasterType VirtualPath="~/MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
        <h3>Les erreurs suivantes se sont produites au démarrage de l'application</h3>
        <ul>
            <asp:Repeater id="rptErreurs" runat="server">
                <ItemTemplate>
                    <li>
                        <%# Container.DataItem %>
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </ul>
</asp:Content>

11.5. Sayfa denetim kodu

11.5.1. Genel Bakış

Uygulamanın mimarisine geri dönelim:

  • [Global], uygulamayı başlatan (adım 0) [HttpApplication] türündeki nesnedir. Bu sınıf, önceki sürümdekiyle aynıdır.
  • Önceki sürümde tamamen [Default.aspx.cs] içinde bulunan denetleyici kodu, artık birkaç sayfaya dağıtılmıştır:
    • [MasterPage.master]: [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarının ana sayfasıdır. Menüyü içerir.
    • [Formulaire.aspx]: Simülasyon formunu gösteren ve bu formda gerçekleşen eylemleri yöneten sayfa
    • [Simulations.aspx]: Simülasyon listesini gösteren ve bu sayfada gerçekleşen işlemleri yöneten sayfadır
    • [Erreurs.aspx]: Uygulamanın başlatılması sırasında bir hata oluştuğunda görüntülenen sayfadır. Bu sayfada gerçekleştirilebilecek herhangi bir işlem yoktur.

Bir müşteri talebinin işlenmesi aşağıdaki adımlara göre gerçekleşir:

  1. Müşteri, uygulamaya bir talep gönderir. Normalde bu talebi [Formulaire.aspx, Simulations.aspx] sayfalarından birine gönderir, ancak [Erreurs.aspx] sayfasını talep etmesini engelleyen bir durum yoktur. Bu durum da dikkate alınmalıdır.
  2. İstenen sayfa bu talebi işler (adım 1). Bunu yapmak için, [métier] katmanının yardımına ihtiyaç duyabilir (adım 2); veritabanıyla veri alışverişi yapılması gerekiyorsa, bu katman da [dao] katmanına ihtiyaç duyabilir. Uygulama, [métier] katmanından bir yanıt alır.
  3. Bu yanıt uyarınca, uygulamaya müşteriye gönderilecek görünümü (= yanıt) seçer (adım 3) ve müşteriye ihtiyaç duyduğu bilgileri (şablonu) sağlar (adım 4). Bu yanıtı oluşturmak için üç olasılık gördük:
    • İstenen sayfa (D), yanıt olarak gönderilen sayfa (R) ile aynıdır. Bu durumda, yanıt şablonunu (R) oluşturmak, sayfa (D) bileşenlerinden bazılarına yanıtta sahip olmaları gereken değeri atamaktan ibarettir.
    • İstenen sayfa (D), yanıt olarak gönderilen sayfa (R) değildir. Bu durumda sayfa (D):
      • Server.Transfer(" R ") komutuyla yürütme akışını (R) sayfasına aktarabilir. Şablon, Context.Items("anahtar")=değer komutuyla bağlama yerleştirilebilir veya daha nadiren Session.Items("anahtar")=değer komutuyla oturuma yerleştirilebilir
      • Response.redirect(" R ") komutuyla müşteriyi (R) sayfasına yönlendirin. Şablon bu durumda oturuma yerleştirilebilir, ancak bağlama yerleştirilemez.
  4. yanıt müşteriye gönderilir (adım 5)

[MasterPage.master, Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarının her biri, aşağıdaki olaylardan birine veya birkaçına yanıt verecektir:

  • Init: sayfanın yaşam döngüsündeki ilk olay
  • Load: sayfa yüklendiğinde gerçekleşir
  • Click: ana sayfanın menüsündeki bağlantılardan birine tıklandığında

Sayfaları, ana sayfadan başlayarak sırayla işliyoruz.

11.5.2. [MasterPage.master] sayfasının kontrol kodu

11.5.2.1. Sınıf şablonu

Ana sayfanın kontrol kodu aşağıdaki iskelete sahiptir:


using System.Web.UI.WebControls;

namespace pam_v7
{
  public partial class MasterPage : System.Web.UI.MasterPage
  {

    // menü 
    public LinkButton OptionFaireSimulation
    {
      get { return LinkButtonFaireSimulation; }
    }
...

    // menüyü sabitleyin 
    public void SetMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
    {
....
    }

    // seçenek yönetimi [Terminer la session] 
    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
....
    }

    // ana sayfayı başlat 
    protected void Page_Init(object sender, System.EventArgs e)
    {
....
      }
    }
  }
}
  • 5. satır: Sınıfın adı [MasterPage]'tir ve [System.Web.UI.MasterPage] sistem sınıfından türetilmiştir.
  • 9-14. satırlar: Menüdeki 6 seçenek, sınıfın genel özellikleri olarak tanımlanmıştır
  • 16-19. satırlar: SetMenu adlı genel yöntem, [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarının ana sayfanın menüsünü ayarlamasını sağlayacaktır
  • 22-25. satırlar: [LinkButtonTerminerSession] bağlantısına yapılan tıklamayı yönetecek yordam
  • 28-31. satırlar: Ana sayfanın Init olayını yöneten yordam

11.5.2.2. Sınıfın genel özellikleri


using System.Web.UI.WebControls;

namespace pam_v7
{
  public partial class MasterPage : System.Web.UI.MasterPage
  {

    // menü 
    public LinkButton OptionFaireSimulation
    {
      get { return LinkButtonFaireSimulation; }
    }

    public LinkButton OptionEffacerSimulation
    {
      get { return LinkButtonEffacerSimulation; }
    }

    public LinkButton OptionEnregistrerSimulation
    {
      get { return LinkButtonEnregistrerSimulation; }
    }

    public LinkButton OptionVoirSimulations
    {
      get { return LinkButtonVoirSimulations; }
    }

    public LinkButton OptionTerminerSession
    {
      get { return LinkButtonTerminerSession; }
    }

    public LinkButton OptionFormulaireSimulation
    {
      get { return LinkButtonFormulaireSimulation; }
    }

...
  }
}

Bu kodu anlamak için, ana sayfayı oluşturan bileşenleri hatırlamak gerekir:

No
Tür
Ad
Rol
A
Panel (yukarıdaki pembe)
başlık
sayfa başlığı
B
Panel (yukarıda sarı renkli)
içerik
sayfa içeriği
1
LinkButton
LinkButtonFaireSimulation
simülasyonun hesaplanmasını talep eder
2
LinkButton
LinkButtonEffacerSimulation
giriş formunu sil
3
LinkButton
LinkButtonVoirSimulations
daha önce yapılmış simülasyonların listesini gösterir
4
LinkButton
LinkButtonFormulaireSimulation
giriş formuna geri döner
5
LinkButton
LinkButtonEnregistrerSimulation
mevcut simülasyonu simülasyon listesine kaydeder
6
LinkButton
LinkButtonTerminerSession
mevcut oturumu sonlandır

1'den 6'ya kadar olan bileşenlere, bunları içeren sayfanın dışında erişilemez. 9'dan 37'ye kadar olan satırlardaki özellikler, bu bileşenleri harici sınıflara, yani burada uygulamanın diğer sayfalarındaki sınıflara erişilebilir hale getirmeyi amaçlamaktadır.

11.5.2.3. SetMenu yöntemi

SetMenu adlı genel yöntem, [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarının ana sayfa menüsünü ayarlamasına olanak tanır. Kod yapısı basittir:


        // menüyü sabitlemek 
        public void SetMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
        {
            // menü seçeneklerini sabitliyoruz 
            LinkButtonFaireSimulation.Visible = boolFaireSimulation;
            LinkButtonEnregistrerSimulation.Visible = boolEnregistrerSimulation;
            LinkButtonEffacerSimulation.Visible = boolEffacerSimulation;
            LinkButtonVoirSimulations.Visible = boolVoirSimulations;
            LinkButtonFormulaireSimulation.Visible = boolFormulaireSimulation;
            LinkButtonTerminerSession.Visible = boolTerminerSession;
}

11.5.2.4. Ana sayfanın olay yönetimi

Ana sayfa iki olayı yönetecektir:

  • Init olayı, sayfanın yaşam döngüsünün ilk olayıdır
  • [LinkButtonTerminerSession] bağlantısı üzerindeki Click olayı

Ana sayfada beş bağlantı daha bulunmaktadır: [LinkButtonFaireSimulation, LinkButtonEnregistrerSimulation, LinkButtonEffacerSimulation, LinkButtonVoirSimulations, LinkButtonFormulaireSimulation]. Örnek olarak, [LinkButtonFaireSimulation] bağlantısına tıklandığında yapılması gerekenleri inceleyelim:

  1. [Formulaire.aspx] sayfasında girilen verileri (saatler, günler) kontrol etmek
  2. maaş hesaplamasını yapmak
  3. sonuçları [Formulaire.aspx] sayfasında görüntülemek

1 ve 3 numaralı işlemler, [Formulaire.aspx] sayfasının bileşenlerine erişim gerektirir. Ancak durum böyle değildir. Zira ana sayfa, [ContentPlaceHolder1] konteynerine eklenebilecek sayfaların bileşenleri hakkında hiçbir bilgiye sahip değildir. Örneğimizde, [Formulaire.aspx] sayfası, [LinkButtonFaireSimulation] bağlantısına yapılan tıklamayı yönetmelidir; çünkü bu olay gerçekleştiğinde görüntülenen sayfa budur. Peki bu olaydan nasıl haberdar olabilir?

  • [LinkButtonFaireSimulation] bağlantısı [Formulaire.aspx] sayfasının bir parçası olmadığı için, [Formulaire.aspx] sayfasına her zamanki prosedürü yazamayız:

    private void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
...
}

[Formulaire.aspx] dosyasında aşağıdaki kodu kullanarak bu sorunu aşabiliriz:


using System.Collections.Generic;
...

namespace pam_v7
{
    public partial class Formulaire : System.Web.UI.Page
    {
// sayfayı yükleme 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // olay yöneticisi
        Master.OptionFaireSimulation.Click += OptFaireSimulation_Click;
        Master.OptionEffacerSimulation.Click += OptEffacerSimulation_Click;
        Master.OptionVoirSimulations.Click += OptVoirSimulations_Click;
        Master.OptionEnregistrerSimulation.Click += OptEnregistrerSimulation_Click;
...
    }

    // maaş hesaplaması 
    private void OptFaireSimulation_Click(object sender, System.EventArgs e)
    {
....
    }

    // simülasyonu sil 
    private void OptEffacerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void OptVoirSimulations_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void OptEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }
 }
}
  • 12-15. satırlar: [Formulaire.aspx] sayfasındaki Load olayı gerçekleştiğinde, ana sayfanın [MasterPage] sınıfı örneklenmiştir. Optionxx adlı bu sınıfın genel özelliklerine erişilebilir ve bu özellikler, LinkButton türündedir; bu bileşen, Click olayını destekler. Bu Click olaylarına şu yöntemleri ilişkilendiriyoruz:
    • OptFaireSimulation_Click yöntemi, Click olayı için LinkButtonFaireSimulation bağlantısı üzerinde
    • OptEffacerSimulation_Click yöntemi, LinkButtonEffacerSimulation bağlantısındaki Click olayı için
    • OptVoirSimulations_Click, LinkButtonVoirSimulations bağlantısındaki Click etkinliği için
    • OptEnregistrerSimulation_Click, Click etkinliği için LinkButtonEnregistrerSimulation bağlantısında

Menüdeki altı bağlantıdaki Click etkinliklerinin yönetimi şu şekilde dağıtılacaktır:

  • [Formulaire.aspx] sayfası, [LinkButtonFaireSimulation, LinkButtonEnregistrerSimulation, LinkButtonEffacerSimulation, LinkButtonVoirSimulations] bağlantılarını yönetecek
  • [Simulations.aspx] sayfası, [LinkButtonFormulaireSimulation] bağlantısını yönetecektir
  • [MasterPage.master] ana sayfası, [LinkButtonTerminerSession] bağlantısını yönetecektir. Bu olay için, ana sayfanın kapsadığı sayfayı bilmesi gerekmez.

11.5.2.5. Ana sayfanın Init olayı

Uygulamadaki üç [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfası, [MasterPage.master] sayfasını ana sayfa olarak kullanır. Ana sayfaya M, kapsanan sayfaya E diyelim. E sayfası istemci tarafından talep edildiğinde, aşağıdaki olaylar sırayla gerçekleşir:

  • E.Init
  • M.Init
  • E.Load
  • M.Load
  • ...

M sayfasındaki Init olayını, hedef E sayfası ne olursa olsun, mümkün olduğunca erken çalıştırılması gereken kodu çalıştırmak için kullanacağız. Bu kodu bulmak için uygulamanın genel görünümüne tekrar bakalım:

Yukarıda, [Global], uygulamayı başlatan [HttpApplication] türündeki nesnedir. Bu sınıf, [pam-v4-3tier-nhibernate-multivues-monopage] sürümündekiyle aynıdır:


using System;
...

namespace pam_v7
{
  public class Global : System.Web.HttpApplication
  {
    // --- uygulamanın statik verileri ---
    public static Employe[] Employes;
    public static IPamMetier PamMetier = null;
    public static string Msg;
    public static bool Erreur = false;

    // uygulamanın başlatılması
    public void Application_Start(object sender, EventArgs e)
    {
...
    }

    public void Session_Start(object sender, EventArgs e)
    {
...
    }
  }
}

[Global] sınıfı uygulamayı düzgün bir şekilde başlatamazsa, iki statik genel değişkeni ayarlar:

  • 12. satırdaki boole tipi Hata değişkeni vrai olarak ayarlanır
  • 11. satırdaki Msg değişkeni, karşılaşılan hatayla ilgili ayrıntıları içeren bir mesaj barındırır

Uygulama düzgün bir şekilde başlatılmamışken kullanıcı [Formulaire.aspx, Simulations.aspx] sayfalarından birini talep ettiğinde, bu istek, [Erreurs.aspx] sayfasına aktarılmalı veya yönlendirilmelidir; bu sayfa, [Global] sınıfındaki hata mesajını görüntüler. Bu durumu çeşitli şekillerde yönetebiliriz:

  • her bir [Formulaire.aspx, Simulations.aspx] sayfasının Init veya Load olay işleyicisinde başlatma hatası testi yapmak
  • Bu iki sayfanın ana sayfasındaki Init veya Load olay yöneticisinde başlatma hatası testini gerçekleştirin. Bu yöntemin avantajı, başlatma hatası testini tek bir yere yerleştirmektir.

Başlık sayfasındaki Init olay yöneticisinde başlatma hatası testini yapmayı tercih ediyoruz:


        protected void Page_Init(object sender, System.EventArgs e)
        {
            // olay yöneticisi 
            LinkButtonTerminerSession.Click += LinkButtonTerminerSession_Click;
            // başlatma hataları mı var? 
            if (Global.Erreur)
            {
                // kapsüllenmiş sayfa hata sayfası mı? 
                bool isPageErreurs =...;
                // eğer görüntülenen sayfa hata sayfasıysa, olduğu gibi bırakılır; aksi takdirde istemci hata sayfasına yönlendirilir 
                if (!isPageErreurs)
                    Response.Redirect("Erreurs.aspx");
                return;
            }
}

Yukarıdaki kod, [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarından herhangi biri istendiğinde çalışacaktır. İstenen sayfa [Formulaire.aspx, Simulations.aspx] ise, (12. satırda) istemciyi [Erreurs.aspx] sayfasına yönlendirmekle yetiniyoruz; bu sayfa, [Global] sınıfına ait hata mesajını görüntüleme görevini üstlenir. İstenen sayfa [Erreurs.aspx] ise, bu yönlendirme yapılmamalıdır: [Erreurs.aspx] sayfasının görüntülenmesine izin verilmelidir. Bu nedenle, ana sayfanın [Page_Init] yönteminde, bu yöntemin hangi sayfayı kapsadığını bilmemiz gerekir.

Ana sayfanın bileşen ağacına geri dönelim:


...
<body background="ressources/standard.jpg">
    <form id="form1" runat="server">
        <asp:Panel ID="entete" runat="server" BackColor="#FFE0C0" Width="1239px" >
...
        </asp:Panel>
        <div>
            <asp:Panel ID="contenu" runat="server" BackColor="#FFFFC0">
                <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>
            </asp:Panel>
        </div>
    </form>
</body>
</html>
  • 1-13. satırlar: "form1" kimliğine sahip kapsayıcı
  • 4-6. satırlar: "form1" kimliğine sahip kapsayıcı içinde yer alan "entete" kimliğine sahip kapsayıcı
  • 8-11. satırlar: "form1" kimliğine sahip kapsayıcının içinde yer alan "contenu" kimliğine sahip kapsayıcı
  • 9-10. satırlar: "ContentPlaceHolder1" kimliğine sahip konteyner; "contenu" kimliğine sahip konteynerin içinde yer alır

Ana sayfa M içinde yer alan E sayfası, "ContentPlaceHolder1" kimliğine sahip konteyner içinde bulunur. Bu E sayfasındaki C kimliğine sahip bir bileşene başvurmak için şu şekilde yazılır:


this.FindControl("form1").FindControl("contenu").FindControl("ContentPlaceHolder1").FindControl("C");

[Erreurs.aspx] sayfasının bileşen ağacı ise şu şekildedir:


<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
  CodeBehind="Erreurs.aspx.cs" Inherits="pam_v7.PageErreurs" Title="Pam : erreurs" %>

<%@ MasterType VirtualPath="~/MasterPage.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
        <h3>Les erreurs suivantes se sont produites au démarrage de l'application</h3>
        <ul>
            <asp:Repeater id="rptErreurs" runat="server">
                <ItemTemplate>
                    <li>
                        <%# Container.DataItem %>
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </ul>
</asp:Content>

[Erreurs.aspx] sayfası ana sayfa M ile birleştirildiğinde, yukarıdaki <asp:Content> etiketinin içeriği (5-16. satırlar), M sayfasının "ContentPlaceholder1" kimliğine sahip <asp:ContentPlaceHolder> etiketine entegre edilir, böylece bu sayfanın bileşen ağacı şu şekilde olur:

...
<body background="ressources/standard.jpg">
    <form id="form1" runat="server">
        <asp:panel ID="entete" runat="server" BackColor="#FFE0C0" Width="1239px" >
...
        </asp:Panel>
        <div>
            <asp:Panel ID="contenu" runat="server" BackColor="#FFFFC0">
                <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
              <h3>Les erreurs suivantes se sont produites au démarrage de l'application</h3>
              <ul>
                  <asp:Repeater id="rptErreurs" runat="server">
                      <ItemTemplate>
                          <li>
                              <%# Container.DataItem %>
                          </li>
                      </ItemTemplate>
                  </asp:Repeater>
              </ul>
                </asp:ContentPlaceHolder>
            </asp:Panel>
        </div>
    </form>
</body>
</html>
  • 12. satır: [rptErreurs] bileşeni, ana sayfa M'nin [Erreurs.aspx] sayfasını içerip içermediğini belirlemek için kullanılabilir. Zira bu bileşen yalnızca bu sayfada mevcuttur.

Bu açıklamalar, ana sayfanın [Page_Init] prosedürünün kodunu anlamak için yeterlidir:


protected void Page_Init(object sender, System.EventArgs e)
        {
            // olay yöneticisi 
            LinkButtonTerminerSession.Click += LinkButtonTerminerSession_Click;
            // başlatma hataları mı var? 
            if (Global.Erreur)
            {
                // Kapsüllenmiş sayfa hata sayfası mı? 
                bool isPageErreurs = this.FindControl("form1").FindControl("contenu").FindControl("ContentPlaceHolder1").FindControl("rptErreurs") != null;
                // eğer görüntülenen sayfa hata sayfasıysa, olduğu gibi bırakılır; aksi takdirde kullanıcı hata sayfasına yönlendirilir 
                if (!isPageErreurs)
                    Response.Redirect("Erreurs.aspx");
                return;
            }
        }
  • 4. satır: LinkButtonTerminerSession bağlantısındaki Click olayına bir olay işleyicisi atanır. Bu işleyici, MasterPage sınıfındadır.
  • 6. satır: [Global] sınıfının Erreur boole değerini ayarlayıp ayarlamadığı kontrol edilir
  • 9. satır: Eğer öyleyse, IsPageErreurs boole değeri, ana sayfada kapsüllenmiş sayfanın [Erreurs.aspx] sayfası olup olmadığını belirtir
  • 12. satır: Ana sayfada kapsüllenmiş sayfa [Erreurs.aspx] sayfası değilse, istemci bu sayfaya yönlendirilir; aksi takdirde hiçbir işlem yapılmaz.

11.5.2.6. [LinkButtonTerminerSession] bağlantısına tıklama olayı

Kullanıcı yukarıdaki (1) numaralı görünümde [Terminer la session] bağlantısına tıkladığında, oturumun içeriği silinmeli ve boş bir form (2) gösterilmelidir.

Bu olayın işleyicisinin kodu şu şekilde olabilir:


        protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
        {
            // oturum sonlandırılır 
            Session.Abandon();
            // [formulaire] görünümünü görüntüler 
            Response.Redirect("Formulaire.aspx");
}
  • 4. satır: mevcut oturum sonlandırılır
  • 6. satır: müşteri, [Formulaire.aspx] sayfasına yönlendirilir

Bu kodun, [Formulaire.aspx, Simulations.aspx, Erreurs.aspx] sayfalarının hiçbir bileşenini kullanmadığı görülmektedir. Dolayısıyla olay, ana sayfa tarafından yönetilebilir.

11.5.3. [Erreurs.aspx] sayfasının kontrol kodu

[Erreurs.aspx] sayfasının kontrol kodu şu şekilde olabilir:


using System.Collections.Generic;

namespace pam_v7
{
  public partial class Erreurs : System.Web.UI.Page
  {
    protected void Page_Load(object sender, System.EventArgs e)
    {
      // başlatma hataları mı var? 
      if (Global.Erreur)
      {
        // [erreurs] sayfası şablonu hazırlanıyor 
        List<string> erreursInitialisation = new List<string>();
        erreursInitialisation.Add(Global.Msg);
        // hata listesi ilgili bileşene atanıyor 
        rptErreurs.DataSource = erreursInitialisation;
        rptErreurs.DataBind();
      }
      // menü sabitleniyor 
      Master.SetMenu(false, false, false, false, false, false);
    }
  }
}

[Erreurs.aspx] sayfasının tek işlevinin, uygulama başlatma hatası oluştuğunda bu hatayı görüntülemek olduğunu hatırlayalım:

  • 10. satır: başlatma işleminin bir hatayla sonuçlanıp sonuçlanmadığı kontrol edilir
  • 13-14. satırlar: Eğer öyleyse, hata mesajı (Global.Msg) [ErreursInitialisation] listesine eklenir
  • 16-17. satırlar: [rptErreurs] bileşeninden bu listeyi görüntülemesi istenir
  • 20. satır: Her durumda (hata olsun ya da olmasın), ana sayfanın menü seçenekleri görüntülenmez; böylece kullanıcı bu sayfadan yeni bir işlem başlatamaz.

Kullanıcı doğrudan [Erreurs.aspx] sayfasını talep ederse (uygulamanın normal kullanımında bunu yapması beklenmez) ne olur? [MasterPage.master.cs] ve [Erreurs.aspx.cs] kodlarını incelediğimizde şunu görürüz:

  • başlatma hatası varsa, bu hata görüntülenir
  • başlatma hatası yoksa, kullanıcıya yalnızca [MasterPage.master] başlığını içeren ve hiçbir menü seçeneği gösterilmeyen bir sayfa sunulur.

11.5.4. [Formulaire.aspx] sayfasının kontrol kodu

11.5.4.1. Sınıf şablonu

[Formulaire.aspx] sayfasının kontrol kodunun iskeleti şu şekilde olabilir:


using Pam.Metier.Entites;
...

partial class PageFormulaire : System.Web.UI.Page
{

    // sayfa yükleniyor 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // olay yöneticisi
        Master.OptionFaireSimulation.Click += OptFaireSimulation_Click;
        Master.OptionEffacerSimulation.Click += OptEffacerSimulation_Click;
        Master.OptionVoirSimulations.Click += OptVoirSimulations_Click;
        Master.OptionEnregistrerSimulation.Click += OptEnregistrerSimulation_Click;
....
    }

    // maaş hesaplaması 
    private void OptFaireSimulation_Click(object sender, System.EventArgs e)
    {
....
    }

    // simülasyonu sil 
    private void OptEffacerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void OptVoirSimulations_Click(object sender, System.EventArgs e)
    {
....
    }

    protected void OptEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }

}

[Formulaire.aspx] sayfa kontrol kodu beş olayı yönetir:

  1. sayfanın Load olayı
  2. ana sayfadaki [LinkButtonFaireSimulation] bağlantısı üzerindeki Click olayı
  3. ana sayfadaki [LinkButtonEffacerSimulation] bağlantısındaki Click olayı
  4. ana sayfadaki [LinkButtonEnregistrerSimulation] bağlantısındaki Click olayı
  5. ana sayfadaki [LinkButtonVoirSimulations] bağlantısındaki Click olayı

11.5.4.2. Sayfanın Load olayı

Sayfanın Load olay işleyicisinin iskeleti şu şekilde olabilir:


    protected void Page_Load(object sender, System.EventArgs e)
    {
        // olay yöneticisi
        Master.OptionFaireSimulation.Click += OptFaireSimulation_Click;
        Master.OptionEffacerSimulation.Click += OptEffacerSimulation_Click;
        Master.OptionVoirSimulations.Click += OptVoirSimulations_Click;
        Master.OptionEnregistrerSimulation.Click += OptEnregistrerSimulation_Click;
        // görünüm görüntüleme [saisies] 
        ...
        // ana sayfa menüsünü konumlandırma 
        ...
        // isteğin işlenmesi GET 
        if (!IsPostBack)
        {
            // çalışan adlarının açılır menüye yüklenmesi 
...
            // [saisies] görünümünü, varsa oturumda kaydedilmiş girdilerle başlatma 
....
        }
}
  1. satırdaki açıklamayı netleştirmek için bir örnek şu şekilde olabilir:
  • [1]'te simülasyon listesinin görüntülenmesi istenir. [A, B, C]'te girişler yapılmıştır.
  • [2]'te liste görüntülenir
  • [3]'te, forma geri dönülmesi istenir
  • [4]'te, formu bıraktığımız haliyle buluruz. İki istek (1,2) ve (3,4) olduğu için bu şu anlama gelir:
    • [1]'ten [2]'e geçiş sırasında, [1]'teki girdiler kaydedildi
    • [3]'ten [4]'e geçiş sırasında bu girişler geri yüklendi. Bu geri yükleme işlemini, [Formulaire.aspx]'in [Page_Load] prosedürü gerçekleştirir.

Soru: [pam-v4-3tier-nhibernate-multivues-monopage] sürümündeki açıklamalar ve koddan yararlanarak Page_Load prosedürünü tamamlayınız


11.5.4.3. Menü bağlantılarındaki tıklama olaylarının yönetimi

Ana sayfadaki bağlantılar üzerindeki Click olay işleyicilerinin iskeleti şu şekildedir:


// maaş hesaplaması 
    private void OptFaireSimulation_Click(object sender, System.EventArgs e)
    {
        // Ajax etkisi
        Thread.Sleep(3000);
        // sayfa geçerli mi? 
        Page.Validate();
        if (!Page.IsValid)
        {
            // [saisie] görünümünün görüntülenmesi 
...
        }
        // sayfa geçerli - girdiler alınır 
...
        // çalışanın maaşı hesaplanıyor 
        FeuilleSalaire feuillesalaire;
        try
        {
            feuillesalaire = ...;
        }
        catch (PamException ex)
        {
            // bir sorunla karşılaşıldı 
...
            return;
        }
        // sonuç oturuma kaydediliyor 
        Session["simulation"] = ...;
        // girdiler oturuma kaydediliyor 
...
        // görüntüleme 
...
        // görünümlerin görüntülenmesi 
...
        // menü görüntüleme MasterPage 
...
    }

    // simülasyonu sil 
    private void OptEffacerSimulation_Click(object sender, System.EventArgs e)
    {
        // panel görüntüleme [saisie] 
...
        // 1. çalışanı seç 
...
    }

    protected void OptVoirSimulations_Click(object sender, System.EventArgs e)
    {
        // girdileri oturuma kaydediyoruz 
...
        // görünümü görüntüleniyor [simulations] 
        Response.Redirect("simulations.aspx");
    }

    protected void OptEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
        // mevcut simülasyonu kullanıcının oturumuna kaydedilir 
...
        // [simulations] görünümünü görüntüler 
        Response.Redirect("simulations.aspx");
}

Soru: [pam-v4-3tier-nhibernate-multivues-monopage] sürümündeki açıklamalardan ve koddan yararlanarak yukarıdaki prosedürlerin kodunu tamamlayınız


11.5.5. [Simulations.aspx] sayfasının kontrol kodu

[Simulations.aspx] sayfasının kontrol kodunun iskeleti şu şekilde olabilir:


using System.Collections.Generic;
using Pam.Web;
using System.Web.UI.WebControls;

partial class PageSimulations : System.Web.UI.Page
{

    // simülasyonlar 
    private List<Simulation> simulations;

    // sayfa yükleniyor
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // olay yöneticisi 
        Master.OptionFormulaireSimulation.Click += OptFormulaireSimulation_Click;
        GridViewSimulations.RowDeleting += GridViewSimulations_RowDeleting;
        // oturumdaki simülasyonlar alınır
        simulations = ...;
        // simülasyon var mı? 
        if (simulations.Count != 0)
        {
            // ilk görünür görünüm 
            ...
            // GridView dolduruluyor 
            ...
        }
        else
        {
            // ikinci görünüm 
            ...
        }
        // menü sabitleniyor 
        ...
    }

    protected void GridViewSimulations_RowDeleting(object sender, System.Web.UI.WebControls.GridViewDeleteEventArgs e)
    {
        // oturumdaki simülasyonları alıyoruz
        List<Simulation> simulations = ...;
        // belirtilen simülasyon siliniyor (e.RowIndex, GridView'da silinen satırın numarasını temsil eder)
        ..
        // Hala simülasyonlar var mı? 
        if (simulations.Count != 0)
        {
            // gridview doldurulur 
            ...
        }
        else
        {
            // [SimulationsVides] görünümü 
            ...
        }
    }

    protected void OptFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
        // [formulaire] görünümü görüntüleniyor 
        Response.Redirect("formulaire.aspx");
    }

}

Soru: [pam-v4-3tier-nhibernate-multivues-monopage] sürümündeki yorumlardan ve koddan yararlanarak yukarıdaki prosedürlerin kodunu tamamlayın


11.5.6. [Default.aspx] sayfasının kontrol kodu

Uygulamada, kullanıcının aşağıda gösterildiği gibi herhangi bir sayfa belirtmeden uygulamanın URL kodunu talep etmesine olanak sağlamak için bir [Default.aspx] sayfası öngörülebilir:

[1] isteğine yanıt olarak [Formulaire.aspx] sayfası (2) gönderilmiştir. (1) numaralı isteğin varsayılan olarak uygulamanın [Default.aspx] sayfası tarafından işlendiği bilinmektedir. (2) sayfasını elde etmek için, [Default.aspx]'in istemciyi [Formulaire.aspx] sayfasına yönlendirmesi yeterlidir. Bu, aşağıdaki kodla gerçekleştirilebilir:


partial class _Default : System.Web.UI.Page
{

    protected void Page_Init(object sender, System.EventArgs e)
    {
        // giriş formuna yönlendiriliyor 
        Response.Redirect("Formulaire.aspx");
    }
}

[Default.aspx] tanıtım sayfası ise yalnızca onu [Default.aspx.cs] sayfasına bağlayan yönergeyi içerir:


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