Todor Iliev Ответов: 1

Asp.net-core передает данные из представления в контроллер, а затем в другое представление


Прямо сейчас я успешно передаю свои данные из представления в контроллер. Мой контроллер подключен к двум видам. Один из них-тот, который я хочу использовать для своего пользовательского ввода, а второй-для отображения пользовательского ввода в таблице.

Что я уже пробовал:

Итак, вот мой контроллер. Он подключен к представлениям "Index"(моя таблица-html) и "Create" (для пользовательского ввода). Метод Index()-это моя инициализация таблицы несколькими объектами.
    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();
        }
    }

}


Следующий код-это мое представление "создать". Данные успешно передаются обратно на контроллер.
@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>
}


Это мое "индексное" представление. Он отображает таблицу правильно:
@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>


Теперь, как я могу получить пользовательский ввод из этого первого представления в виде элемента таблицы во второе ?

1 Ответов

Рейтинг:
7

Richard Deeming

Каждый раз, когда вы делаете запрос, создается новый экземпляр вашего контроллера. Он обрабатывает запрос и генерирует ответ, а затем этот экземпляр выбрасывается вместе со всеми его полями.

Элемент, который вы добавляете в bookings поле в метод POST не переживет, что один запрос.

Данные должны быть сохранены в базе данных или каком-либо другом механизме хранения. Для "игрушечного" приложения, не предназначенного для реального использования, вам может сойти с рук составление списка static Но вам нужно будет быть очень осторожным, чтобы управлять доступом из нескольких потоков.

После того как вы добавили бронирование в свое постоянное хранилище, перенаправьте пользователя обратно на сайт. Index действие для отображения обновленного списка.

Вероятно, вы захотите использовать какой-то шаблон репозитория, чтобы облегчить переключение механизма хранения позже:

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();
    }
}
Зарегистрируйте репозиторий при запуске вашего приложения - этот фиктивный репозиторий должен быть одноэлементным, чтобы для всех запросов использовался один экземпляр:
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IBookingRepository, DummyBookingRepository>();
    ...
}
Обновите контроллер для использования службы репозитория:
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));
    }
}


Todor Iliev

Я довольно новичок в этом деле. Таким образом, статический подход, очевидно, сработал, но я попробую ваше второе решение для лучшего качества кода. Большое спасибо !

Richard Deeming

То DummyRepository это все еще то, что я не хотел бы использовать в реальном приложении. Данные не сохранятся при перезапуске приложения.

Но поскольку он использует инъекцию зависимостей, вам должно быть довольно легко поменять реализацию на использование реальной базы данных, когда вы будете готовы. :)