代码之家  ›  专栏  ›  技术社区  ›  Shea Daniels

VB.NET中的Razor视图引擎怪癖

  •  22
  • Shea Daniels  · 技术社区  · 15 年前

    我刚刚下载了MVC 3.0rc,我很高兴开始使用它,特别是Razor视图引擎。但是,由于这里有一些墨守成规的人,我们只能使用VB.NET而不是C。

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

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

    剃刀会自动检测到 <li> 文本是一个HTML标记,将从“代码模式”切换。对于VB.NET VBHTML文件,这似乎不起作用。它让我把 @: 每行前面的关键字如下:

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

    如果我没有它,我会得到一个运行时错误。而且 <text></text> 标签似乎不起作用。

    有人知道这里发生了什么或者有没有解决办法?

    5 回复  |  直到 15 年前
        1
  •  16
  •   Buildstarted    15 年前

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

    Dim xmlMarkup = <someElement>Values</span>
    

    因此,vb的自然解析器的行为必须与c不同,因此必须告诉解析器使用 @ . 你可以用 @ @: .

        2
  •  4
  •   Jonathan    14 年前

    正如前面在注释中提到的,但没有显式显示;在文本标记前面加上@可以解决问题:

    @For Each genreName As String In Model.Genres
        @<text>
            <li>@genreName</li>
        </text>
    Next
    
        3
  •  2
  •   Eilon    15 年前

    我刚刚在一个VBHTML视图中的ASP.netmvc3rc中尝试了这个方法,它似乎工作得很好:

    <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>
    
        4
  •  1
  •   Carl Onager    11 年前

    这不使用与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时,需要在每一行前面加上 @: 或者用 @<text></text> 封锁。很明显,当您使用 @Code ... End Code 而不是用 @ .

    p、 注意 @<text></文本> 标记不会输出到页面,因此不会干扰任何内容

        5
  •  0
  •   Gabriele Petrioli    15 年前

    更新:

    您可以使用@li@genreName/li而不使用:因为您的HTML标记是自动关闭的,如果不是,那么您将需要使用@:但是您不需要,这在Gabe提供的链接中得到了澄清。也, @<text> 也会有用的!我不想让人们认为他们需要一直使用@:因为他们不需要,如果是这样的话,我会告诉Andrew nurse关于这个核心的:) 结束更新

    下面是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返回,这样就可以避免使用@:-hunt to ellon,我想他是在试图不必使用@: