【问题标题】:Using View model instead of data to create使用视图模型而不是数据来创建
【发布时间】:2020-01-09 11:46:02
【问题描述】:

我正在尝试使用视图模型而不是直接使用数据来完成我正在尝试做的大部分事情。

这样的事情之一是尝试在航班上预订乘客/客户。数据使用两个键/ID,乘客 ID 和航班 ID。

现在视图模型看起来像这样:

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");}
}

现在我尝试在其中实现视图模型,但它不会将数据带入下拉列表。我不确定如何让它发挥作用。

【问题讨论】:

  • 嗨@SSM,关于这个案例的任何更新?你达到要求了吗?
  • @FeiHan 是的,对不起。我实际上从我的一位导师那里得到了答案。我已经发布了答案以说明我做了什么以及为什么。

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


【解决方案1】:

尝试在视图中使用它 -

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

【讨论】:

  • 我需要把它放在视图的什么地方?
【解决方案2】:

现在我尝试在其中实现视图模型,但它不会将数据带入下拉列表。我不确定如何让它发挥作用。

如果您想通过 ViewModel(而不是 ViewData)将 PassengersFlights 的数据传递到您的视图页面,然后用这些数据填充两个 dorpdown 列表,您可以参考以下代码 sn- p.

Passenger、Flight 和 FlightBookingViewModel 类

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);
}

测试结果

【讨论】:

    【解决方案3】:

    所以我终于从我的导师那里得到了帮助,所以控制器代码的第一部分是这样的:

    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);
            }
    

    这样,当视图模型 ID 与数据 ID 命名相同时,我可以使下拉菜单正常工作

    问题似乎在于无法识别的 id 名称。因此,一旦 viewmodels id 名称与数据相同,问题就消失了,我仍在使用 viewmodels

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      相关资源
      最近更新 更多