2

I have some Razor code that has conditional logic based on whether a certain array variable is set. I'm having a heck of a time figuring out the best way to handle when it's null and I'm not happy with my kludgy solution.

Here's a simple example of what's happening:

@{
    if (ViewBag.Foo != null)
    {
        double[] bar = new double[ViewBag.Foo.Length];
    }
}

Later on in the code, I'll have something like this:

@if (ViewBag.Foo != null)
{
    ...some code that uses `bar` goes here ...
}

With that code, I get errors when ViewBag.Foo actually is null. I get an exception thrown complaining about the second section of code that uses bar and it not being in scope . However, in the execution, that second section will always be skipped.

After messing with it for awhile, I just did this instead:

double[] bar;
@{
    if (ViewBag.Foo != null)
    {
        bar = new double[ViewBag.Foo.Length];
    }
}
else
{
    bar = new double[1];
}

With this change, the code works when ViewBag.Foo is null and non-null. There's gotta be a better way to handle this... anyone?

TMC
  • 8,088
  • 12
  • 53
  • 72
  • It seems to me that in your case ViewBag.Foo actually doesn't exist (since it's a dynamic type your code runs fine.) Does ViewBag.Foo exist? if not, read: http://stackoverflow.com/questions/2634858/how-do-i-reflect-over-the-members-of-dynamic-object – Polity Oct 24 '11 at 05:40
  • I mean... this is precisely the reason why you're suppose to avoid dynamic languages in the first place. Have you considered making a custom view, with a definite model? – cwharris Oct 24 '11 at 06:01

2 Answers2

4

This sort of work does not belong in a view:

@{
    if (ViewBag.Foo != null)
    {
        double[] bar = new double[ViewBag.Foo.Length];
    }
}

The sort of problem you had is exactly why this is the case. Your problem came down to the fact that bar was not correctly scoped. If instead this work was happing within a ViewModel, a similar mistake would have immediately given you a compiler error. Instead you don't find out until you compile and use the application, and the error you are given can often be cryptic and difficult to track down.

Dan Turner
  • 2,233
  • 18
  • 19
  • what's the better approach for this code? Should it be in the controller instead? – TMC Oct 24 '11 at 17:54
  • Talking in Foo's and Bar's its really hard for me to give you a definite answer. Ultimately it comes down to how complicated the massaging is that you're doing. If it's really simple you could do the in the constructor of the ViewModel or possibly the controller. Personally though, what I usually do is have a ViewModel for each View in the application. This view model is simply a POCO with a property per field in the view. I then have a ModelFactory per ViewModel that does the work of fetching required data and setting appropriate properties. This is where I would be doing stuff that. – Dan Turner Oct 26 '11 at 06:47
0

You solved your own problem.

The bar variable was not in scope because you declared it within an if block. Your change broadened it.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123