บทความ

ASP.NET 2.0 MasterPage

เรตติ้ง
เขียนโดย admin เมื่อวันที่ 22 January 2008 ตอน 15:29
มาสเตอร์เพจใน ASP.NET 2.0ใช้ได้กับ
  • Microsoft ASP.NET 2.0

สรุป:

มาสเตอร์เพจช่วยให้คุณสร้างเพจ ASP.NET ซึ่งมีธีมและสไตล์สอดคล้องกัน เราจะบอกให้คุณทราบว่าคุณจะใช้ปมเด่นของคุณสมบัติใหม่นี้ได้อย่างไร

คำนำ

มาสเตอร์เพจเป็นคุณสมบัติใหม่ที่มีอยู่ใน Microsoft ASP NET 2.0 คุณสมบัตินี้จะช่วยให้คุณนำเอาเพจเลย์เอาท์เดิมไปใช้กับเพจข้อมูลหลายๆเพจที่อยู่ในเว็บแอพพลิเคชันได้   มาสเตอร์เพจจัดเป็นวิธีการง่ายๆที่ช่วยให้เว็บไซต์ของคุณมีหน้าตาที่คงเส้นคงวา

เพจต่างๆของเว็บแอพพลิเคชันส่วนใหญ่มีองค์ประกอบมาตรฐานที่หมือนกัน  อาทิเช่นโลโก เมนูค้นหา และข้อความแจ้งเตือนเรื่องลิขสิทธิ์เป็นต้น  คุณสามารถนำเอาองค์ประกอบต่างๆเหล่านี้ไปใส่เอาไว้ในมาสเตอร์เพจเพียงเพจเดียวได้ ถ้าหากคุณนำเอาเพจข้อมูลในแอพพลิเคชันไปโยงกับมาสเตอร์เพจนี้แล้วละก็   เพจข้อมูลทั้งหมดจะมีองค์ประกอบมาตรฐานที่เหมือนกันทั้งหมด

ในบทความนี้คุณจะเรียนรู้วิธีการใช้ประโยชน์จากมาสเตอร์เพจ   เพื่อสร้างเพจเลย์เอาท์แบบมาตรฐานขึ้นมา   นอกจากนั้นเรายังจะศึกษาคุณสมบัติใหม่ๆบางอย่างในมาสเตอร์เพจอีกด้วย        ตัวอย่างเช่นคุณจะเรียนรู้วิธีการแก้ไข header  properties  อาทิเช่นหัวเรื่องของเพจ  และ  meta tags จากเพจข้อมูลอีกด้วย นอกจากนั้นคุณยังจะเรียนรู้วิธีการโหลดมาสเตอร์เพจที่แตกต่างกันในตอนรันไทม์ได้อีกด้วย

 

มาสเตอร์เพจและเพจข้อมูล

ขอเริ่มโดยการสร้างมาสเตอร์เพจแบบง่ายๆขึ้นมาก่อน   คุณสามารถสร้างมาสเตอร์เพจโดยใช้โปรแกรม  Notepad ได้ หรือคุณอาจจะใช้ประโยชน์จาก Microsoft Visual Web Developer เพื่อช่วยให้ใช้บริการออกแบบอย่างเต็มที่ในขณะที่สร้างมาสเรอร์เพจก็ได้  (ดูภาพที่ 1) แม้ว่าการสร้างมาสเตอร์เพจโดยใช้ Visual Web Developer มีความสนุกสนานมากกว่าก็ตาม แต่ผมไม่คาดคิดว่าคุณต้องใช้ Visual Web Developer เท่านั้น

ภาพที่ 1 บริการออกแบบสำหรับมาสเตอร์เพจ

การสร้างมาสเตอร์เพจแบบง่ายๆ

การสร้างมาสเตอร์เพจเหมือนกับการสร้างเพจปกติของ  ASP.NET โดยที่ในมาสเตอร์เพจอาจจะมีเว็บคอนโทรล ยูซเซอร์คอนโทรล  ข้อมูล  HTML และสคริปท์ ที่คุณสามารถใส่ลงไปในเพจ ASP.NET มาตรฐานได้ อย่างไรก็ตามมีข้อแตกต่างหลักๆ 3 ประการระหว่างมาสเตอร์เพจกับเพจปกติของ ASP.NET

เรื่องแรกสิ่งที่ต่างจากเพจปกติของ  ASP.NET ก็คือชื่อของมาสเตอร์จะต้องมีนามสกุลพิเศษคือ .master นามสกุลดังกล่าวจะกำหนดให้เพจนี้เป็นมาสเตอร์เพจ  นอกจากนั้นคุณยังต้องมีการปรับแต่งแอพพลิเคชัน ASP.NET เพื่อที่คุณจะได้ไม่สามารถเรียกเพจที่มีนามสกุล  .master ได้อีก เนื่องจากการเรียกมาสเตอร์เพจโดยตรงเป็นเรื่องที่ไม่สมเหตุสมผล แต่คุณควรเรียกเพจข้อมูลที่อิงอยู่กับมาสเตอร์เพจจะดีกว่า

เรื่องที่สอง  มาสเตอร์เพจมี  <%@  Master  %>  directive แทนที่จะเป็น <%@ Page %> directive ปกติ โดยที่  <%@ Master %> directive รองรับ attributes ส่วนใหญ่เหมือนกับ <%@ Page %> directive ตัวอย่างเช่นคุณสามารถกำหนดภาษาในการเขียนโปรแกรมของเพจโดยใช้  directive  <%@ Master Language = "vb"%> เป็นต้น

ข้อแตกต่างเรื่องสุดท้ายระหว่างมาสเตอร์เพจและเพจปกติของ   ASP.NET  ก็คือมาสเตอร์เพจสามารถใส่คอนโทรล ContenPlaceHolder  ที่เป็นศูนย์หรือมากกว่าได้  โดยที่คอนโทรล  ContentPlaceHolder จะใช้ได้ภายในมาสเตอร์เพจเท่านั้น คอนโทรลนี้จะกำหนดหน้าที่ของมาสเตอร์เพจที่สามารถเขียนทับโดยเพจข้อมูลบางเพจได้

