使用视图模型而不是数据来创建
Using View model instead of data to create
我正在尝试使用视图模型而不是直接使用数据来完成我尝试做的大部分事情。
其中之一就是尝试预订 Passenger/Customer 航班。数据使用了两个keys/IDs,passenger Id和Flight 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");}
}
现在我尝试在其中实现视图模型,但它不会将数据带入下拉列表。我不确定如何让它发挥作用。
尝试在视图中使用它 -
@Html.DropDownList("IdC",
ViewData["IdC"],
"Select Flight ID",
new { @class = "form-control" })
Now i tried to implement the viewmodel into this but it just wouldnt bring the data into the dropdown list. and i am unsure how to get that working.
如果您想通过 ViewModel(而不是 ViewData)将 Passengers
和 Flights
的数据传递到您的视图页面,然后用这些数据填充两个 dorpdown 列表,您可以参考到以下代码片段。
乘客、航班和 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);
}
测试结果
所以我终于从我的导师那里得到了帮助,所以控制器代码的第一位是这样的:
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
我正在尝试使用视图模型而不是直接使用数据来完成我尝试做的大部分事情。
其中之一就是尝试预订 Passenger/Customer 航班。数据使用了两个keys/IDs,passenger Id和Flight 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");}
}
现在我尝试在其中实现视图模型,但它不会将数据带入下拉列表。我不确定如何让它发挥作用。
尝试在视图中使用它 -
@Html.DropDownList("IdC",
ViewData["IdC"],
"Select Flight ID",
new { @class = "form-control" })
Now i tried to implement the viewmodel into this but it just wouldnt bring the data into the dropdown list. and i am unsure how to get that working.
如果您想通过 ViewModel(而不是 ViewData)将 Passengers
和 Flights
的数据传递到您的视图页面,然后用这些数据填充两个 dorpdown 列表,您可以参考到以下代码片段。
乘客、航班和 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);
}
测试结果
所以我终于从我的导师那里得到了帮助,所以控制器代码的第一位是这样的:
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