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 を贈ることにした。