だるろぐ

明日できることは、今日しない。

WebMatrix 3: @ でハマる(解決編

f:id:daruyanagi:20130929122557p:plain

WebMatrix 3: @ でハマる - だるろぐ の続き。

というアドバイスをもらった。あ、たぶんそれだ。というわけで書き直した。

旧バージョン(Logger.cshtml)

#App_Code/Logger.cshtml

@helper Write(string message)
{
    System.IO.File.AppendAllText(
        Server.MapPath("~/log.txt"),
        string.Format("{0}:\t{1}\r\n", DateTime.Now, message)
    );
}

これって実は public static HelperResult Write(string message) になるんだよね。それにしてもなぜ AppendAllText() が実行されないのかは謎だけど、HTML が含まれていない(出力がない)ならば処理を飛ばしてしまう最適化なんかがあるのかもしれない。とりあえず“Page に対してなんら出力のないヘルパー”という使い方は NG ってことかな。

新バージョン(Logger.cs)

f:id:daruyanagi:20131001075835p:plain

#App_Code/Logger.cs

using System;

public static class Logger
{
    public static void Write(string message)
    {
        System.IO.File.AppendAllText(
            System.Web.Hosting.HostingEnvironment.MapPath("~/log.txt"),
            string.Format("{0}:\t{1}\r\n", DateTime.Now, message)
        );
    }
}

CSHTML → CS にして、コードを Razor ではなく C# で書き直す。“HostingEnvironment.MapPath(String) Method (System.Web.Hosting) | Microsoft Docs”は最近覚えたのだけど、Server.MapPath() が使えない場面でも動く(のだと期待している)。

f:id:daruyanagi:20131001080145p:plain

結果は――期待通りログが出力される。けれど、Default.cshtml も少し書き直さなければならない。

旧バージョン(Default.cshtml)

@{
     @Logger.Write("冒頭のコードブロック内で記述");
}

<!DOCTYPE html>

<html lang="ja">
    <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta charset="utf-8" />
        <title>マイ サイトのタイトル</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    </head>
    <body>
        @Logger.Write("Body 内で記述")
    </body>
</html>

新バージョン(Default.cshtml)

@{
     Logger.Write("冒頭のコードブロック内で記述");
}

<!DOCTYPE html>

<html lang="ja">
    <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta charset="utf-8" />
        <title>マイ サイトのタイトル</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    </head>
    <body>
        @{ Logger.Write("Body 内で記述"); }
    </body>
</html>

Logger.Write が HelperResult を返さなくなったことにより(ヘルパーメソッドとしてシグネチャーが合わなくなったので)、@Logger.Write() という書き方はできなくなり、コードブロックで囲まなければならなくなった。けど、これが正しい。

そういえば

をあんまり理解していないことを思い出したので、これも今度解決しておくことにする。

追記

この功を表して、しばやんにはもう一枚 CD を贈ることにした。