如何将数据从viewmodel传递到?

时间:2019-04-23 12:17:35

标签: c# asp.net-core asp.net-core-mvc

我是MVC的新手,正在尝试了解视图模型。 我有StaffServiceBookingSlotAppointmentsApplicationUser实体。我有以下viewmodel:

public class AppointmentBookingViewModel
{
    [Display (Name ="Select Staff")]
    public int StaffId { get; set; }
    public IEnumerable<Staff> Staffs { get; set; }

    [Display(Name = "Select Service")]
    public int ServiceId { get; set; }
    public IEnumerable<Service> Services { get; set; }

    [Display(Name = "Select Slot")]
    public int BookingSlotId { get; set; }
    public IEnumerable<BookingSlot> BookingSlots { get; set; }

}

这是控制器:

public class AppointmentBookingController : Controller
{
    private readonly SalonContext _context;

    private AppointmentBookingViewModel _appointmentBookingViewModel = new AppointmentBookingViewModel();

    public AppointmentBookingController(SalonContext context)
    {
        _context = context;
        ConfigureViewModel(_appointmentBookingViewModel);
    }

    public void ConfigureViewModel(AppointmentBookingViewModel appointmentBookingViewModel)
    {
        appointmentBookingViewModel.Staffs = _context.Staffs;
        appointmentBookingViewModel.Services = _context.Services;
        appointmentBookingViewModel.BookingSlots = _context.BookingSlots;
    }

    // GET: AppointmentBooking
    public ActionResult Index()
    {
        return View(_appointmentBookingViewModel);
    }
}

我的问题是,如何在视图中创建表单并将数据发布到“约会”表中,以下操作不起作用。

@model HairStudio.Services.ViewModels.AppointmentBooking.AppointmentBookingViewModel
@{
    ViewData["Title"] = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row">
    <div class="col-12">
        <form asp-action="Create">
            <div class="form-group">
                <label asp-for="ServiceId" class="control-label"></label>
                <select asp-for="ServiceId" class="form-control"></select> 
            </div>

            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

2 个答案:

答案 0 :(得分:0)

您已经将表单定向到具有asp-action属性的名为“ Create” 的操作,但是控制器中没有此类操作。提交表单会发送HTTP POST请求,该请求需要由您的控制器处理。因此,请在您的Create()中添加一个AppointmentBookingController方法:

// POST: Create
public IActionResult Create(AppointmentBookingViewModel appointmentViewModel)
{
    if (!ModelState.IsValid)
    {
        // Server side validation of form has failed.
        // Return to the calling view and inform the user about the errors.
        return View(appointmentViewModel, "Index");
    }

    return View(appointmentViewModel, "<NAME_OF_YOUR_CREATED_APPOINTMENT_VIEW>");
}

根据设计模式Post/Redirect/Get,在成功接受HTTP POST请求后,请考虑重定向。

另外,请查看ASP.NET Core文档中的this part,有关使用表单的信息。我相信您会在其中找到有价值的东西。

答案 1 :(得分:0)

视图模型没有什么神奇之处。这只是一堂课。这个想法是,实体类(即您通过Entity Framework持久存储到数据库中的事物)应该只与数据库的需求有关。视图可以并且经常确实有完全不同的需求集,因此您专门为此创建一个类:视图模型。这只是基本的SRP(单一职责原则):单个类不应尝试做太多事情。

然后,您只需要一种桥接两者的方法。换句话说,您需要将值从实体复制到视图模型,反之亦然。该过程称为映射,可以通过多种不同方式来实现。最常见的方法是使用第三方库,例如AutoMapper。但是,您也可以手动映射每个值,甚至可以使用类似于工厂模式的方式,在该模式下,您可以拥有另一个类,该类掌握如何进行映射的知识,并且可以从视图模型中吐出实体,反之亦然。

现在,由于我们没有您的实体,实际上不可能给您确切的指导,但您似乎想选择特定的StaffService和{{ 1}},并将其与您创建的BookingSlot相关联。这不是很关键,但是为了提高效率,您不应在视图模型中随身携带所有这些实体的完整集合。您只需要一个Appointment,它就可以使用效率更高的查询:

例如,代替IEnumerable<SelectListItem>属性:

Staffs

然后:

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

您认为:

model.StaffOptions = await _context.Staffs.AsNoTracking()
    .Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() })
    .ToListAsync();