tags:

views:

290

answers:

7

I'm trying to bind UI controls to a business object exposed as a property on an ASP.NET page in a null-safe manner.

Using the 'If' operator is null-safe, but results in compiler error:

Compiler Error Message: BC30201: Expression expected.

Using 'IIf' succeeds, but isn't null-safe. I've tried both the render expression syntax ('<%= %>') binding expression syntax ('<%# %>'), but there was no difference.

Can someone explain this inconsistency and perhaps provide an alternative?

Sample code:

This works: <%=IIf(Me.Foo Is Nothing, "", Me.Foo.Id)%>

This throws the compiler error: <%=If(Me.Foo Is Nothing, "", Me.Foo.Id)%>

+1  A: 

you have to do something like

<% if someCondition then %>
some html here
<% end if %>

no equals sign after the <%

Jason
A: 

When using IIf, both the "true" and the "false" expression are evaluated before calling IIf.

It is the same as calling this function:

Public Function MyIIf(ByVal test As Boolean, ByVal trueOption As Object, ByVal falseOption As Object) As Object
    If test Then Return trueOption Else Return falseOption
End Function

So before IIf is being called, Me.Foo.Id is being evaluated and throws an exception.

This is not the way that c#'s conditional (?:) operator works. Which is likely the source of confusion.

Ken Browning
A: 

VB.NET now includes a short-circuiting IF() operator. if the first operator isn't true, the second is NEVER evaluated. This is completely different from the way that IIF works, and the way that any custom function you might write works. It is, in fact, equivalent to C#'s ?: operator.

Documentation can be found here: IF operator on MSDN

Mike Hofer
I think Craig knows that (the way he puts it is that If() is null-safe). I think he wants to know why the compiler error occurs with If().
MarkJ
A: 

How about--

<% if foo.me isnot nothing then response.write(me.foo.id) %>

Beau Geste
+1  A: 

Are you using VB2008? The If() operator was not available in earlier versions of VB, which might explain your compiler error.

In earlier versions of VB, I would use Jason's answer.

<% if someCondition then %>
some html here
<% end if %>
MarkJ
+1  A: 

Okay, revisiting the question, I think we may be barking up the wrong tree with IF(). The answer probably lies in the error message:

Compiler Error Message: BC30201: Expression expected.

So, I built a sample app. Standard Visual Studio 2008 Web application. I created a class named Bar and added it to my app_code folder:

Imports Microsoft.VisualBasic

Public Class Bar
    Public Id As String
End Class

In the default.aspx page, I added the following to the code-behind file:

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Foo As New Bar()

End Class

Note that Foo is marked protected.

In the page, I added the following code:

<form id="form1" runat="server">
<div>
    <%=If(Me.Foo Is Nothing, "", Me.Foo.Id)%>
</div>
</form>

This works for me, and I get no errors whatsoever. If I then modify the code-behind as follows, I get the expected output ("Something" appears on a blank page):

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Foo As New Bar()

    Public Sub New()
        Foo.Id = "Something"
    End Sub

End Class

If this isn't working for you, then my suggestion to you is to verify that you are targeting the .NET 3.5 Framework. When I target .NET 2.0, I get "Expression Expected" on the IF() call. This error does not occur when targeting 3.5.

You can verify that you are targeting 3.5 through the Build tab on the properties for your Web application.

Mike Hofer
These are all good contributions to understanding the situation, but Mike's is the best single answer.My project is built in VS 2008, but targets .NET 2.0. The 'If' operator, while available in 2.0, indeed causes the compile error, while targeting 3.5 does not. Kudos to the VB team for another confusing inconsistency!The convenience of a binding expression in this case is compelling to me, and I found a workaround for my situation. Noting MarJ's comment, I'm using this:<%If Not Me.Foo Is Nothing Then Response.Write(Me.Foo.FooId)%>Thanks again, everyone, for your time and attention.
Craig Boland
A: 

I am having this same problem. I developed a site on a vista machine and the IF() syntax worked fine in all databinding expressions. Once I deployed it to a production box running server 2003, I started to get the compiler errors. I don't get what I could be doing wrong. Its set to compile to framework v3.5. The app pools are all set to run v2.0 as usual. Could this be an IIS6 vs IIS7 problem?

Jason