Home > front end >  Unable to save form details in razor page as demonstrated in Pluralsight Fundamentals course
Unable to save form details in razor page as demonstrated in Pluralsight Fundamentals course

Time:10-20

I have been following the ASP.NET Core Fundamentals course of Pluralsight by Scott Allen, and have been working through it with my own program I am creating for a project. So far my code is very similar to in the video except I am using my own class object instead of the restaurant class in the examples.

The problem I am having is in the Model Binding video in the 4th module of the course. When I run the program and edit one of the Meeting Space objects in the browser it saves an empty/null object instead of using the inputs in the form. My unit tests for the MeetingSpaceData class, which contains the Update method, works as intended which leads me to believe I have made a mistake in the Edit razor page which is responsible for these edits.

Edit: The MeetingSpace object received and used in the Update method (called in Edit.cshtml.cs) is a default MeetingSpace. So the issue is that the input form is not used to edit the newly created object.

Below are some of the relevant. Let me know if any more details are required. I am a fairly inexperienced programmer and am new to using ASP.NET, so apologies if anything is unclear.

MeetingSpaceData Class

public class InMemoryMeetingSpaceData : IMeetingSpaceData
{
    public List<MeetingSpace> meetingSpaces;

    public InMemoryMeetingSpaceData()
    {
        meetingSpaces = new List<MeetingSpace>()
        {
            new MeetingSpace { Id = 1, Name = "Meeting Room  1", Location = "The Building", Capacity = 8},
            new MeetingSpace { Id = 2, Name = "Meeting Room 2", Location = "The Building", Capacity = 4},
            new MeetingSpace { Id = 3, Name = "Meeting Room 3", Location = "The Building", Capacity = 6},
            new MeetingSpace { Id = 4, Name = "Meeting Room 4", Location = "The Building", Capacity = 8},
            new MeetingSpace { Id = 5, Name = "Meeting Room 1", Location = "Second Building", Capacity = 7}
        };
    }

    public MeetingSpace Add(MeetingSpace newMeetingSpace)
    {
        if (newMeetingSpace != null)
        {
            meetingSpaces.Add(newMeetingSpace);
            newMeetingSpace.Id = meetingSpaces.Max(m => m.Id)   1;
        }
        return newMeetingSpace;
    }

    public IEnumerable<MeetingSpace> GetAll()
    {
        return from m in meetingSpaces
               orderby m.Name
               select m;
    }

    public MeetingSpace Update(MeetingSpace updatedMeetingSpace)
    {
        var meetingSpace = meetingSpaces.SingleOrDefault(m => m.Id == updatedMeetingSpace.Id);
        if (meetingSpace != null)
        {
            meetingSpace.Name = updatedMeetingSpace.Name;
            meetingSpace.Location = updatedMeetingSpace.Location;
            meetingSpace.Capacity = updatedMeetingSpace.Capacity;
        }
        return meetingSpace;
    }

    public int Commit()
    {
        return 0;
    }

    public MeetingSpace GetById(int id)
    {
        return meetingSpaces.SingleOrDefault(m => m.Id == id);
    }

}

}

Edit.cshtml

@page "{meetingSpaceId:int}"
@model BookingApp.Pages.MeetingSpaces.EditModel
@{
    ViewData["Title"] = "Edit";
}

<h2>Editing @Model.MeetingSpace.Name</h2>

<form method="post">
    <input type="hidden" asp-for="MeetingSpace.Id" />
    <div class="form-group">
        <label asp-for="MeetingSpace.Name"></label>
        <input asp-for="MeetingSpace.Name" class="form-control" />
        <span class="text-danger" asp-validation-for="MeetingSpace.Name"></span>
    </div>
    <div class="form-group">
        <label asp-for="MeetingSpace.Location"></label>
        <input asp-for="MeetingSpace.Location" class="form-control" />
        <span class="text-danger" asp-validation-for="MeetingSpace.Location"></span>
    </div>
    <div class="form-group">
        <label asp-for="MeetingSpace.Capacity"></label>
        <input asp-for="MeetingSpace.Capacity" class="form-control" />
        <span class="text-danger" asp-validation-for="MeetingSpace.Capacity"></span>
    </div>

    <button type="submit" class="btn btn-primary">Save</button>
</form>

Edit.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BookingApp.Core;
using BookingApp.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace BookingApp.Pages.MeetingSpaces
{
    public class EditModel : PageModel
    {
        private readonly IMeetingSpaceData meetingSpaceData;

        [BindProperty]
        public MeetingSpace MeetingSpace { get; set; }

        public EditModel(IMeetingSpaceData meetingSpaceData)
        {
            this.meetingSpaceData = meetingSpaceData;
        }

        public IActionResult OnGet(int meetingSpaceId)
        {
            MeetingSpace = meetingSpaceData.GetById(meetingSpaceId);
            if (MeetingSpace == null)
            {
                return RedirectToPage("./NotFound");
            }
            return Page();
        }

        public IActionResult OnPost()
        {
            MeetingSpace = meetingSpaceData.Update(MeetingSpace);
            meetingSpaceData.Commit();
            return Page();
        }
    }
}

MeetingSpace.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BookingApp.Core
{
    public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
    {
        //private static int classCount = 3;          //TODO: Change to 0 default when database implemented
        public string Name;
        public string Location;
        public int Capacity;

        public override void EditDetails()
        {
            throw new NotImplementedException();
        }

        public bool Equals(MeetingSpace other)
        {
            if (Name == other.Name
                && Location == other.Location
                && Capacity == other.Capacity)
            { 
                return true; 
            }
            else 
            { 
                return false; 
            }
        }

        public override int GenerateNewId()
        {
            throw new NotImplementedException();
        }

        public override void GetAll()
        {
            throw new NotImplementedException();
        }
    }
}

BookingEntityBase.cs The MeetingSpace inherits the id field from this class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BookingApp.Core
{
    public abstract class BookingEntityBase
    {
        public int Id { get; set; }

    }
}

CodePudding user response:

I tested your code and was able to fix the issue by modifying your MeetingSpace class. It contains fields and not properties and i think that's why it's messing up the databinding.

So change this :

public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
    public string Name;
    public string Location;
    public int Capacity;
    ...

To this :

public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
    public string Name { get; set; }
    public string Location { get; set; }
    public int Capacity { get; set; }
    ...

And the databinding should be working properly.

  • Related