มาสเตอร์เพจในตัวอย่างโค้ดที่    1    มีชื่อว่า    Simple.master    เก็บตาราง    HTML   ที่มีคอนโทรล ContentPlaceHolder เอาไว้

ตัวอย่างโค้ด 1 Simple.master
<%@ Master %>
<html>
<head>
    <title>Simple Master Page</title>
</head>
<body>
<form id="form1" runat="server">
<table width="100%">
<tr>
    <td>
    <asp:ContentPlaceHolder 
        id="ContentPlaceHolder1" 
        runat="server" />
    </td>
    <td>
    <asp:ContentPlaceHolder 
        id="ContentPlaceHolder2" 
        runat="server" />
    </td>
</tr>
</table>
</form>
</body>
</html>

มาสเตอร์เพจในตัวอย่างโค้ด 1 เก็บคอนโทรล ContentPlaceHolder สองอันที่ชื่อ ContenPlaceHolder1 และ ContentPlaceHolder2   เอาไว้   คอนโทรลทั้งสองตัวทำหน้าที่กำหนดพื้นที่ของมาสเตอร์เพจที่สามารถแก้ไขในเพจข้อมูลแต่ละเพจได้  ถ้าหากคุณใช้ Visual Web Developer เปิดมาสเตอร์เพจในตัวอย่างโค้ด 1 ขึ้นมา คุณจะเห็นเพจเหมือนอย่างในภาพที่ 2 ดังนี้

ภาพที่ 2 มาสเตอร์เพจ Simple.masterถ้าหากลองสังเกตให้ดี เราจะพบว่ามาสเตอร์เพจในตัวอย่างโค้ด 1 เก็บ opening HTML tags แบบมาตรฐานเอาไว้  ตัวอย่างเช่นในนี้มี HTML <title> และ <body> tags อยู่ด้วย โดยปกติแล้วคุณคงอยากใส่ tags มาตรฐานเหล่านี้เอาไว้ในมาสเตอร์เพจด้วย  ซึ่งในช่วงต่อๆไปของบทความนี้  (หัวข้อ  "การแก้ไข  properties ของมาสเตอร์เพจ") เราจะอธิบายว่าคุณจะแก้ไขหัวเรื่องในเพจข้อมูลแต่ละหน้าได้อย่างไร

นอกจากนั้นถ้า  คุณสังเกตคุณจะพบว่ามาสเตอร์เพจมี <form> tag ในฝั่งของเซิร์ฟเวอร์ด้วย เนื่องจากระบบยอมให้คุณใส่  <form> tag ฝั่งเซิร์ฟเวอร์เอาไว้ในเพจ ASP.NET ได้เพียงจุดเดียว ดังนั้นคุณคงอยากใส่เพจดังกล่าวเอาไว้ในมาสเตอร์เพจอย่างแน่นอน

 

การสร้างเพจข้อมูลแบบง่ายๆ หลังจากที่คุณสร้างมาสเตอร์เพจขึ้นมาแล้ว     คุณสามารถเชื่อมโยงเพจข้อมูลตั้งแต่หนึ่งเพจขึ้นไปกับมาสเตอร์เพจได้ เพจข้อมูลก็คือเพจที่เว็บบราวเซอร์จะเรียกไปใช้งาน  โดยที่เพจข้อมูลจะมีนามสกุล .aspx เหมือนกับไฟล์ ASP.NET ปกติทั่วๆไป เพจข้อมูลคล้ายคลึงกับเพจ ASP.NET ปกติโดยมีข้อแตกต่าง 2 ประการ

เรื่องแรก ข้อมูลทั้งหมดของเพจข้อมูลจะต้องอยู่ในคอนโทรล Content เราใช้คอนโทรล Content เพื่อเทียบพื้นที่ข้อมูลในเพจข้อมูลไปยังพื้นที่ข้อมูลที่กำหนดโดยคอนโทรล ContentPlaceHolder ของมาสเตอร์เพจ

เรื่องที่สอง   เพจข้อมูลต้องเชื่อมโยงกับมาสเตอร์เพจ  โดยที่คุณสามารถเชื่อมโยงเพจข้อมูลกับมาสเตอร์เพจโดยใช้ attribute  ของ  <%@ Page %> directive หรือคุณอาจใช้ไฟล์ตัวแปรเว็บ เพื่อเชื่อมโยงเพจข้อมูลจำนวนมากกับมาสเตอร์เพจก็ได้

ตัวอย่างเช่น    เพจข้อมูลในโค้ดตัวอย่าง   2   มีคอนโทรล   Content   สองอัน   ซึ่งสอดคล้องกับคอนโทรล ContentPlaceHolder ในมาสเตอร์เพจของโค้ดตัวอย่าง 1

ตัวอย่างโค้ด 2 Simple.aspx

<%@ Page MasterPageFile="~/Simple.master" %>
<asp:Content
    ID="Content1"
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="server">
    Content in Left Column
</asp:Content>
<asp:Content
    ID="Content2"
    ContentPlaceHolderID="ContentPlaceHolder2"
    Runat="server">
    Content in Right Column
</asp:Content>

เพจข้อมูลในโค้ดตัวอย่าง  2 มี MasterPageFile attribute ใน <%@ Page %> directive ของตนเองด้วย โดยที่ attribute ดังกล่าวเกี่ยวข้องกับเพจข้อมูลที่ใช้มาสเตอร์เพจในตัวอย่างโค้ด 1ถ้าหากสังเกตให้ดีจะพบว่าคอนโทรล  Content ทั้งสองอันมีการใส่ข้อความลงไปใน tag เปิดและปิดของตนเองด้วย ซึ่งในกรณีนี้คอนโทรล  Content มีแต่ข้อความเท่านั้น อย่างไรก็ตามคุณสามารถใส่ข้อมูลใดๆก็ได้ที่คุณต้องการลงไปในคอนโทรล Content ได้ด้วย อาทิเช่นเว็บคอนโทรลและยูซเซอร์คอนโทรลเป็นต้น

เมื่อคุณแก้ไขเพจข้อมูลใน  Visual  Web  Developer คุณจะเห็นมาสเตอร์เพจซ่อนอยู่ในแบกกราวน์ (ดูภาพที่ 3) Visual  Web  Developer จะเพิ่มคอนโทรล Content ให้เองโดยอัตโนมัติ โดยที่คอนโทรลดังกล่าวจะเกี่ยวข้องกับ ContentPlaceHolder แต่ละอันจากมาสเตอร์เพจ

ภาพที่ 3: การแก้ไขเพจข้อมูลใน Visual Web Developer

 การสร้างมาสเตอร์เพจโดยใช้ Site Navigation

มาสเตอร์เพจและเพจข้อมูลที่เราพูดถึงในหัวข้อก่อนหน้านี้จัดว่าค่อนข้างเรียบง่ายมากเกินไป      ถ้าหากเป็นการใช้งานจริงแล้ว   คุณมักต้องการใส่องค์ประกอบมาตรฐานสำหรับการค้นหาสิ่งต่างๆ   อาทิเช่นเมนูบาร์และ   bread crumb  trail ลงไปด้วย ดังนั้นในหัวข้อนี้ เราจะอธิบายขั้นตอนของการสร้างมาสเตอร์เพจที่สมจริงมากขึ้นให้ดู (ดูภาพที่ 4)

 

ภาพที่ 4: มาสเตอร์เพจที่ซับซ้อนมากขึ้น

มาสเตอร์เพจของเราจะใส่ทั้งคอนโทล Site MapPath และคอนโทรล Menu เพื่อใช้สำหรับการค้นหาสิ่งต่างๆลงไปด้วย  คอนโทรล  SiteMapPath  แสดง  bread crumb trail ในขณะที่คอนโทรล Menu แสดงเมนูค้นหา คอนโทรลทั้งสองชนิดจะใช้ไฟล์ SiteMap ในตัวอย่างโค้ด 3ตัวอย่างโค้ด 3 web.sitemap

<?xml version="1.0" encoding="utf-8" ?>
<siteMap>
    <siteMapNode url="~/Default.aspx" title="Home">
   <siteMapNode url="~/Products.aspx" title="Products"/>
   <siteMapNode url="~/Services.aspx" title="Services"/>
    </siteMapNode>
</siteMap>

ไฟล์  SiteMap  ในตัวอย่างโค้ด  3  กำหนดโหนด  3 ชนิดก็คือโฮมเพจ เพจผลิตภัณฑ์ และเพจบริการ โดยแต่ละโหนดจะมีการระบุ  URL  และ  title attribute เอาไว้ มาสเตอร์เพจในตัวอย่างที่ 4 นำเอาไฟล์นี้ไปใช้ประโยชน์ร่วมกับคอนโทรล SiteMapPath และ Menuโค้ดตัวอย่าง 4: NavMaster.master
<%@ Master %>
<html>
<head>
    <title>NavMaster</title>
</head>
<body>
    <form id="form1" runat="server">

        <table 
            width="100%"
            border="0"
            cellpadding="5">
        <tr>
            <td colspan="2">
            <asp:Image 
                id="Image1"
                ImageUrl="~/Logo.gif" Runat="Server" />
            </td>
        </tr>
        <tr bgcolor="lightblue">
            <td colspan="2">
            <asp:SiteMapPath 
                id="SiteMapPath1" 
                Runat="Server" />             
            </td>
        </tr>
        </table>
        <table width="100%" cellpadding="10" border="0">
        <tr>
            <td valign="top" width="100" bgcolor="#eeeeee">
            <asp:Menu 
                id="Menu" 
                Runat="Server" 
                DataSourceID="SiteMapDataSource1" 
                StaticDisplayLevels="2" />
            </td>
            <td valign="top">
            <asp:contentplaceholder 
                id="ContentColumn" 
                runat="server" />
            </td>
            <td valign="top" width="100" bgcolor="#eeeeee">
            <asp:ContentPlaceHolder 
                id="AdColumn" 
                runat="server">
                <asp:Image
                    ID="Ad1" 
                    ImageUrl="Ad1.gif"
                    Runat="Server" />
                <br />
                <asp:Image
                    ID="Ad2"  
                    ImageUrl="Ad2.gif"
                    Runat="Server" />
            </asp:ContentPlaceHolder>
            </td>
        </tr>
        </table>     
        <small>All contents copyright &copy; 
  2004 by Microsoft Hair Stylists</small>
        <asp:SiteMapDataSource ID="SiteMapDataSource1" 
  Runat="server" />
    </form>
</body>
</html>
มาสเตอร์เพจในโค้ดตัวอย่าง     4    มีคอนโทรล    ContentPlaceHolder    สองอัน    โดยที่คอนโทรล ContentPlaceHolder  อันแรกใช้เป็นที่เก็บข้อมูลของเพจหลัก  ในขณะที่คอนโทรล ContentPlaceHolder อันที่สองใช้เป็นที่เก็บข้อมูลโฆษณา

คอนโทรล  ContentPlaceHolder  อันที่สองเก็บข้อมูลเบื้องต้นเอาไว้ ซึ่งประกอบด้วยคอนโทรล Image สองอันที่เอาไว้แสดงผลป้ายโฆษณา (ดูภาพที่ 5) เราสามารถนำเอาข้อมูลอื่นๆมาทับโฆษณาได้ในบางเพจด้วย

ภาพที่ 5: มาสเตอร์เพจ NavMaster.master

ท้ายสุดเพจข้อมูลในตัวอย่างโค้ด  5  อิงอยู่กับมาสเตอร์เพจ  NavMaster.master (ดูภาพที่ 6) เพจนี้มีคอนโทรล Content เพียงอันเดียว ซึ่งเก็บข้อมูลสำหรับพื้นที่ข้อมูลหลักของมาสเตอร์เพจเอาไว้

ภาพที่ 6: เพจ Products.aspxตัวอย่างโค้ด 5: Product.aspx

<%@ Page MasterPageFile="~/NavMaster.master" %>
<asp:Content
    ID="Content1"
    ContentPlaceHolderID="ContentColumn"
    Runat="server">
    This is the Products.aspx page
