Search code examples
razorasp.net-core-mvc-2.0

Accessing a 2D array in a Razor View


I'm attempting to create a booking form where the user can pick an hour slot. My idea is to create a ViewBag which will be a 2d array, which will contain a Booking object or a null reference. In the View I can then build a table using Razor. Each will contain the booking information if present or a DateTime in the event a null reference to the array is detected. Clicking on DateTime cells will use javascript to provide a DateTime value to the form which will supply the booking information.

My current problem is that I'm unable to access the array from within the view.

Any suggestions on a better approach would be much appreciated.

Here is what I have so far: The View:

@model Booking
<link rel="stylesheet" href="/Styles/Calendar.css"/>
<div>
    <form action="Book" method="POST">
        <div class="form-group">
            <label asp-for="User"></label>
            <input asp-for="User" class="form-control"/>
            <button type="submit">Submit</button>
        </div>
        <input asp-for="Slot" id="Slot" hidden="hidden"></p>
    </form>

    <table class="table table-bordered">
        <tr>
            <th></th>
            <th>Monday</th>
            <th>Tuesday</th>
            <th>Wednesday</th>
            <th>Thursday</th>
            <th>Friday</th>
            <th>Saturday</th>
            <th>Sunday</th>
        </tr>
        <tr>
            <th></th>
            @for(int day = 0; day < 7; day++){
                <th>@ViewBag.WkStart.AddDays(day).ToString("d")</th>                
            }
        </tr>
        @for(int x = 0; x < 12; x++){           
            <tr>
                <td>@ViewBag.WkStart.AddHours(x).ToString("h tt")</td>
                @for(int d = 0; d < 7; d++){
                    @if(ViewBag.Dairy[x,d] != null){
                        <td>ViewBag.Diary[x,d].User</td>
                    }
                    else{
                        <td  onclick="SelectDate(this)">ViewBag.WkStart.AddDays(d).AddHours(x)</td>
                    }
                }               
            </tr>
        }
    </table>


</div>

<script src="/Scripts/Calendar.js"></script>

The Controller:

public class BookingController : Controller{
    private IRepository repository;
    private Booking[,] weekBooking = new Booking[12,7];

    public BookingController(IRepository repo){
        repository = repo;
    }

    public ViewResult Calendar(){
        DateTime date = DateTime.Now.Date.AddHours(6);
        DateTime wkStart;
        switch(date.DayOfWeek){
            case DayOfWeek.Monday:
                wkStart = date;
                break;
            case DayOfWeek.Tuesday:
                wkStart = date.AddDays(-1);
                break;
            case DayOfWeek.Wednesday:
                wkStart = date.AddDays(-2);
                break;
            case DayOfWeek.Thursday:
                wkStart = date.AddDays(-3);
                break;
            case DayOfWeek.Friday:
                wkStart = date.AddDays(-4);
                break;
            case DayOfWeek.Saturday:
                wkStart = date.AddDays(-5);
                break;
            case DayOfWeek.Sunday:
                wkStart = date.AddDays(-6);
                break;
            default:
                wkStart = date;
                break;
        }
        ViewBag.WkStart = wkStart;

        /* test booking */
        Booking trial = new Booking {
            BookingID = 111,
            User = "Dan",
            Slot = DateTime.Now.Date.AddHours(12)
        };
        weekBooking[1,1] = trial;
        ViewBag.Diary = weekBooking;

        return View();
    }
}

Edit: Error message added.

The Error message:

An unhandled exception occurred while processing the request.
RuntimeBinderException: Cannot perform runtime binding on a null reference

CallSite.Target(Closure , CallSite , object , int , int )

    Stack Query Cookies Headers 

    RuntimeBinderException: Cannot perform runtime binding on a null reference
        CallSite.Target(Closure , CallSite , object , int , int )
        System.Dynamic.UpdateDelegates.UpdateAndExecute3<T0, T1, T2, TRet>(CallSite site, T0 arg0, T1 arg1, T2 arg2)
        AspNetCore._Views_Booking_Calendar_cshtml+<ExecuteAsync>d__15.MoveNext() in Calendar.cshtml

                        @if(ViewBag.Dairy[x,d] != null){

System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

Screenshot for a better view: ErrorScreenshot


Solution

  • Check your spelling. In your controller code you have ViewBag.Diary = weekBooking. In your view you spelled diary differently. (@if(ViewBag.Dairy[x,d] != null). Also you may want to consider using the null conditional operator to prevent exceptions. You can check for null and log that a null value was found versus getting the exception page.

    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators