Julia
Julia

Reputation: 83

VB syntax in razor view page

Here is my MVC View page VB code, that ViewData("Maximum exceed") is passed from controller. That is, if ViewData("Maximum exceed") is true, it will render a row with label control. Is there anything wrong with my VB syntax? How can I put VB condition in the View page?

@Using (Html.BeginForm())
@<table>  

     @If ViewData("IsMaximumExceed") Then
     <tr>
         <td colspan="3">
             @Html.Label(
                 Sub(settings)
                     settings.AssociatedControlName = "MaximumExceed"
                     settings.Text = "Maximum Exceed"                                                               
                 End Sub).GetHtml()
         </td>
     <tr>
</table>
End Using

Upvotes: 0

Views: 1717

Answers (2)

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

Since @Using (Html.BeginForm()) statement begins a form in "code block mode", in VB.NET context you need to set "text mode" either using @: (single line operator), @<text>...</text> (single or multiple line mode) or simply @ followed with HTML block element:

' Using @:
@Using (Html.BeginForm())
@:<table cellpadding="0" cellspacing="0" style="width: 800px; height:100px;">
    <!-- inner table -->
@:</table>
End Using

' Using @<text>...</text>
@Using (Html.BeginForm())
@<text><table cellpadding="0" cellspacing="0" style="width: 800px; height:100px;">
       <!-- inner table -->
 </table></text>
End Using

'Using @<tag>...</tag>
@Using (Html.BeginForm())
    @<table cellpadding="0" cellspacing="0" style="width: 800px; height:100px;">
           <!-- inner table -->
    </table>
End Using

The reason behind usage of operators to enclose HTML tags is that VB.NET allows inline XML elements by applying "text mode" inside "code block mode" which C# doesn't have that feature (see Razor syntax for VB.NET).

Hence, the provided sample in question should be modified like this, using @ before <tr> tag to create HTML block element under If code block:

@Using (Html.BeginForm())
@<table cellpadding="0" cellspacing="0" style="width: 800px; height:100px;">  
 @If ViewData("IsGroupVessel") Then
 @<tr>
      <td colspan="3">
      @Html.DevExpress().Label(Sub(settings)
            settings.AssociatedControlName = "GroupBooking"
            settings.Text = "Maximum Exceeded"                                                               
       End Sub).GetHtml()
      </td>
  </tr>
  End If
 </table>
End Using

As @Dai stated in his answer, I also prefers usage of a strongly-typed "view model" with properties instead passing ViewBag or ViewData, hence the modified code is shown below:

Model

Public Class ViewModel
   Public Property IsExceeded As Boolean
   ' other models
End Class

Controller

Public Function ActionMethod() As ActionResult
   Dim model As New ViewModel
   ' other logic
   model.IsExceeded = True
   ' other logic
   Return Me.View(model)
End Function

View

@ModelType ViewModel

@Using (Html.BeginForm())
@<table cellpadding="0" cellspacing="0" style="width: 800px; height:100px;">
 @If Model.IsExceeded Then
 @<tr>
      <td colspan="3">
      @Html.DevExpress().Label(Sub(settings)
          settings.AssociatedControlName = "GroupBooking"
          settings.Text = "Maximum Exceeded"                                                               
      End Sub).GetHtml()
      </td>
  </tr>
  End If
  </table>
End Using

Related issues:

Razor View Engine Quirks in VB.NET

Using in Razor VB.net MVC not work as expected

Upvotes: 1

Dai
Dai

Reputation: 155648

You have the arguments to Label(HtmlHelper, String, String) the wrong way around. The first string parameter is the expression, the second string parameter is the labelText.

Your If ViewData("Maximum exceed") checks to see if there's a dictionary member with key "Maximum exceed" but the expression value is "MaximumExceed" - they don't match.

That said, you should prefer a strongly-typed "view model" object instead of using the untyped ViewData or ViewBag objects.

Public Class MyPageViewModel

    Public MaximumExceeded As Boolean

End Class

...

Public Function MyControllerAction() As ActionResult 

    Dim viewModel As New MyPageViewModel
    viewModel.MaximumExceeded = True
    Return Me.View( viewModel )

End Sub

...

@Model MyPageViewModel

@If Model.MaximumExceeded Then

    @Html.Label( NameOf(Model.MaximumExceeded), "Maximum exceeded" )

End If

Note my use of the NameOf operator to get the string name of the property. Or better yet, use Html.LabelFor.

Upvotes: 1

Related Questions