</asp:Content>

เท่าที่ผ่านมาเราได้อธิบายวิธีการสร้างมาสเตอร์เพจเพียงอันเดียวและอ้างอิงเพจข้อมูลกับมาสเตอร์เพจ    แต่ที่จริงแล้วเว็บไซต์แต่ละแห่งอาจจะมีมาสเตอร์เพจหลายๆอันได้  ตัวอย่างเช่นคุณสามารถสร้างมาสเตอร์เพจที่ต่างสำหรับหัวข้อมูลต่างๆในเว็บไซต์ได้นอกจากนั้นถ้าหากคุณต้องการ      คุณยังสามารถซ้อนมาสเตอร์เพจหลายๆอันเข้าด้วยกันได้     ตัวอย่างเช่นคุณสามารถสร้างมาสเตอร์เพจอันหนึ่งขึ้นมาสำหรับทั้งเว็บไซต์  จากนั้นซ้อนมาสเตอร์เพจย่อยอีกหลายๆอันลงไปในมาสเตอร์เพจของเว็บไซต์ เพื่อรองรับเนื้อหาแต่ละหัวข้อได้ Visual Web Developer ไม่มีบริการช่วยออกแบบในเรื่องนี้ ดังนั้นถ้าหากคุณต้องการมาสเตอร์เพจเชิงซ้อน คุณต้องใช้ source code view หรือสร้างเพจโดยใช้ Notepad ก็ได้ตัวอย่างเช่นเพจในตัวอย่างที่  6  อาจใช้เป็นมาสเตอร์เพจของไซต์ได้  มาสเตอร์เพจนี้จะมี  HTML เปิดและปิด มี Form tags และมีคอนโทรล ContentPlaceHolder อีกหนึ่งอันโค้ดตัวอย่าง 6: SiteMasste.master

<%@ Master %>
<html>
<head>
    <title>Site Master</title>
</head>
<body bgcolor="LightGreen">
    <form id="form1" runat="server">
        <h1>Site Master Page</h1>
        <asp:contentplaceholder
            id="SiteContentPlaceHolder"
            runat="server" />
    </form>
</body>
</html>

เพจในตัวอย่างโค้ด  7 เป็นมาสเตอร์เพจเชิงซ้อน โดยที่มาสเตอร์เพจนี้จะไปทับข้อมูลที่อยู่ในมาสเตอร์เพจของไซต์ ถ้าหากลองสังเกตให้ดีจะพบว่า <%@ Master %> directive อ้างอิงถึงมาสเตอร์เพจ SiteMaster.masterโค้ดตัวอย่าง 7: SectionMaster.master

<%@ Master  MasterPageFile="~/SiteMaster.master" %>
<asp:content
    ContentPlaceHolderID="SiteContentPlaceHolder"
    runat="server">
   
    <table width="100%" bgcolor="LightYellow">
    <tr>
        <td colspan="2">
        <h1>Section Master Page</h1>
        </td>
    </tr>
    <tr>
        <td>
        <asp:ContentPlaceHolder  
            id="LeftColumn"
            Runat="Server" />    
       
        </td>
        <td>
        <asp:ContentPlaceHolder  
            id="RightColumn"
            Runat="Server" />    
        </td>
    </tr>
    </table>
   
</asp:content>

ท้ายสุดเพจข้อมูลในโค้ดตัวอย่าง 8 อิงอยู่กับมาสเตอร์เพจหัวข้อย่อย ถ้าลองสังเกตุ คุณจะพบว่าเพจนี้จะมีการเขียนข้อมูลทับคอนโทรล ContentPlaceHolder สองอันที่อยู่ในมาสเตอร์เพจหัวข้อย่อยโค้ดตัวอย่าง 8: NestedMaster.aspx

<%@ Page MasterPageFile="~/SectionMaster.master" %>

<asp:Content   
    ContentPlaceHolderId="LeftColumn"
    Runat="Server">

    This content appears in the left column

</asp:Content>


<asp:Content  
    ContentPlaceHolderId="RightColumn"
    Runat="Server">

    This content appears in the right column

</asp:Content>

หลังจากทำเสร็จแล้ว  คุณจะเห็นเพจตามภาพที่  7 ถ้าลองสังเกตจะพบว่าข้อมูลมาสเตอร์เพจของไซต์ และมาสเตอร์เพจหัวข้อย่อยจะรวมเข้าด้วยกันเพื่อสร้างเพจข้อมูลสุดท้ายขึ้นมา  ข้อมูลมาสเตอร์เพจของไซต์จะเป็นสีเขียว  สวนข้อมูลมาสเตอร์เพจของหัวข้อย่อยจะเป็นสีเหลือง

ภาพที่ 7: มาสเตอร์เพจเชิงซ้อน

 การปรับแต่งมาสเตอร์เพจ แทนที่จะเชื่อมโยงเพจข้อมูลกับมาสเตอร์เพจโดยใช้  <%@ Page %> directive แต่คุณสามารถเชื่อมโยงมาสเตอร์เพจกับเพจข้อมูลที่อยู่ภายในไฟล์ตัวแปรเว็บแอพพลิเคชันของคุณได้ด้วยเช่นกัน การใช้ไฟล์ตัวแปรจะช่วยให้เราดูแลเว็บไซต์ขนาดใหญ่ได้ง่ายขึ้น เนื่องจากคุณสามารถแก้ไขมาสเตอร์เพจที่เกี่ยวข้องกับเพจข้อมูลจำนวนมากได้ในทีเดียวคุณสามารถกำหนดมาสเตอร์เพจให้อยู่ภายใน  <pages> element ของไฟล์ตัวแปรได้ (element ดังกล่าวอยู่ในหัวข้อ  <system.web>  ของไฟล์ตัวแปร) ตัวอย่างเช่น <pages> element ด้านล่างกำหนดให้มาสเตอร์เพจเริ่มต้นเป็น "SuperMaster.master"

<pages masterPageFile="SuperMaster.master" />

