自訂 ASP.NET Web Pages (Razor) 網站Site-Wide行為

作者:Tom FitzMacken

本文說明如何在 ASP.NET Web Pages (Razor) 網站中建立網頁的月臺端設定。

您將學到什麼:

  • 如何執行程式碼,讓您設定值 (全域值或協助程式設定,) 網站中的所有頁面。
  • 如何執行程式碼,讓您設定資料夾中所有頁面的值。
  • 如何在頁面載入前後執行程式碼。
  • 如何將錯誤傳送至中央錯誤頁面。
  • 如何將驗證新增至資料夾中的所有頁面。

教學課程中使用的軟體版本

  • ASP.NET Web Pages (Razor) 2
  • WebMatrix 3
  • ASP.NET Web Helpers 程式庫 (NuGet 套件)

本教學課程也適用于 ASP.NET Web Pages 3 和 Visual Studio 2013 (或 Visual Studio Express 2013 for Web) ,但您無法使用 ASP.NET Web 協助程式程式庫。

新增 ASP.NET Web Pages的網站啟動程式碼

對於您在 ASP.NET Web Pages中撰寫的大部分程式碼,個別頁面可以包含該頁面所需的所有程式碼。 例如,如果頁面傳送電子郵件訊息,就可以將該作業的所有程式碼放在單一頁面中。 這可以包含程式碼,以初始化傳送電子郵件 (的設定,也就是 SMTP 伺服器) 以及傳送電子郵件訊息。

不過,在某些情況下,您可能想要在月臺上的任何頁面執行之前執行一些程式碼。 這適用于設定可在網站中的任何位置使用的值, (稱為 全域值。) 例如,某些協助程式會要求您提供電子郵件設定或帳戶金鑰等值。 在全域值中保留這些設定很有用。

若要這樣做,您可以在網站的根目錄中建立名為 _AppStart.cshtml 的頁面。 如果此頁面存在,它會在第一次要求網站中的任何頁面時執行。 因此,執行程式碼來設定全域值是個不錯的位置。 (因為 _AppStart.cshtml 有底線前置詞,所以即使使用者直接要求頁面,ASP.NET 也不會將頁面傳送至瀏覽器。)

下圖顯示 _AppStart.cshtml 頁面的運作方式。 當某個頁面的要求傳入時,如果這是網站中任何頁面的第一個要求,ASP.NET 會先檢查 _AppStart.cshtml 頁面是否存在。 如果是, _AppStart.cshtml 頁面中的任何程式碼都會執行,然後要求的頁面就會執行。

[影像顯示 App Star dot CSHTML 的運作方式。]

