将数据从视图模型传递到控制器

我是ASP.NET Core的初学者,正在制作租车网站,在一个视图上,我具有包含两个属性的视图模型,我的第一个模型包含有关汽车的数据,第二个模型包含有关预订的数据。

第一辆模型车:

public class Car
{
    public int Id { get; set; }

    public string Model { get; set; }

    public string Manufacturer { get; set; }

    public Transmission Transmission { get; set; }

    public Fuel Fuel { get; set; }

    public string ImageThumbnailUrl { get; set; }

    public int DoorNumber { get; set; }

    public int Passangers { get; set; }

    public decimal Price { get; set; }

    public int Year { get; set; }

    public bool Available { get; set; }

    public Location CurrentLocation { get; set; }
}

和第二个模型预订:

public class Reservation
{
    public int Id { get; set; }

    public int UserId { get; set; }

    public int CarId { get; set; } 

    public Location PickUpLocation { get; set; }

    public Location ReturnLocation { get; set; }

    public DateTime PickUpDate { get; set; }

    public DateTime ReturnDate { get; set; }
}

该视图包含CarReservationViewModel:

public class CarReservationViewModel
{
    public Car Car { get; set; }

    public Reservation Reservation { get; set; }
}

视图看起来像:

@model CarReservationViewModel
<form asp-action="MakeReservation" method="post" role="form">
    <div class="container detail">
        <div class="row">
            <div class="col-md-8">
                <h2>@Model.Car.Manufacturer  @Model.Car.Model</h2>
                <h4>Rent a @Model.Car.Manufacturer  @Model.Car.Model</h4>
                <p>
                    @Html.Raw(@Model.Car.LongDescription)
                </p>
            </div>
            <div class="col-md-4">
                <img class="car-image" src="@Url.Content(@Model.Car.ImageThumbnailUrl)" alt="" />
                <div class="pricing primary-background">
                    <span class="amount">
                        Price from @Model.Car.Price EUR
                    </span>
                </div>
            </div>
        </div>
        <hr />
        <div class="row">
            <div class="col-md-8">
                <div class="row center-subrow">
                    <div class="col-md-6">
                        <div class="form-group align-items">
                            <label class="col-md-6" asp-for="@Model.Reservation.PickUpLocation"></label>
                            <div class="col-md-6">
                                <select class="col-md-4 form-control" asp-for="@Model.Reservation.PickUpLocation" asp-items="@Html.GetEnumSelectList<Location>().OrderBy(l =>l.Text)"></select>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group align-items">
                            <label class="col-md-6" asp-for="@Model.Reservation.ReturnLocation"></label>
                            <div class="col-md-6">
                                <select class="col-md-4 form-control" asp-for="@Model.Reservation.ReturnLocation" asp-items="@Html.GetEnumSelectList<Location>().OrderBy(l =>l.Text)"></select>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row center-subrow">
                    <div class="col-md-6">
                        <div class="form-group align-items">
                            <label class="col-md-6" asp-for="@Model.Reservation.PickUpDate"></label>
                            <div class="col-md-6">
                                <input id="datepicker1" class="col-md-4 form-control datepicker" asp-for="@Model.Reservation.PickUpDate" data-provide="datepicker" />
                            </div>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group align-items">
                            <label class="col-md-6" asp-for="@Model.Reservation.ReturnDate"></label>
                            <div class="col-md-6">
                                <input id="datepicker2" class="col-md-4 form-control datepicker" asp-for="@Model.Reservation.ReturnDate" data-provide="datepicker" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="reservation">
                    @Html.HiddenFor(m => m.Car.Id);
                    <input type="submit" class="btn-reservation" value="Make reservation">
                </div>
            </div>
        </div>
    </div>
</form>

汽车控制器有方法Detail和MakeReservation:

    public IActionResult Detail(int id)
    {
        var carReservationViewModel = new CarReservationViewModel
        {
            Car = _carRepository.GetCarById(id)
        };
        return View(carReservationViewModel);
    }

当我进入Detail方法时,它将汽车详细信息传递给视图,并且该视图包含用于提交有关预订数据的表单。我在该表单上单击“提交”按钮时遇到问题,viewModel Car属性为null,但是Reservation属性具有值,我可以将汽车数据传递回viewModel.Car属性吗?

    [HttpPost]
    public IActionResult MakeReservation(CarReservationViewModel viewModel)
    {

        if(ModelState.IsValid)
        {
            var reservation = new Reservation
            {
                CarId = viewModel.Car.Id, //viewModel.Car is null
                PickUpDate = viewModel.Reservation.PickUpDate,
                ReturnDate = viewModel.Reservation.ReturnDate,
                PickUpLocation = viewModel.Reservation.PickUpLocation,
                ReturnLocation = viewModel.Reservation.ReturnLocation
            };

            _reservationRepository.Add(reservation);

        }

        return View();
    }

在视图上有两个模型是否正常?一个模型用于显示信息(汽车模型),另一个模型用于包含有关预订的数据(预订模型)。

评论
墨oo
墨oo

“在视图上有两个模型是正常的,一个模型用于显示信息(汽车模型),另一个模型用于包含有关预订的数据(预订模型)。” :

No, it is not normal. Instead, you can combine multiple entities into a ViewModel and pass this ViewModel to the View.

另一方面,您可以尝试以下方法来组合实体或模型:

ViewModel:

public class GroupViewModel
{       
    //Foreign key for Lab
    public int LabId { get; set; }

    //Foreign key for Term
    public int TermId { get; set; }

    public IEnumerable<SelectListItem> Labs { get; set; }

    public IEnumerable<SelectListItem> Terms { get; set; } 
}

控制器:

public ActionResult Create()
{
    var model = new GroupViewModel
    {
        // Hard coded for demo. You can replace with real data from dB
        var model = new GroupViewModel();

        Labs = repository.Labs.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        }),
        Terms = repository.Terms.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        })
    };
    return PartialView("_Create", model);
}

希望这可以帮助。

点赞
评论