質問に対する私のコメント、
自分の開発環境(OS, .NET, IIS, Visual Studio のバージョンなど)は書けませんか?
に反応がないので、質問者さんの環境も私の環境とほぼ同じだろうと想像してレスしておきます。
link 要素は runat="server" を付けなくてもサーバーコントロールと同じ扱いになるようです。
そのことを書いた Microsoft の公式文書は見つけられていませんが、サーバーコントロールでしか使えないはずの ~ 演算子(ルート演算子)が href 属性に使えることなどがそれを裏付けていると思います。stackoverflow にもそのことについて述べている記事があります。
Inline code in head tag - ASP.NET
https://stackoverflow.com/questions/8104268/inline-code-in-head-tag-asp-net
そして、上に紹介した記事にも書いてありますが、href="xxxxxx ..." とすると、xxxxxx ... は文字列として認識され、その中にコードブロック <%= %>
を記述しても文字列の一部としてみなされるということのようです。(<%= %>
はレンダリングされる際に HtmlEncode, UrlEncode されますが)
質問者さんが試した「ダブルクォーテーションを2つ付加する」と何故コードブロック <%= %>
が認識されるのかのメカニズムは分かりませんが、想定外のことをして想定外の結果になったということではないかと思います。(思うだけで確証はありませんが)
で、解決策ですが、href="<%= ... %>" と書くとコードブロックだと認識するようで、例えば以下のようにすれば、【訂正】間違いでした。下の【訂正 2018/8/8 11:27】を見てください。
<link href="<%= "/Content/Site.css?" + strVal %>" rel="stylesheet" />
<link href="<%= ResolveUrl("~/Content/Site.css?") + strVal %>" rel="stylesheet" />
結果は以下のようになるはずです。
<link href="/Content/Site.css?012345" rel="stylesheet" />
<link href="/Content/Site.css?012345" rel="stylesheet" />
Windows 10, .NET 4.6.1, ローカル IIS10、Visual Studio Community 2015 で確認しました。質門者さんの環境で確認してみてください。
本題とは直接関係ないですが、データバインド式を使った場合でも似たようなことがあります。参考までにその関係の記事を紹介しておきます。
データバインド式
http://surferonwww.info/BlogEngine/post/2010/08/17/Data-bind-method.aspx
【訂正 2018/8/8 11:27】
上の回答で「href="<%= ... %>" と書くとコードブロックだと認識するようで」と書きましたが、そうではなくて、href="<%= ... %>"
中の ... でダブルクォートを使った影響でした。
例えば、コードビハインドで、
protected string cssPath = "/Content/Site.css?012345";
として、以下のようにすると、
<link href="<%= cssPath %>" rel="stylesheet" />
<%= cssPath %> は文字列と認識されダメです。以下のようにダブルクォートを使って空の文字列を入れると、
<link href="<%= "" + cssPath %>" rel="stylesheet" />
以下の通り望む結果が得られました。
<link href="/Content/Site.css?012345" rel="stylesheet" />
そのことは上に紹介した stackoverflow の記事にも書いてありました。ただ、strange だそうで、そのメカニズムは不明ですが。