Click here to Skip to main content
15,884,633 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Right now I am successfully passing my data from the View to the Controller. My Controller is connected to two Views. One of which is the one i want to use for my user input and second one where i Display the user input in a table.

What I have tried:

So here is my Controller. It is connected to the Views "Index"(my table-html) and "Create" (for user input). The Index()-Method is me initalizing the table with a few objects.
    public class BookingController : Controller
    {
        List<BookingModel> bookings = new List<BookingModel>();
        

        public IActionResult Index()
        {

            BookingModel model1 = new BookingModel 
            {
                ladestand = 10,
                fahrstrecke = 100,
                startzeit = new DateTime(2020, 10, 2, 8, 45, 0),
                endzeit = new DateTime(2020, 10, 2, 12, 45, 0)
            };
            BookingModel model2 = new BookingModel
            {
                ladestand = 65,
                fahrstrecke = 340,
                startzeit = new DateTime(2020, 05, 3, 9, 45, 0),
                endzeit = new DateTime(2020, 05, 3, 11, 45, 0)
            };
            BookingModel model3 = new BookingModel
            {
                ladestand = 30,
                fahrstrecke = 150,
                startzeit = new DateTime(2020, 09, 15, 22, 45, 0),
                endzeit = new DateTime(2020, 09, 16, 0, 00, 0)
            };
            bookings.Add(model1);
            bookings.Add(model2);
            bookings.Add(model2);

            return View(bookings);
        }

        [HttpGet]
        public IActionResult Create() 
        {
            return View(new BookingModel());
        }

        [HttpPost]
        public IActionResult Create(BookingModel model) 
        {
            bookings.Add(model);
            return View();
        }
    }

}


The following code is my "Create" View. The data is being passed successfully back to the Controller.
@model SoPro3NEU.Models.BookingModel
@{
    ViewData["Title"] = "Create";
}

<h1 class="align-middle" style="margin-bottom: 20px">Create</h1>


@using (Html.BeginForm())
{

    @Html.TextBoxFor(model => model.ladestand)
    @Html.ValidationMessageFor(model => model.ladestand)
    <p>Ladestand</p>

    @Html.TextBoxFor(model => model.fahrstrecke)
    @Html.ValidationMessageFor(model => model.fahrstrecke)
    <p>Fahrstrecke</p>

    @Html.TextBoxFor(model => model.startzeit)
    @Html.ValidationMessageFor(model => model.startzeit)
    <p>Startzeit</p>

    @Html.TextBoxFor(model => model.endzeit)
    @Html.ValidationMessageFor(model => model.endzeit)
    <p>Endzeit</p>

    <br>
    <button type="submit">Add Booking to list</button>
}


This is my "Index" View. It displays the table properly:
@model List<SoPro3NEU.Models.BookingModel>
@{
    Layout = "_Layout";
}



<h1 class="display-4 text-center font-weight-bold">Bookings</h1>
<table class="table table-borderless table-hover table-striped">
    <tr>
        <th>Ladestand</th>
        <th>Fahrstrecke</th>
        <th>Startzeit</th>
        <th>Endzeit</th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <th>@item.ladestand</th>
            <th>@item.fahrstrecke</th>
            <th>@item.startzeit</th>
            <th>@item.endzeit</th>
        </tr>
    }
</table>

<a class="nav-link text-dark" asp-area="" asp-controller="Booking" asp-action="Create">Create a new Booking</a>


Now how do i get the user input from that first View as a table item into the second one ?
Posted
Updated 11-May-20 8:17am

1 solution

Every time you make a request, a new instance of your controller is created. It processes the request and generates a response, and then that instance is thrown away, along with all of its fields.

The item you add to the bookings field in your POST method doesn't survive beyond that single request.

The data needs to be persisted in a database, or some other storage mechanism. For a "toy" application, with no real-world use intended, you might be able to get away with making the list static. But you will need to be very careful to manage access from multiple threads.

Once you've added the booking to your persistent storage, redirect the user back to the Index action to display the updated list.

You'll probably want to use some sort of repository pattern to make it easier to switch the storage mechanism later:
C#
public interface IBookingRepository
{
    List<BookingModel> GetAll();
    void Add(BookingModel model);
}

public sealed class DummyBookingRepository : IBookingRepository, IDisposable
{
    private readonly ReaderWriterLockSlim _bookingsLock = new ReaderWriterLockSlim();
    
    private readonly List<BookingModel> _bookings = new List<BookingModel>
    {
        new BookingModel 
        {
            ladestand = 10,
            fahrstrecke = 100,
            startzeit = new DateTime(2020, 10, 2, 8, 45, 0),
            endzeit = new DateTime(2020, 10, 2, 12, 45, 0)
        },
        new BookingModel
        {
            ladestand = 65,
            fahrstrecke = 340,
            startzeit = new DateTime(2020, 05, 3, 9, 45, 0),
            endzeit = new DateTime(2020, 05, 3, 11, 45, 0)
        },
        new BookingModel
        {
            ladestand = 30,
            fahrstrecke = 150,
            startzeit = new DateTime(2020, 09, 15, 22, 45, 0),
            endzeit = new DateTime(2020, 09, 16, 0, 00, 0)
        }
    };
    
    public List<BookingModel> GetAll()
    {
        _bookingsLock.EnterReadLock();
        try
        {
            // Return a copy of the list so that we don't have to hold onto the lock:
            return new List<BookingModel>(_bookings);
        }
        finally
        {
            _bookingsLock.ExitReadLock();
        }
    }
    
    public void Add(BookingModel model)
    {
        _bookingsLock.EnterWriteLock();
        try
        {
            _bookings.Add(model);
        }
        finally
        {
            _bookingsLock.ExitWriteLock();
        }
    }
    
    public void Dispose()
    {
        _bookingsLock.Dispose();
    }
}
Register the repository in your app's startup - this dummy repository needs to be a singleton, so that a single instance is used for all requests:
C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IBookingRepository, DummyBookingRepository>();
    ...
}
Update your controller to use the repository service:
C#
public class BookingController : Controller
{
    public BookingController(IBookingRepository repository)
    {
        Repository = repository;
    }
    
    private IBookingRepository Repository { get; }
    
    public IActionResult Index()
    {
        List<BookingModel> bookings = Repository.GetBookings();
        return View(bookings);
    }

    [HttpGet]
    public IActionResult Create() 
    {
        return View(new BookingModel());
    }

    [HttpPost]
    public IActionResult Create(BookingModel model) 
    {
        Repository.AddBooking(model);
        return RedirectToAction(nameof(Index));
    }
}
 
Share this answer
 
Comments
Todor Iliev 11-May-20 14:28pm    
I'm pretty new to this stuff. So the static approach obviously worked, but I'll try your second solution for a better quality of the code. Thanks a lot !
Richard Deeming 11-May-20 14:34pm    
The DummyRepository is still something I wouldn't want to use in a real application. The data won't survive when the application restarts.

But since it's using Dependency Injection, it should be fairly easy for you to swap out the implementation to use a real database when you're ready. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900