คุณจำเป็นต้องตระหนักถึงประเด็นสำคัญสองประการก่อนที่จะกำหนดมาสเตอร์เพจในไฟล์ตัวแปร     เรื่องแรกการกำหนดมาสเตอร์เพจภายในเพจข้อมูลจัดว่ามีสิทธิมากกว่าการกำหนดมาสเตอร์เพจในไฟล์ตัวแปร    ด้วยเหตุนี้ถ้าหากคุณต้องการใช้ไฟล์  Web.Config  เพื่อกำหนดมาสเตอร์เพจ คุณไม่ควรใส่ MasterPageFile attribute ลงไปในเพจข้อมูลอีก

เรื่องที่สอง แอพพลิเคชันของคุณสามารถจัดเก็บไฟล์ Web.Config มากกว่าหนึ่งไฟล์ที่อยู่ในซับโฟลเดอร์ต่างๆได้ เพื่อใช้กำหนดมาสเตอร์เพจที่ต่างกัน    หรือพูดอีกแง่หนึ่งก็คือคุณสามารถทับมาสเตอร์เพจที่กำหนดเอาไว้ในไฟล์   Web.Config ที่อยู่ในซับโฟลเดอร์ได้โดยการสร้างไฟล์ Web.Config อันใหม่ขึ้นมา

 การสร้างข้อมูลใหม่ทับมาสเตอร์เพจ properties ปัญหาอย่างหนึ่งที่คุณจะเจอเกือบในทันทีเมื่อทำงานกับมาสเตอร์เพจก็คือการเขียนข้อมูลทับ properties อย่างเพจหัวเรื่องและ meta tags ของมาสเตอร์เพจที่อยู่ในเพจข้อมูลแต่ละเพจ โดยปกติแล้วคุณมักต้องการแสดงหัวเรื่องที่ไม่ซ้ำกันสำหรับเพจข้อมูลแต่ละเพจ แม้ว่าเพจข้อมูลแต่ละเพจจะอิงอยู่กับมาสเตอร์เพจที่ใช้ร่วมกันเพียงอันเดียวก็ตาม

มีวิธีการหลายแบบที่ใช้เขียนทับข้อมูลในมาสเตอร์เพจที่อยู่ภายในเพจข้อมูลแต่ละเพจ  โดยเราจะอธิบายแต่ละวิธีในหัวข้อนี้

 การใช้ PageTitle attribute ถ้าหากคุณเพียงแต่ต้องการแก้ไขหัวเรื่องของเพจที่ได้มาจากมาสเตอร์เพจภายในเพจข้อมูลแล้วละก็       คุณต้องใช้ Title  attribute  ของ <%@ Page %> directive โดยที่ attribute ตัวนี้จะมีผลก็ต่อเมื่อมาสเตอร์เพจใช้คอนโทรลในฝั่งเซิร์ฟเวอร์ตัวอย่างเช่น มาสเตอร์เพจในตัวอย่างโค้ด 9 มีคอนโทรล HtmlHead ในฝั่งเซิร์ฟเวอร์อยู่โค้ดตัวอย่าง 9: TitleMaster.master

<%@ Master %>
<html>
<head runat="server">
    <title>Master Title</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:contentplaceholder
        id="ContentPlaceHolder1"
        runat="server" />
    </form>
</body>
</html>

ถ้าหากลองสังเกตเราจะพบว่า  <head>  tag  ในโค้ดตัวอย่าง  9  มี runat="server" attribute อยู่ด้วย attribute ตัวนี้จะแปลงสภาพ <head> tag ไปเป็นคอนโทรล HtmlHead ในฝั่งเซิร์ฟเวอร์เพจข้อมูลในตัวอย่างโค้ด 10 จะนำข้อมูลใหม่เขียนทับลงไปในหัวเรื่องของเพจ ถ้าหากสังเกตจะพบว่า <%@ Page %>  directive  ที่อยู่ด้านบนสุดของเพจมีค่าสำหรับ Title attribute ของตนเองด้วย ถ้าหากมีการแสดงผล ข้อความ "Content Pagte Title" จะแสดงเป็นหัวเรื่องของเพจโค้ดตัวอย่าง 10: TitleContent.aspx

<%@ Page MasterPageFile="~/TitleMaster.master" Title="Content Page Title" %>

<asp:Content
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
   
    Here is some content
   
</asp:Content>

 

การเขียนข้อมูลทับ HTML Header attributes

ถ้าหากคุณต้องการเขียนข้อมูลทับ  attribute  ตัวอื่นๆของ  HTML  header อาทิเช่น meta tags หรือ style tags แล้วละก็ คุณสามารถอ้างอิง HtmlHead element ได้โดยตรงจากเพจข้อมูล โดยที่คอนโทรล HtmlHead จะใช้อินเทอร์เฟซ IPageHeader ซึ่งประกอบด้วย properties ดังต่อไปนี้

  • LinkedStyle Sheets: style sheets ภายนอกที่เชื่อมโยงกับเพจ HTML
  • Metadata: ชุดของ Metadata tags
  • SytleSheet: เป็นตัวแทนของสไตล์ที่ใช้กับเพจ HTML
  • Title: หัวเรื่องของเพจ HTML
คุณสามารถแก้ไข  properties เหล่านี้ที่อยู่ภายในเพจข้อมูลได้ ตัวอย่างเช่นมาสเตอร์เพจในตัวอย่างโค้ด 11 ประกอบด้วยคอนโทรล HtmlHead ในฝั่งเซิร์ฟเวอร์ที่สามารถนำเอาข้อมูลอื่นมาเขียนทับในเพจข้อมูลได้โค้ดตัวอย่าง 11: HeaderMaster.master

<%@ Master %>

<html>
<head runat="server">
    <title>Master Title</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:contentplaceholder
        id="ContentPlaceHolder1"
        runat="server" />
    </form>
</body>
</html>

เพจข้อมูลที่อยู่ในตัวโค้ด  12  มีการแก้ไข  properties ทั้ง Title และ Metadata ของคอนโทรล HtmlHead เพื่อใช้แสดงข้อมูลพิเศษโค้ดตัวอย่าง 12: HeaderContent.aspx (Microsoft Visual Basic .NET)

