ASP.NET Core – Razor Syntax

前言

Full stack 的问题就是经常需要一阵子离开一个环境. 比如我跑去写 Angular 几个月. 回来写 Razor, 肯定是卡卡的.

尤其是一些比较不常用到的语法. 所以有一个很好的笔记就很重要了. 以前我都懒的写, 但这半年我整理了很多, 也体会到这样做确实是很方便.

毕竟人家写的是教程, 但是我只是要复习丫, 自然看自己的笔记是最舒服.

这里记入一些我常用到的

 

参考

Docs – Razor syntax reference for ASP.NET Core

 

当想写 @ 时

@ 是特殊字符, 用来切换 to C#, 所以下面会报错

解决方法就是写 double @@

<h1>value @@ value</h1>

最后只会输出 1 个

另外, email 的 @ 不需要 double, 它有特别处理了.

<a href="mailto:support@stooges.com.my">support@stooges.com.my</a>

题外话: C# 的 quote "

C# 的 quote 也是类似的方式破解.

var value1 = "class="abc""; // 语法错误
var value2 = "class=\"abc\""; // 用反斜杠破
var value3 = @"class=""abc"""; // 用 @ + double "" 破

更多详情请参考: C# – 11.0

 

当在 C# 作用域想输出 HTML text

<text>

用 <text> 标签可以切换回 HTML 作用域, 但 <text> 是 Razor 特别的 tag 最终不会 render, 类似 <ng-container>

<h1>@if (true)
  {
    <text>Hello World</text>
  }
  else
  {
    <text>Derrick</text>
  }</h1>

上面这个只是作为一个例子, 更好的写法是

<h1>@(true ? "Hello World" : "Derrick")</h1>

@:

还有这种写法

<h1>@if (true)
  {
    @:my text
  }
</h1>

 

Conditional Attribute

参考: Stack Overflow – ASP.NET MVC razor: conditional attribute in HTML [duplicate]

<div class="@null">Content</div>

当 class = null 那最终 class 完全不会出现。

注:如果是 empty string 会变成 <div class>,class 会出现,虽然不影响解析,但看上去怪怪的。所以最好使用 null。

但是如果 attribute 是 data-,那 null 和 empty string 是一样的。

参考: Stack Overflow – Razor conditional attribute not working

<div class="@null" data-message="@null">Content</div>
之后
<div data-message>Content</div>

拼接也容易

@{
    var classValue = "c1 c2";
}
<div class="@(true ? $"{classValue} extra" : null)">Content</div>

for attribute data- 可以这样

<div @(true ? "data-whatever=SomeValue" : null)></div>
<div @(true ? $"data-whatever={"SomeValue"}" : null)></div>

第一个 =SomeValue 不需要 quote 挺神奇的呢。

另外 SomeValue 不可以有空格哦,有的话会 break 掉。。

所以推荐使用 raw(注:要 HTML encode 哦)

@{
  var datas = new Dictionary<string, string> {
    { "key1", "<div>\"Hello World\"</div>" },
    { "key2", "value2" },
  };
  
  string appendDatas(Dictionary<string, string> datas) {
    List<string> dataKeyValues = new List<string>();
    foreach(var (key, value) in datas)
    {
       dataKeyValues.Add($"data-{key}=\"{WebUtility.HtmlEncode(value)}\"");
    }
    return string.Join(" ", dataKeyValues);
  }

  <h1 @(Html.Raw(appendDatas(datas)))></h1>
} 
<script>
  const h1 = document.querySelector('h1');
  const dataAttributes = Array.from(h1.attributes).filter(a => a.name.startsWith('data-'));
  for (const { name, value } of dataAttributes) {
    console.log([name, value]);
  }
</script>

results

for style 的 example

参考: Stack Overflow – Conditional Formatting in a Razor Index View

拼接可以

@{
  string? style = null;
}
<button style="color: white; @style">play</button>

 

@namespace

参考: Docs – @namespace

在 _ViewImports.cshtml 里面有一个 @namespace

@namespace Hello.World
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

之后所有的 view 都会依据 folder 给予 namespace

我踩过一个坑. 在一个 view 中想引入我的 Library Stooges

但我的 folder 结果里也有一个同名的 Stooges

于是就 error 了. 解决方法是避开这种撞名字的情况. 不建议去修改 @namespace 的逻辑.

 

当 for loop 拼接 <span> 时小心 new line 制造出来的 space

之前有提过 HTML 的特性 当 inline element 遇上 new line 会制造出 space

当我们写这样时

<p>
  @{
    var values = new List<string> { "abc", "xyz", "123" };
    foreach (var value in values)
    {
      <span>@value</span>
    }
  }
</p>

出来的结果是

<p>
  <span>abc</span>
  <span>xyz</span>
  <span>123</span>
</p>

它就会有空格, 像这样:

如果不希望有 new line 那么可以这样写

@{
  var values = new List<string> { "abc", "xyz", "123" };
  foreach (var value in values)
  {<span>@value</span>}
}

或者 wrap 多一层 parenthese

foreach (var value in values)
{
  {<span>@value</span>}
}

效果

注: 这些写法很可能会被 auto format 修正哦.

 

Disable Element Tag Helper

参考: Stack Overflow – The tag helper 'input' must not have C# in the element's attribute declaration area

有些 element 有默认的 Tag Helper, 比如 option

 

 

 一旦有 Tag Helper, 那么就不可以使用 C# 语法, 会报错.

我们可以在 element 前面加叹号来 disable 这个 default 设置

<!option value="@customerAction.ToString()" @(true ? "selected" : "") >@customerAction.ToDisplay()</!option>

这样就可以使用 C# 语法了

 

posted @ 2022-05-21 17:58  兴杰  阅读(112)  评论(0)    收藏  举报