設定網站的全域值

  1. 在 WebMatrix 網站的根資料夾中,建立名為 _AppStart.cshtml的檔案。 檔案必須位於網站的根目錄中。

  2. 以下列專案取代現有的內容:

    @{
      AppState["customAppName"] = "Application Name";
    }
    

    此程式碼會將值儲存在字典中 AppState ,此字典會自動提供給網站中的所有頁面使用。 請注意 ,_AppStart.cshtml 檔案中沒有任何標記。 頁面會執行程式碼,然後重新導向至原本要求的頁面。

    注意

    當您將程式碼放在 _AppStart.cshtml 檔案時,請小心。 如果在 _AppStart.cshtml 檔案的程式碼中發生任何錯誤,則網站將不會啟動。

  3. 在根資料夾中,建立名為 AppName.cshtml的新頁面。

  4. 以下列專案取代預設標記和程式碼:

    <!DOCTYPE html>
    <html>
        <head>
            <title>Show Application Name</title>
        </head>
        <body>
            <h1>@AppState["customAppName"]</h1>
        </body>
    </html>
    

    此程式碼會從 AppState 您在 _AppStart.cshtml 頁面中設定的物件擷取值。

  5. 在瀏覽器中執行 AppName.cshtml 頁面。 (執行頁面之前,請確定已在 [ 檔案 ] 工作區中選取頁面。) 頁面會顯示全域值。

    [顯示顯示全域值的頁面螢幕擷取畫面。

設定協助程式的值

_AppStart.cshtml檔案的一個好用是針對您在網站中使用的協助程式設定值,且這些值必須初始化。 典型的範例包括協助程式的電子郵件設定 WebMail ,以及協助程式的私人和公開金鑰 ReCaptcha 。 在這些情況下,您可以在 _AppStart.cshtml 中設定值一次,然後已針對網站中的所有頁面設定這些值。

此程式示範如何全域設定 WebMail 設定。 (如需使用 WebMail 協助程式的詳細資訊,請參閱將Email新增至 ASP.NET Web Pages Site.)

  1. 如果您尚未新增,請將 ASP.NET Web Helpers 程式庫新增至您的網站,如在ASP.NET Web Pages網站中安裝協助程式中所述。

  2. 如果您還沒有 _AppStart.cshtml 檔案,請在網站的根資料夾中建立名為 _AppStart.cshtml 的檔案。

  3. 將下列 WebMail 設定新增至 _AppStart.cshtml 檔案:

    @{
         // Initialize WebMail helper
         WebMail.SmtpServer = "your-SMTP-host";
         WebMail.SmtpPort = 25;
         WebMail.UserName = "your-user-name-here";
         WebMail.Password = "your-account-password";
         WebMail.From = "your-email-address-here";
    }
    

    修改程式碼中的下列電子郵件相關設定:

    • 設定 your-SMTP-host 為您有權存取的 SMTP 伺服器名稱。

    • 設定 your-user-name-here 為 SMTP 伺服器帳戶的使用者名稱。

    • 設定 your-account-password 為 SMTP 伺服器帳戶的密碼。

    • 設定 your-email-address-here 為您自己的電子郵件地址。 這是郵件從中傳送的電子郵件地址。 (某些電子郵件提供者不會讓您指定不同的 From 位址,並將您的使用者名稱作為 From address.)

      如需 SMTP 設定的詳細資訊,請參閱從 ASP.NET Web Pages (Razor) 網站傳送Email一文中的設定Email設定,以及ASP.NET Web Pages (Razor) 疑難排解指南傳送Email的問題

  4. 儲存 _AppStart.cshtml 檔案並加以關閉。

  5. 在網站的根資料夾中,建立名為 TestEmail.cshtml的新頁面。

  6. 以下列專案取代現有的內容:

    @{
        var message = "";
        try{
            if(IsPost){
                WebMail.Send(
                    to: Request.Form["emailAddress"],
                    subject: Request.Form["emailSubject"],
                    body:Request.Form["emailBody"]
               );
               message = "Email sent!";
            }
        }
        catch(Exception ex){
            message = "Email could not be sent!";
        }
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
         <meta charset="utf-8" />
         <title>Test Email</title>
      </head>
      <body>
        <h1>Test Email</h1>
        <form method="post">
          <p>
            <label for="emailAddress">Email address:</label>
            <input type="text" name="emailAddress" />
          </p>
          <p>
            <label for="emailSubject">Subject:</label>
            <input type="text" name="emailSubject" />
          </p>
          <p>
            <label for="emailBody">Text to send:</label><br/>
            <textarea name="emailBody" rows="6"></textarea>
          </p>
        <p><input type="submit" value="Send!" /></p>
        @if(IsPost){
            <p>@message</p>
        }
        </form>
      </body>
    </html>
    
  7. 在瀏覽器中執行 TestEmail.cshtml 頁面。

  8. 填寫欄位以傳送電子郵件訊息,然後按一下 [ 傳送]。

  9. 請檢查您的電子郵件,以確定您已收到訊息。

此範例的重要部分是您通常不會變更的設定,例如 SMTP 伺服器的名稱和電子郵件認證,是在 _AppStart.cshtml 檔案中設定。 如此一來,您就不需要在傳送電子郵件的每個頁面中再次設定它們。 (雖然基於某些原因而需要變更這些設定,您可以在 page.) 頁面中個別設定這些設定,但您只會設定一般每次變更的值,例如收件者和電子郵件訊息本文。

在資料夾中的檔案前後執行程式碼

就像您可以使用 _AppStart.cshtml 在網站執行中的頁面之前撰寫程式碼一樣,您可以撰寫在 (之前執行的程式碼,以及在) 特定資料夾執行中的任何頁面之後執行。 這適用于設定資料夾中所有頁面的相同版面配置頁面,或是在資料夾中執行頁面之前,先檢查使用者是否已登入。

對於特定資料夾中的頁面,您可以在名為 _PageStart.cshtml 的檔案中建立程式碼。 下圖顯示 _PageStart.cshtml 頁面的運作方式。 當要求傳入頁面時,ASP.NET 先檢查 _AppStart.cshtml 頁面,然後執行該頁面。 然後,ASP.NET 會檢查是否有 _PageStart.cshtml 頁面,如果是,則會執行該頁面。 然後,它會執行所要求的頁面。

_PageStart.cshtml 頁面中,您可以指定在處理期間,您希望要求的頁面執行的位置,方法是包含 RunPage 方法。 這可讓您在要求的頁面執行之前執行程式碼,然後在它之後再執行一次。 如果您沒有包含 RunPage則_PageStart.cshtml 中的所有程式碼都會執行,然後要求的頁面會自動執行。

[影像顯示要求的頁面如何自動執行。]

ASP.NET 可讓您建立 _PageStart.cshtml 檔案的階層。 您可以將 _PageStart.cshtml 檔案放在網站根目錄和任何子資料夾中。 要求頁面時,最上層 (最接近網站) 根目錄 (的 _PageStart.cshtml 檔案會執行,後面接著下一個子資料夾中 的 _PageStart.cshtml 檔案,直到要求到達包含要求頁面的資料夾為止。 執行所有適用的 _PageStart.cshtml 檔案之後,要求的頁面就會執行。

例如,您可能有下列_PageStart.cshtml 檔案和 Default.cshtml檔案的組合:

@* ~/_PageStart.cshtml *@
@{
  PageData["Color1"] = "Red";
  PageData["Color2"] = "Blue";
}
@* ~/myfolder/_PageStart.cshtml *@
@{
  PageData["Color2"] = "Yellow";
  PageData["Color3"] = "Green";
}
@* ~/myfolder/default.cshtml *@
@PageData["Color1"]
<br/>
@PageData["Color2"]
<br/>
@PageData["Color3"]

當您執行 /myfolder/default.cshtml時,您會看到下列內容:

Red

Yellow

Green

執行資料夾中所有頁面的初始化程式碼

_PageStart.cshtml檔案是針對單一資料夾中的所有檔案初始化相同的版面配置頁面。

  1. 在根資料夾中,建立名為 InitPages的新資料夾。

  2. 在網站的 InitPages 資料夾中,建立名為 _PageStart.cshtml 的檔案,並以下列專案取代預設標記和程式碼:

    @{
        // Sets the layout page for all pages in the folder.
        Layout = "~/Shared/_Layout1.cshtml";
    
        // Sets a variable available to all pages in the folder.
        PageData["MyBackground"] = "Yellow";
    }
    
  3. 在網站的根目錄中,建立名為 Shared的資料夾。

  4. [共用資料夾 ] 中,建立名為 _Layout1.cshtml 的檔案,並以下列專案取代預設標記和程式碼:

    @{
      var backgroundColor = PageData["MyBackground"];
    }
    <!DOCTYPE html>
    <html>
    <head>
      <title>Page Title</title>
      <link type="text/css" href="/Styles/Site.css" rel="stylesheet" />
    </head>
    <body>
      <div id="header">
        Using the _PageStart.cshtml file
      </div>
      <div id="main" style="background-color:@backgroundColor">
        @RenderBody()
      </div>
    <div id="footer">
      &copy; 2012 Contoso. All rights reserved
    </div>
    </body>
    </html>
    
  5. InitPages 資料夾中,建立名為 Content1.cshtml 的檔案,並以下列內容取代現有的內容:

    <p>This is content page 1.</p>
    
  6. InitPages 資料夾中,建立另一個名為 Content2.cshtml 的檔案,並以下列專案取代預設標記:

    <p>This is content page 2.</p>
    
  7. 在瀏覽器中執行 Content1.cshtml

    [影像顯示在瀏覽器中執行 Content 1 dot CSHTML。]

    Content1.cshtml 頁面執行時, _PageStart.cshtml 檔案會設定 Layout 並設定 PageData["MyBackground"] 為色彩。 在 Content1.cshtml中,會套用版面配置和色彩。

  8. 在瀏覽器中顯示 Content2.cshtml

    版面配置相同,因為兩個頁面都使用相同的版面配置頁面和色彩,如同 在 _PageStart.cshtml中初始化。

使用 _PageStart.cshtml 來處理錯誤

_PageStart.cshtml檔案的另一個好用是建立方法來處理常式設計錯誤, (資料夾中任何.cshtml頁面中可能發生的例外狀況) (例外狀況。 此範例示範執行此動作的其中一種方式。

  1. 在根資料夾中,建立名為 InitCatch的資料夾。

  2. 在網站的 InitCatch 資料夾中,建立名為 _PageStart.cshtml 的檔案,並以下列程式碼取代現有的標記和程式碼:

    @{
        try
        {
            RunPage();
        }
        catch (Exception ex)
        {
            Response.Redirect("~/Error.cshtml?source=" +
                HttpUtility.UrlEncode(Request.AppRelativeCurrentExecutionFilePath));
        }
    }
    

    在此程式碼中,您會嘗試在 區塊內 try 呼叫 RunPage 方法,明確地執行要求的頁面。 如果要求的頁面發生任何程式設計錯誤,區塊內的程式碼就會 catch 執行。 在此情況下,程式碼會重新導向至錯誤頁面 (Error.cshtml) ,並將發生錯誤的檔案名傳遞為 URL 的一部分。 (您很快就會建立頁面。)

  3. 在網站的 InitCatch 資料夾中,建立名為 Exception.cshtml 的檔案,並以下列程式碼取代現有的標記和程式碼:

    @{
        var db = Database.Open("invalidDatabaseFile");
    }
    

    針對此範例的目的,您在此頁面中執行的動作是嘗試開啟不存在的資料庫檔案,以刻意建立錯誤。

  4. 在根資料夾中,建立名為 Error.cshtml 的檔案,並以下列程式碼取代現有的標記和程式碼:

    <!DOCTYPE html>
    <html>
        <head>
            <title>Error Page</title>
        </head>
        <body>
    <h1>Error report</h1>
    <p>An error occurred while running the following file: @Request["source"]</p>
        </body>
    </html>
    

    在此頁面中,運算式 @Request["source"] 會從 URL 取得值,並加以顯示。

  5. 在工具列中,按一下 [ 儲存]。

  6. 在瀏覽器中執行 Exception.cshtml

    [顯示瀏覽器中執行例外狀況點 CSHTML 的螢幕擷取畫面。]

    因為 Exception.cshtml中發生錯誤, 所以 _PageStart.cshtml 頁面會重新導向至 Error.cshtml 檔案,以顯示訊息。

    如需例外狀況的詳細資訊,請參閱使用 Razor 語法 ASP.NET Web Pages程式設計簡介

使用 _PageStart.cshtml 限制資料夾存取

您也可以使用 _PageStart.cshtml 檔案來限制存取資料夾中的所有檔案。

  1. 在 WebMatrix 中,使用 [ 網站來源範本 ] 選項建立新的網站。

  2. 從可用的範本中,選取 [入門網站]。

  3. 在根資料夾中,建立名為 AuthenticatedContent的資料夾。

  4. AuthenticatedContent 資料夾中,建立名為 _PageStart.cshtml 的檔案,並以下列程式碼取代現有的標記和程式碼:

    @{
        Response.CacheControl = "no-cache";
        if (!WebSecurity.IsAuthenticated) {
            var returnUrl = "~/Account/Login?ReturnUrl=" + Request.Url.LocalPath;
            Response.Redirect(returnUrl);
        }
    }
    

    程式碼一開始會防止快取資料夾中的所有檔案。 (公用電腦這類案例需要這項功能,其中您不希望有一位使用者的快取頁面可供下一個使用者使用。) Next,程式碼會判斷使用者是否已登入網站,才能檢視資料夾中的任何頁面。 如果使用者未登入,程式碼會重新導向至登入頁面。 如果您包含名為 ReturnUrl 的查詢字串值,登入頁面可以將使用者傳回原本要求的頁面。

  5. 在名為Page.cshtmlAuthenticatedContent資料夾中建立新頁面。

  6. 以下列專案取代預設標記:

    @{
        Layout = "~/_SiteLayout.cshtml";
        Page.Title = "Authenticated Content";
    }
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
      </head>
      <body>
        Thank you for authenticating!
      </body>
    </html>
    
  7. 在瀏覽器中執行 Page.cshtml 。 程式碼會將您重新導向至登入頁面。 您必須先註冊,才能登入。 註冊並登入之後,您可以流覽至頁面並檢視其內容。

其他資源

使用 Razor 語法 ASP.NET Web Pages程式設計簡介