Использование модели представления вместо данных для создания - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь использовать viewmodels вместо того, чтобы использовать данные напрямую для большинства вещей, которые я пытаюсь сделать.

Одна из таких вещей - попытаться забронировать Пассажира / Клиента на рейс. В данных используются два ключа / идентификатора: идентификатор пассажира и идентификатор рейса.

Теперь модель представления выглядит примерно так:

namespace WebSite.Models.PassengerViewModels
    {
        public class FlightBookingViewModel
        {
            [Display(Name = "Passenger ID ")]
            public int IdC { get; set; }

            [Display(Name = "E-mail Address ")]
            [Required]
            [DataType(DataType.EmailAddress)]
            public string Email { get; set; }

            [Display(Name = "Flight ID ")]
            public int IdF { get; set; }

            [Display(Name = "Flight Name ")]
            public int Name { get; set; }

        }
    }

Но код скаффолда для создания бронирования выглядит как-то например:

public IActionResult Create()
        {
            ViewData["IdC"] = new SelectList(_context.Passengers, "Id", "Email");
            ViewData["IdF"] = new SelectList(_context.Flights, "Id", "Name");

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("IdC,IdF,Attended")] FlightBooking model)
        {
            if (ModelState.IsValid)
            {
                _context.Add(model);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            ViewData["IdC"] = new SelectList(_context.Customers, "Id", "Email", model.IdF);
            ViewData["IdF"] = new SelectList(_context.Events, "Id", "Name", model.IdE);
            return View(model);
        }

Тогда страница просмотра для создания выглядит следующим образом:

@model WebSite.Data.FlightBooking

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>FlightBooking</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="IdC" class="control-label"></label>
                <select asp-for="IdC" class ="form-control" asp-items="ViewBag.IdC"></select>
            </div>
            <div class="form-group">
                <label asp-for="IdF" class="control-label"></label>
                <select asp-for="IdF" class ="form-control" asp-items="ViewBag.IdF"></select>
            </div>
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input asp-for="Attended" /> @Html.DisplayNameFor(model => model.Attended)
                    </label>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Теперь я попытался внедрить в нее модель представления, но она просто не привела бы данные в раскрывающийся список. список. и я не уверен, как заставить это работать.

Ответы [ 3 ]

0 голосов
/ 10 января 2020

Теперь я попытался внедрить модель представления в это, но это просто не принесло бы данные в выпадающий список. и я не уверен, как заставить это работать.

Если вы хотите передать данные Passengers и Flights через ViewModel (а не ViewData) на страницу просмотра, а затем заполните В двух раскрывающихся списках с этими данными вы можете обратиться к следующему фрагменту кода.

Passenger, Flight и FlightBookingViewModel class

public class FlightBookingViewModel
{
    public List<Passenger> Passengers { get; set; }
    public List<Flight> Flights { get; set; }

    public FlightBooking FlightBooking { get; set; }
}

public class Passenger
{
    [Display(Name = "Passenger ID ")]
    public int IdC { get; set; }

    [Display(Name = "E-mail Address ")]
    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }
}

public class Flight
{
    [Display(Name = "Flight ID ")]
    public int IdF { get; set; }

    [Display(Name = "Flight Name ")]
    public string Name { get; set; }
}

На странице просмотра

@model FlightBookingViewModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>FlightBooking</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="@Model.FlightBooking.IdC" class="control-label"></label>
                <select asp-for="@Model.FlightBooking.IdC" class="form-control" asp-items="@(new SelectList(Model.Passengers,"IdC","Email"))"></select>
            </div>
            <div class="form-group">
                <label asp-for="@Model.FlightBooking.IdF" class="control-label"></label>
                <select asp-for="@Model.FlightBooking.IdF" class="form-control" asp-items="@(new SelectList(Model.Flights,"IdF","Name"))"></select>
            </div>
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input asp-for="@Model.FlightBooking.Attended" /> @Html.DisplayNameFor(model => model.FlightBooking.Attended)
                    </label>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

В действии контроллера

public IActionResult Create([Bind("FlightBooking")] FlightBookingViewModel model)
{

    // replace following test code with your code logic

    var passengers = new List<Passenger>
    {
        new Passenger
        {
            IdC = 1,
            Email = "p1@test.com"
        },
        new Passenger
        {
            IdC = 2,
            Email = "p2@test.com"
        },
        new Passenger
        {
            IdC = 3,
            Email = "p3@test.com"
        }
    };

    var flights = new List<Flight>
    {
        new Flight
        {
            IdF = 1,
            Name = "F1"
        },
        new Flight
        {
            IdF = 2,
            Name = "F2"
        },
        new Flight
        {
            IdF = 3,
            Name = "F3"
        }
    };

    var fb_viewmodel = new FlightBookingViewModel
    {
        Passengers = passengers,
        Flights = flights,
        FlightBooking = new FlightBooking()
    };

    return View(fb_viewmodel);
}

Результат теста

enter image description here

0 голосов
/ 14 января 2020

Итак, я наконец-то получил помощь от моего преподавателя, поэтому первый бит кода контроллера, который выглядит так:

public IActionResult Create()
        {
            ViewData["PassengerId"] = new SelectList(_context.Passengers, "Id", "Email");
            ViewData["FlightId"] = new SelectList(_context.Flights, "Id", "Name");

            return View();
        }

, в некотором смысле уже является моделью представления и защищает данные.

теперь работа со вторым битом кода контроллера:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("PassengerId,IdF,Attended")] FlightBookingViewModel model)
        {
            if (ModelState.IsValid)
            {
                FlightBooking flightBooking = new FlightBooking
                {
                    PassengerId = model.PassengerId,
                    FlightId = model.FlightId,
                    Attended = model.Attended
                }
                await _context.Guests.AddAsync(flightBooking);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            ViewData["PassengerId"] = new SelectList(_context.Customers, "Id", "Email", model.PassengerId);
            ViewData["FlightId"] = new SelectList(_context.Events, "Id", "Name", model.FlightId);
            return View(model);
        }

Таким образом, я могу получить раскрывающееся меню, работающее, когда идентификаторы идентификаторов моделей именуются так же, как идентификаторы данных

Проблема, похоже, заключалась в том, что имена идентификаторов не были распознаны. поэтому, когда имена идентификаторов viewmodels совпадают с именами данных, проблемы исчезли, и я все еще использую viewmodels

0 голосов
/ 09 января 2020

Попробуйте использовать это в представлении -

   @Html.DropDownList("IdC", 
                         ViewData["IdC"],
                        "Select Flight ID",
                        new { @class = "form-control" })
...