<%@ Page Language="VB" MasterPageFile="~/HeaderMaster.master" %>

<script runat="server">

    Sub Page_Load()
        Master.Page.Header.Title = "Content Title"
        Master.Page.Header.Metadata.Add("Keywords", "blah,blah")
        Master.Page.Header.Metadata.Add("Description", "blah,blah")
    End Sub
   
</script>

<asp:Content
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
   
    Here is some content
   
    </asp:Content>

โค้ดตัวอย่าง 12: HeaderContent.aspx (C#)

<%@ Page Language="c#" MasterPageFile="~/HeaderMaster.master" %>

<script runat="server">

    void Page_Load() {
        Master.Page.Header.Title = "Content Title";
        Master.Page.Header.Metadata.Add("Keywords", "blah,blah");
        Master.Page.Header.Metadata.Add("Description", "blah,blah");
    }
   
</script>

<asp:Content ID="Content1"
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
   
    Here is some content
   
    </asp:Content>

Master  property ของ Page object อ้างอิงไปยังมาสเตอร์เพจของเพจข้อมูล (คุณอาจจะใช้ Page.Master แทนที่จะเป็น  Master ก็ได้ถ้าต้องการ) ส่วน Header property อ้างอิงถึง HtmlHead element โดยที่เพจข้อมูลของโค้ดตัวอย่าง 12 มีการแก้ไข Title และ Metadata properties ของคอนโทรล HtmlHead แล้ว

 การใช้ properties และ methods จากมาสเตอร์เพจ ถ้าหากคุณต้องการควบคุมข้อมูลของมาสเตอร์เพจให้มากขึ้นไปอีก    ถ้าอย่างนั้นคุณควรใช้    properties   และ methods  จากมาสเตอร์เพจ  คุณสามารถแก้ไข public properties ที่มาสเตอร์เพจใช้ในเพจข้อมูลได้ โดยคุณสามารถเรียกใช้ public methods ที่มาสเตอร์เพจใช้ในเพจข้อมูลได้ตัวอย่างเช่นถ้าหากคุณต้องการแก้ไขข้อมูลของท้ายเรื่องมาสเตอร์เพจที่อยู่ในเพจข้อมูลแล้วละก็   มาสเตอร์เพจในตัวอย่าง 13 จะมี public property ชื่อ Footer ให้คุณแก้ไขได้โค้ดตัวอย่าง 13: Footer Master.master (Visual Basic .NET)
<%@ Master Language="VB" %>

<script runat="server">

    Private _footer As String
    
    Public Property Footer() As String
        Get
            Return _footer
        End Get
        Set(ByVal value As String)
            _footer = value
        End Set
    End Property
    
</script>

<html>
<head runat="server">
    <title>Footer Master</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:contentplaceholder 
        id="ContentPlaceHolder1" 
        runat="server" />
    <br />
    <small><%= _footer %></small>
    </form>
</body>
</html>
โค้ดตัวอย่าง 13: FooterMaster.master (C#)
<%@ Master Language="C#" %>

<script runat="server">

    private string _footer;
    
    public string Footer {
        get {
            return _footer;
        }
        set {
            _footer = value;
        }
    }
    
</script>

<html>
<head id="Head1" runat="server">
    <title>Footer Master</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:contentplaceholder 
        id="ContentPlaceHolder1" 
        runat="server" />
    <br />
    <small><%= _footer %></small>
    </form>
</body>
</html>
ในตัวอย่างโค้ด  13  ส่วนที่เป็น  public Footer property มีการแก้ไขไพรเวทฟิลด์ที่ชื่อ _footer โดยที่ฟิลด์ private _footer แสดงเอาไว้ด้านล่างของมาสเตอร์เพจโดยใช้ inline expression <%- _footer %>เพจข้อมูลในตัวอย่างโค้ด  14  มีการกำหนด  Footer  property ด้วย โดยที่ Master property ของ Page object   จะเป็นผู้ใช้   Footer  property  ตัวนี้  โดยปกติแล้ว  Master  property  ถือเป็นตัวแทนของ MasterPage  object  อย่างไรก็ตามเพจข้อมูลนี้มี  <%@  MasterType %> directive ที่ส่งค่าของ Master property ไปยัง FootMaster object ด้วยตัวอย่างโค้ด 14: FootContent.aspx (Visual Basic .NET)
<%@ Page Language="VB" MasterPageFile="~/FooterMaster.master" %>
<%@ MasterType VirtualPath="~/FooterMaster.master" %>

<script runat="server">

    Sub Page_Load()
        Master.Footer = "Custom Page Footer"
    End Sub
    
</script>

<asp:Content
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
    Here is some content    
</asp:Content>
ตัวอย่างโค้ด 14: FootContent.aspx (C#)

<%@ Page Language="C#" MasterPageFile="~/FooterMaster.master" %>
<%@ MasterType VirtualPath="~/FooterMaster.master" %>

<script runat="server">

    void Page_Load() {
        Master.Footer = "Custom Page Footer";
    }
   
</script>

<asp:Content ID="Content1"
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
    Here is some content   
</asp:Content>

การใช้ properties และ methods ในมาสเตอร์เพจจะช่วยให้คุณแก้ไขการแสดงผลทุกจุดของมาสเตอร์เพจได้

 การโหลดมาสเตอร์เพจที่มีการเปลี่ยนแปลงได้ ในหัวข้อสุดท้ายนี้  เราจะทำการดัดแปลงมาสเตอร์เพจให้ก้าวหน้ามากขึ้นไปอีก  โดยเราจะอธิบายว่าคุณจะโหลดมาสเตอร์เพจที่ต่างกันตอนรันไทม์ได้อย่างไรมีบางสถานการณ์ที่การโหลดมาสเตอร์เพจที่ต่างกันจัดว่ามีประโยชน์อย่างมาก   เรื่องแรก  คุณอาจต้องการผสานเว็บไซต์ของคุณกับเว็บไซต์ของพันธมิตรมากกว่าหนึ่งรายก็เป็นได้ ถ้าหากมีผู้ใช้บางคนเข้ามาหาเว็บไซต์ของคุณผ่านทางเว็บไซต์พันธมิตร คุณอาจต้องการโหลดมาสเตอร์เพจที่สอดคล้องกับหน้าตาเว็บไซต์พันธมิตรโดยอัตโนมัติก็เป็นได้อีกสถานการณ์หนึ่งที่คุณอาจต้องการโหลดมาสเตอร์เพจที่ต่างออกไปก็คือ   เมื่อคุณต้องการให้ผู้ที่ใช้แอพพลิเคชันของคุณสามารถเลือกเพจเลย์เอาท์ได้เองตามความต้องการ ดังนั้นคุณจึงเตรียมชุดมาสเตอร์เพจมาตรฐานเอาไว้ให้ผู้ใช้เลือก ผู้ใช้แอพพลิเคชันสามารถเลือกเพจเลย์เอาท์ที่ตนพอใจได้โดยการเลือกจาก favorite ของมาสเตอร์เพจคุณสามารถโหลดมาสเตอร์เพจที่ต่างออกไปโดยการกำหนดค่าให้แก่  MasterPageFile  property  ของ  Page object ค่าที่กำหนดให้ property นี้ควรมีเส้นทางสัมพันธ์กับไฟล์มาสเตอร์เพจที่ถูกต้องด้วยคุณควรทราบข้อจำกัดสำคัญอย่างหนึ่งก่อนใช้    MasterPageFile   property   ก็คือคุณสามารถกำหนดค่าให้แก่ property  นี้ก่อนหรือระหว่าง  Page PreInit event เท่านั้น PreInit เป็นเหตุการณ์แรกสุดในช่วงวงจรประมวลผลเพจ  ถ้าหากคุณพยายามที่จะกำหนดค่าให้แก่  property  นี้ในช่วงเหตุการณ์หลังๆ  อาทิเช่นในช่วง  Page Load  event  คุณจะได้รับข้อความเตือน ข้อจำกัดดังกล่าวถือเป็นเรื่องที่เหมาะสมแล้ว เนื่องจาก MasterPage ที่แตกต่างกันจะส่งผลต่อชุดคอนโทรลต่างๆที่กำลังโหลดขึ้นไปในเพจเพจข้อมูลในตัวอย่างโค้ด  15 ใช้ประโยชน์จาก MasterPageFile property เพื่อโหลดมาสเตอร์เพจที่ต่างกันในข่วงรันไทม์โค้ดตัวอย่าง 15: DynamicContent.aspx (Visual Basic .NET)

<%@ Page Language="VB" MasterPageFile="~/DynamicMaster1.master" %>

<script runat="server">
   
    Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)
        MasterPageFile = Profile.Master
    End Sub

</script>

<asp:Content
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
    Here is the content
</asp:Content>

โค้ดตัวอย่าง 15: DynamicContent.aspx (C#)

<%@ Page Language="c#" MasterPageFile="~/DynamicMaster1.master" %>

<script runat="server">
   
    void Page_PreInit(Object sender, EventArgs e) {
        MasterPageFile = Profile.Master;
    }

</script>

<asp:Content ID="Content1"
    ContentPlaceHolderID="ContentPlaceHolder1"
    Runat="Server">
    Here is the content
</asp:Content>

ในโค้ดตัวอย่าง  15 มีการโหลดมาสเตอร์เพจที่ต่างกันในช่วง PreInit event ซึ่งในกรณีนี้มีการโหลดเส้นทางระบุไฟล์มาสเตอร์เพจจากประวัติของผู้ใช้  คุณสามารถใช้ประวัติดังกล่าวเพื่อจัดเก็บข้อมูลอื่นๆที่เกี่ยวข้องกับผู้ใช้คนนี้ได้ วิธีนี้ทำให้เมื่อผู้ใช้ย้ายจากเพจหนึ่งไปยังอีกเพจหนึ่งในแอพพลิเคชัน มาสเตอร์เพจที่ผู้ใช้เลือกเอาไว้ก็จะไม่หายไปไหนการที่จะใช้ประโยชน์จากประวัติผู้ใช้  คุณต้องเพิ่มตัวแปรเหล่านี้ลงไปในหัวข้อ  <system.web>  ที่อยู่ในไฟล์ Web.Config ของแอพพลิเคชันด้วย

<anonymousIdentification enabled="true" />
    
<profile>
<properties>
    <add
   name="Master"
    allowAnonymous="true"
   defaultValue="DynamicMaster1.master" />
</properties>
</profile>

ตัวแปรเหล่านี้สามารถสร้าง  Profile  property  ใหม่ขึ้นมาชื่อ Master ที่สามารถใช้กับผู้ใช้นิรนามหรือผู้ใช้ที่มีสิทธิถูกต้องการได้เพจข้อมูลในตัวอย่างโค้ด   15   โหลดมาสเตอร์เพจหนึ่งหรือสองอันขึ้นมาชื่อ  DynamicMaster1.master  และ DynamicMaster2.master  ซอร์ซโค้ดของ  DynamicMaster1.master  อยู่ในตัวอย่างโค้ด 16 และซอร์ซโค้ดของ  DynamicMaster2.master อยู่ในตัวอย่างโค้ด 17 มาสเตอร์เพจเหล่านี้เหมือนกันยกเว้นมีชื่อต่างกันและใช้สีแบกกราวน์ที่ต่างกันเท่านั้นตัวอย่างโค้ด 16: DynamicMaster1.master (Visual Basic .NET)
<%@ Master Language="vb" %>
<script runat="server">

    Sub Page_Load()
        If Not IsPostBack Then
            dropMaster.SelectedValue = Profile.Master
        End If
    End Sub
    
    Sub SelectMaster(ByVal s As Object, ByVal e As EventArgs)
        Profile.Master = dropMaster.SelectedValue
        Response.Redirect(Request.Path)
    End Sub
    
</script>

<html>
<head>
    <title>Dynamic Master 1</title>
</head>
<body bgcolor="LightYellow">
<form runat="server">
<h1>Dynamic Master 1</h1>
<p>
<asp:DropDownList 
    id="dropMaster"
    AutoPostBack="true"
    OnSelectedIndexChanged="SelectMaster" 
    ValidationGroup="Master" 
    Runat="Server">
    <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" />
    <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" />
</asp:DropDownList>
</p>
<asp:contentplaceholder 
    id="ContentPlaceHolder1" 
    runat="server" />
</form>
</body>
</html>
ตัวอย่างโค้ด 16: DynamicMaster1.master (C#)
<%@ Master Language="c#" %>

<script runat="server">
    
    void Page_Load() {
        if (!IsPostBack)
            dropMaster.SelectedValue = Profile.Master;
        }
    
    void SelectMaster(Object s, EventArgs e) {
        Profile.Master = dropMaster.SelectedValue;
        Response.Redirect(Request.Path);
    }
    
</script>

<html>
<head>
    <title>Dynamic Master 1</title>
</head>
<body bgcolor="LightYellow">
<form id="Form1" runat="server">
<h1>Dynamic Master 1 CS</h1>
<p>
<asp:DropDownList 
    id="dropMaster"
    AutoPostBack="true"
    OnSelectedIndexChanged="SelectMaster" 
    ValidationGroup="Master" 
    Runat="Server">
    <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" />
    <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" />
</asp:DropDownList>
</p>
<asp:contentplaceholder 
    id="ContentPlaceHolder1" 
    runat="server" />
</form>
</body>
</html>
ตัวอย่างโค้ด 17: DynamicMaster2.master (visual Basic .NET)
<%@ Master Language="vb" %>
<script runat="server">
    Sub Page_Load()
        If Not IsPostBack Then
            dropMaster.SelectedValue = Profile.Master
        End If
    End Sub
    
    Sub SelectMaster(ByVal s As Object, ByVal e As EventArgs)
        Profile.Master = dropMaster.SelectedValue
        Response.Redirect(Request.Path)
    End Sub
    
</script>

<html>
<head>
    <title>Dynamic Master 2</title>
</head>
<body bgcolor="LightGreen">
<form id="Form1" runat="server">
<h1>Dynamic Master 2</h1>
<p>
<asp:DropDownList 
    id="dropMaster"
    AutoPostBack="true"
    OnSelectedIndexChanged="SelectMaster" 
    ValidationGroup="Master"
    Runat="Server">
    <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" />
    <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" />
</asp:DropDownList>
</p>
<asp:contentplaceholder 
    id="ContentPlaceHolder1" 
    runat="server" />
</form>
</body>
</html>
ตัวอย่างโค้ด 17: DynamicMaster2.master (C#)
<%@ Master Language="c#" %>
<script runat="server">
    
    void Page_Load() {
        if (!IsPostBack)
            dropMaster.SelectedValue = Profile.Master;
        }
    
    void SelectMaster(Object s, EventArgs e) {
        Profile.Master = dropMaster.SelectedValue;
        Response.Redirect(Request.Path);
    }
    
</script>

<html>
<head>
    <title>Dynamic Master 2</title>
</head>
<body bgcolor="LightGreen">
<form id="Form1" runat="server">
<h1>Dynamic Master 2 CS</h1>
<p>
<asp:DropDownList 
    id="dropMaster"
    AutoPostBack="true"
    OnSelectedIndexChanged="SelectMaster" 
    ValidationGroup="Master"
    Runat="Server">
    <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" />
    <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" />
</asp:DropDownList>
</p>
<asp:contentplaceholder 
    id="ContentPlaceHolder1" 
    runat="server" />
</form>
</body>
</html>
มาสเตอร์เพจทั้งสองอันมีคอนโทรล DropDownList ที่ช่วยให้ผู้ใช้เลือกมาสเตอร์เพจในแบบที่ตนเองต้องการได้ เมื่อผู้ใช้เลือกมาสเตอร์เพจอันใดอันหนึ่งจะมีการเรียก  SelectMaster  method  ขึ้นมา  method นี้เป็นการกำหนด Master  Page  ที่เลือกเอาไว้ไปเก็บไว้ในประวัติของผู้ใช้ และโหลดเพจปัจจุบันขึ้นมาอีกทีหนึ่ง การโหลดเพจขึ้นมาใหม่เป็นสิ่งที่จำเป็นเนื่องจากมาสเตอร์เพจใหม่ที่เลือกเอาไว้ต้องถูกโหลดในช่วง PreInit event เท่านั้น

 

สรุป มาสเตอร์เพจจัดเป็นคุณสมบัติใหม่ที่ผมโปรดปรานมากที่สุดชนิดหนึ่งใน   ASP.NET  2.0  คุณสมบัติใหม่นี้จะส่งผลกระทบอย่างมากต่อการสร้างแอพพลิเคชัน  ASP.NET ของผมในอนาคตอย่างแน่นอน ในปัจจุบันผมต้องปลุกปล้ำกับยูซเซอร์คอนโทล   หรือเพจคลาสพิเศษ  เพื่อสร้างเพจเลย์เอาท์ซึ่งสามารถนำมาใช้ซ้ำได้  แต่มาสเตอร์เพจจัดเป็นวิธีการที่เรียบง่ายในการสร้างเพจเลย์เอาท์ที่สารถนำกลับมาใช้ใหม่ได้ แถมสิ่งที่ดีที่สุดก็คือ Microsoft Visual Studio .NET  2005 ได้จัดเตรียมบริการออกแบบที่ทำงานได้อย่างครบถ้วนเอาไว้แล้ว เพื่อที่คุณจะได้มองเห็นว่าเพจของคุณจะมีหน้าตาอย่างไรหลังจากที่สร้างมันออกมาแล้ว
Filed under:
 

c said:

ขอบคุณสำหรับบทความดี ๆ

November 2, 2008 10:08 AM
 

cee said:

Thanks

November 2, 2008 10:08 AM
 

Kra said:

ขอบคุณมากครับ ^^

January 3, 2009 12:31 PM
 

nung said:

thankful

June 9, 2009 10:34 AM
 

ksaikool said:

ขอบคุณมากๆครับ

June 24, 2009 6:08 PM

Leave a Comment

(required)  
(optional)
(required)  
Add