【问题标题】:Razor View Engine Quirks in VB.NETVB.NET 中的 Razor 视图引擎怪癖
【发布时间】:2010-11-12 21:46:15
【问题描述】:

我刚刚下载了 MVC 3.0 RC,我很高兴开始使用它,尤其是 Razor 视图引擎。但是,由于这里有一些陷入泥潭的人,我们被困在使用 VB.NET 而不是 C#。

当我开始尝试它时,我注意到了一些怪癖。如果您使用 CSHTML 创建 Razor 视图,您可以编写如下代码:

@foreach(string genreName in Model.Genres)
{
    <li>@genreName</li>
}

Razor 会自动检测到&lt;li&gt; 文本是 HTML 标记,并会退出“代码模式”。对于 VB.NET VBHTML 文件,这似乎不起作用。这让我将@: 关键字放在每一行的前面,如下所示:

@For Each genreName As String In Model.Genres
    @:<li>@genreName</li>
Next

如果我没有它,我会收到运行时错误。此外,&lt;text&gt;&lt;/text&gt; 标签似乎不起作用。

有人知道这里发生了什么或是否有解决方法?

【问题讨论】:

  • 你用的是&lt;text&gt;还是@&lt;text&gt;
  • 我没有尝试@。感谢您的链接。
  • 您可以使用 @
  • @genreName
  • 而不使用 : 因为您的 HTML 标签是自关闭的,如果它们不是,那么您需要使用 @: 但您不需要,这在 Gabe 提供的链接中得到了澄清。此外,@ 也可以使用!我讨厌人们认为他们需要一直使用 @: 因为他们不需要,如果是这样的话,我会向安德鲁护士讲述这个铁杆 :)
  • 是的,这些都有效,但我的意思是,在 C# 模板中,您不需要 HTML 元素前面的“@”字符。对我来说,这使它们更加优雅和易于阅读。
  • 标签: asp.net-mvc vb.net visual-studio-2010 razor


    【解决方案1】:

    我会说在 Vb.net 中需要它的原因是 vb 允许内联 xml 元素而 c# 不允许。

    Dim xmlMarkup = <someElement>Values</span>
    

    因此,vb 的自然解析器的行为必须与 c# 不同,因此您必须使用 @ 告诉解析器转义回 html。您可以使用@@:

    【讨论】:

    • 这似乎可以解释它。我想这是可以理解的,但它使 VB 模板不如 C# 模板那么优雅。哦,好吧。
    • @SheaDaniels 非常正确 - 有多少人使用 XML Literals?没有什么比破坏新的语言功能来支持未使用的旧功能更重要的了
    • 这太荒谬了...... 2 年后,我仍然把 @: 放在 Html 的每一行
    • 我认为这不会改变,@ScottSelby。 vb的xml特性不会很快消失。
    【解决方案2】:

    如之前在 cmets 中提到的,但没有明确显示;在文本标签前加上 @ 解决了这个问题:

    @For Each genreName As String In Model.Genres
        @<text>
            <li>@genreName</li>
        </text>
    Next
    

    【讨论】:

      【解决方案3】:

      我刚刚在 ASP.NET MVC 3 RC 的 VBHTML 视图中尝试过这个,它似乎工作正常:

      <ul>
      @For Each i As Integer In Enumerable.Range(0, 5)
          @:<li>@i</li>
      Next
      </ul>
      

      它呈现这个标记:

      <ul>
          <li>0</li>
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
      </ul>
      

      【讨论】:

      • 我在我的问题中发布了这个工作。我遇到的问题是,在 C# 模板中,解析足够智能,可以识别没有“@:”的“
      • ”标签。至少在我看来,这使得 C# 模板更加优雅和可读。
    • 您可以使用 @
    • @genreName
    • 而不使用 : 因为您的 HTML 标签是自关闭的,如果它们不是,那么您需要使用 @: 但您不需要,这在 Gabe 提供的链接中得到了澄清。此外,@ 也可以使用!我讨厌人们认为他们需要一直使用 @: 因为他们不需要,如果是这样的话,我会向安德鲁护士讲述这个铁杆 :)
      【解决方案4】:

      这不使用与 OP 相同的代码,但我将一些 C# 代码从 MVC 书籍转换为 VB.NET,并且被混合内联 HTML 和 VB 代码卡住了。这是原来的 C#:

      @using (Html.BeginForm()) {
          @Html.ValidationSummary()
              <p>Your name: @Html.TextBoxFor(x => x.Name, new { @class = "form-control" }) </p>
              <p>Your email: @Html.TextBoxFor(x => x.Email, new { @class = "form-control" }) </p>
              <p>Your phone: @Html.TextBoxFor(x => x.Phone, new { @class = "form-control" }) </p>
              <p>Will you attend?
              @Html.DropDownListFor(x => x.WillAttend, new[] {
                      new SelectListItem() {Text = "Yes, I'll be there",
                          Value = bool.TrueString},
                      new SelectListItem() {Text = "No, I can't come",
                          Value = bool.FalseString}
                  }, "Choose an option", new { @class = "form-control" })
              </p>
      }
      

      这些是在 VB 中表示它的不同方式:

      @Using Html.BeginForm()
          @:<p>Your name: @Html.TextBoxFor(Function(x) x.Name)</p>
          @:<p>Your email: @Html.TextBoxFor(Function(x) x.Email)</p>
          @:<p>Your phone: @Html.TextBoxFor(Function(x) x.Phone)</p>
          @:<p>Will you attend?
          @Html.DropDownListFor(Function(x) x.WillAttend, New SelectListItem() {New SelectListItem() With {.Text = "Yes", .Value = Boolean.TrueString}, New SelectListItem() With {.Text = "No", .Value = Boolean.FalseString}})
          @:</p>
      End Using
      
      @Using Html.BeginForm()
          @<text>
              <p>Your name: @Html.TextBoxFor(Function(x) x.Name)</p>
              <p>Your email: @Html.TextBoxFor(Function(x) x.Email)</p>
              <p>Your phone: @Html.TextBoxFor(Function(x) x.Phone)</p>
              <p>Will you attend?
              @Html.DropDownListFor(Function(x) x.WillAttend, New SelectListItem() {New SelectListItem() With {.Text = "Yes", .Value = Boolean.TrueString}, New SelectListItem() With {.Text = "No", .Value = Boolean.FalseString}})
              </p>
          </text>
      End Using
      
      @code
          Using Html.BeginForm()
              @:<p>Your name: @Html.TextBoxFor(Function(x) x.Name)</p>
              @:<p>Your email: @Html.TextBoxFor(Function(x) x.Email)</p>
              @:<p>Your phone: @Html.TextBoxFor(Function(x) x.Phone)</p>
              @:<p>Will you attend?
              @Html.DropDownListFor(Function(x) x.WillAttend, New SelectListItem() {New SelectListItem() With {.Text = "Yes", .Value = Boolean.TrueString}, New SelectListItem() With {.Text = "No", .Value = Boolean.FalseString}})
              @:</p>
          End Using
      End Code
      
      @code    
          Using Html.BeginForm()
              @<text>
                  <p>Your name: @Html.TextBoxFor(Function(x) x.Name)</p>
                  <p>Your email: @Html.TextBoxFor(Function(x) x.Email)</p>
                  <p>Your phone: @Html.TextBoxFor(Function(x) x.Phone)</p>
                  <p>Will you attend?
                  @Html.DropDownListFor(Function(x) x.WillAttend, New SelectListItem() {New SelectListItem() With {.Text = "Yes", .Value = Boolean.TrueString}, New SelectListItem() With {.Text = "No", .Value = Boolean.FalseString}})
                  </p>
              </text>
          End Using
      End Code
      

      从中显而易见的是,当您需要在代码块中包含内联 HTML 时,您需要在每行前面加上 @: 前缀,或者在 HTML 后面加上 @&lt;text&gt;&lt;/text&gt; 块。很明显,当您使用 @Code ... End Code 而不是使用 @ 开始代码块时,这也适用。

      附言请注意,@&lt;text&gt;&lt;/text&gt; 标签不会输出到页面,因此它们不会干扰任何内容

      【讨论】:

        【解决方案5】:

        更新:

        您可以使用 @li@genreName/li 而不使用 : 因为您的 HTML 标签是自关闭的,如果它们不是,那么您需要使用 @: 但您不需要,这在 Gabe 提供的链接中得到了澄清.此外,@&lt;text&gt; 也可以使用!我讨厌人们认为他们需要一直使用@:因为他们不需要,如果是这样的话,我会向安德鲁护士讲述这个铁杆:) 结束更新

        这是vb razor的基本语法,

        @字符开始内联表达式、单语句块和多语句块:

        ?
        <!-- Single statement blocks  -->
        
        @Code  Dim total = 7  End Code
        
        @Code  Dim myMessage = "Hello World" End Code
        
         
        <!-- Inline expressions -->
        <p>The value of your account is: @total </p>
        
        <p>The value of myMessage is: @myMessage</p>
        
                
             
        <!-- Multi-statement block -->
        
        @Code
        
            Dim greeting = "Welcome to our site!"
        
            Dim weekDay = DateTime.Now.DayOfWeek
        
            Dim greetingMessage = greeting & " Today is: " & weekDay.ToString()
        
        End Code
        
        <p>The greeting is: @greetingMessage</p>
        

        所以它应该可以工作,只需在每一行的末尾关闭代码模式,然后在 HTML 中返回,这样可以避免你使用 @: - 寻找 ellon,我认为他试图不必使用 @ :

        【讨论】:

        • 从上面链接的 url 直接复制并粘贴到他的 cmets 中而不回答他的问题...
        • 我最后回答了他的问题。我也复制粘贴,因为答案就在那里,没有人向他指出这一点,我还认为他没有阅读链接,因为链接回答了他的问题,每个人都忽略了它,所以指出这一点很重要。另外我正在回答他不想做的问题@:因为它看起来很讨厌。 Isjob:这是否澄清了您对我的帖子的担忧?
        • 除了批评那些只是想帮忙的人之外,你真的没有别的事可做吗?我没有看到你对他的问题做出任何贡献。
        • 您刚刚说他的代码应该可以工作,并且发布的示例甚至不包括相关的 html 示例,只是链接页面中的前几个示例。这些示例与转义回 html 无关。这就是我对你的回答的担忧。当其他人似乎已经充分回答了这个问题时,我不会做出贡献。最后,每个答案都说“它应该起作用”而不是“为什么”。哪一个人试图做...如果他是对的,我不知道,但我也想知道答案 - 不过你的答案不是。
        • 我已经向他展示了,如果他使用@code,然后在最后使用 End Code,他不需要退出 HTML,这比使用 @: 更麻烦: - 我仍然没有'不明白为什么你认为我没有回答这个问题。结束代码后,您几乎回到了 HTML 模式!我想我不能说得更清楚了。
        猜你喜欢
        相关资源
        最近更新 更多
        热门标签