ASP.NET MVC核心级联DropDownList [英] ASP.NET MVC Core Cascading DropDownList
问题描述
我在查找教程/视频时遇到了麻烦,该教程/视频显示了如何使用EntityFramework从数据库中实现Cascading DropDownList.我正在使用ASP.NET MVC核心,带有C#的EntityFramework核心.
I'm having trouble finding a tutorial / video that shows how to implement Cascading DropDownList from a Database using EntityFramework. I'm using ASP.NET MVC Core, EntityFramework Core with C#.
到目前为止,我能够从数据库中检索数据到3 DropDownList很好.
As of now, I'm able to retrieve the data from my database to my 3 DropDownList fine.
我希望能够完成的工作是让用户首先选择一个州,然后显示与该州相关的所有城市.然后,在用户选择城市后,它将显示与城市相关的邮政编码.
What I would like to be able to accomplish is to have the user select a State first which would then display all Cities related to that State. Then after user has selected a City it would display the Zip Code(s) related to the City.
任何帮助将不胜感激.
Any help would be greatly appreciated.
模型
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int StateId { get; set; }
public int CityId { get; set; }
public int ZipId { get; set; }
public State State { get; set; }
public City City { get; set; }
public Zip Zip { get; set; }
}
public class State
{
public int StateId { get; set; }
public string Abbr { get; set; }
public List<Customer> Customers { get; set; }
}
public class City
{
public int CityId { get; set; }
public string Name { get; set; }
public int StateId { get; set; }
public State State { get; set; }
public List<Customer> Customers { get; set; }
}
public class Zip
{
public int ZipId { get; set; }
public string PostalCode { get; set; }
public int CityId { get; set; }
public City City { get; set; }
public List<Customer> Customers { get; set; }
}
ViewModels
public class CustomerFormVM
{
public int CustomerId { get; set; }
[Display(Name = "First Name")]
[StringLength(50)]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[StringLength(50)]
public string LastName { get; set; }
[Required(ErrorMessage = "Select State")]
[Display(Name = "State")]
public int StateId { get; set; }
//public IEnumerable<State> States { get; set; }
public IEnumerable<SelectListItem> States { get; set; }
[Required(ErrorMessage = "Select City")]
[Display(Name = "City")]
public int CityId { get; set; }
//public IEnumerable<City> Citys { get; set; }
public IEnumerable<SelectListItem> Citys { get; set; }
[Required(ErrorMessage = "Select Zip")]
[Display(Name = "Zip")]
public int ZipId { get; set; }
//public IEnumerable<Zip> Zips { get; set; }
public IEnumerable<SelectListItem> Zips { get; set; }
}
CustomerController
public class CustomerController : Controller
{
private MultiDbContext db;
public CustomerController(MultiDbContext context)
{
db = context;
}
// GET: /<controller>/
public IActionResult Index()
{
return View(db.Customers.ToList());
}
public IActionResult getCititesFromDatabaseByStateId(int id)
{
return View(db.Citys.Where(c => c.StateId == id).ToList());
}
public IActionResult getCities(int id)
{
var cities = new List<City>();
cities = getCititesFromDatabaseByStateId(id); //call repository
return Json(cities);
}
public ActionResult Create()
{
var states = db.States.ToList();
var citys = db.Citys.ToList();
var zips = db.Zips.ToList();
var viewModel = new CustomerFormVM
{
States = states,
Citys = citys,
Zips = zips
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormVM vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.FirstName = vm.FirstName;
customer.LastName = vm.LastName;
customer.StateId = vm.StateId;
customer.CityId = vm.CityId;
customer.ZipId = vm.ZipId;
}
db.Customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
vm.States = db.States.ToList();
vm.Citys = db.Citys.ToList();
vm.Zips = db.Zips.ToList();
return View(vm);
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormVM();
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustomerId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustomerId = customer.CustomerId;
customervm.FirstName = customer.FirstName;
customervm.LastName = customer.LastName;
// Retrieve list of States
var states = db.States.ToList();
customervm.States = states;
// Retrieve list of Citys
var citys = db.Citys.ToList();
customervm.Citys = citys;
// Retrieve list of Citys
var zips = db.Zips.ToList();
customervm.Zips = zips;
// Set the selected state
customervm.StateId = customer.StateId;
// Set the selected city
customervm.CityId = customer.CityId;
// Set the selected zip
customervm.ZipId = customer.ZipId;
}
return View(customervm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormVM vmEdit)
{
if (ModelState.IsValid)
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustomerId == vmEdit.CustomerId);
if (customer == null)
{
return NotFound();
}
customer.FirstName = vmEdit.FirstName;
customer.LastName = vmEdit.LastName;
customer.StateId = vmEdit.StateId;
customer.CityId = vmEdit.CityId;
customer.ZipId = vmEdit.ZipId;
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vmEdit);
}
}
创建视图
<div class="form-group">
@Html.LabelFor(c => c.FirstName)
@Html.TextBoxFor(c => c.FirstName, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(c => c.LastName)
@Html.TextBoxFor(c => c.LastName, new { @class = "form-control" })
</div>
<div class="form-group">
@*@Html.LabelFor(s => s.StateId)
@Html.DropDownListFor(s => s.StateId, new SelectList(Model.States, "StateId", "Abbr"), "", new { @class = "form-control" })
@Html.ValidationMessageFor(s => s.StateId)*@
<label asp-for="StateId "></label>
<select asp-for="StateId " asp-items="Model.States" class="form-control" id="state-target"></select>
<span asp-validation-for="StateId " class="text-danger"></span>
</div>
<div class="form-group">
@*@Html.LabelFor(ct => ct.CityId)
@Html.DropDownListFor(ct => ct.CityId, new SelectList(Model.Citys, "CityId", "Name"), "", new { @class = "form-control" })
@Html.ValidationMessageFor(ct => ct.CityId)*@
<label asp-for="CityId"></label>
<select asp-for="CityId" asp-items="Model.Citys" class="form-control" id="city-target"></select>
<span asp-validation-for="CityId" class="text-danger"></span>
</div>
<div class="form-group">
@Html.LabelFor(z => z.ZipId)
@Html.DropDownListFor(z => z.ZipId, new SelectList(Model.Zips, "ZipId", "PostalCode"), "", new { @class = "form-control" })
@Html.ValidationMessageFor(z => z.ZipId)
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
}
@section scripts {
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<script src="~/lib/js/example.js"></script>,
}
推荐答案
我也遇到类似的情况,但在我的示例中,我有一个Root文件夹,根据我使用的根文件夹,下一个下拉列表将显示相应的子目录. -文件夹.
I had a similar situation but in my example I have a Root folder and depending on which root folder I am using the next drop down list would display the corresponding sub-folders.
不确定是否有纯粹的asp.net解决方案,但是我为此使用了Jquery/Ajax.
Not sure if there is a purly asp.net solution but, I used Jquery/Ajax for this.
您的代码应如下所示:
html列表:
<label asp-for="StateId "></label>
<select asp-for="StateId " asp-items="Model.States" class="form-control" id="state-target"></select>
<span asp-validation-for="StateId " class="text-danger"></span>
<label asp-for="CityId"></label>
<select asp-for="CityId" asp-items="Model.Citys" class="form-control" id="city-target"></select>
<span asp-validation-for="CityId" class="text-danger"></span>
jQuery代码,您将其编写为.js文件,然后使用此语句将其添加到特定视图中.<script src="~/js/example.js"></script>
,别忘了您需要在项目中添加一个jQuery库,然后再添加其他任何javascript,而您的example.js
将包含:
Jquery code, you write this in .js file and then add it to a specific view with this statement<script src="~/js/example.js"></script>
, Don't forget you need to add a jquery library to your project before any other javascript, and your example.js
will contain:
$(document).ready(function () {
$("#state-target").on("change", function () {
$list = $("#city-target");
$.ajax({
url: "/getCities",
type: "GET",
data: { id: $("#state-target").val() }, //id of the state which is used to extract cities
traditional: true,
success: function (result) {
$list.empty();
$.each(result, function (i, item) {
$list.append('<option value="' + item["CityId"] + '"> ' + item["Name"] + ' </option>');
});
},
error: function () {
alert("Something went wrong call the police");
}
});
});
});
Ajax请求将在Controller中调用此操作,该Controller将从数据库中检索城市列表(在getCititesFromDatabaseByStateId(id)
方法中使用return dbContext.CityTable.Where(c => c.StateId == id).ToList()
之类的东西),然后返回Json对象,success
函数将创建选项列表并应用它:
The Ajax request will call this action in the Controller which will retrieve a list of cities from the database (using something like return dbContext.CityTable.Where(c => c.StateId == id).ToList()
inside a getCititesFromDatabaseByStateId(id)
method) and then return the Json object, the success
function will create a list of options and apply it:
public IActionResult getCities(int id)
{
var cities = new List<City>();
cities = getCititesFromDatabaseByStateId(id); //call repository
return Json(citites);
}
在您的ViewModel
中,考虑将IEnumerable<State/City/Zip>
(IEnumerable<T>
)更改为IEnumerable<SelectListItem>
.我也可以说您的模型很混乱(但是如果您可以从数据库中获取数据,则可以使列表优先运行),请考虑稍后进行改进.
In your ViewModel
consider changing IEnumerable<State/City/Zip>
(IEnumerable<T>
) to IEnumerable<SelectListItem>
. I can say as well your Model's are messy (but if you can get data the from the database focus on getting the list working 1st), consider improving them later.
修复注释中提到的2个错误:
Fix for 2 errors mentioned in the comments:
public List<City> getCititesFromDatabaseByStateId(int id)
{
return db.Citys.Where(c => c.StateId == id).ToList();
}
public ActionResult Create()
{
var states = new SelectList(db.States.ToList(), "StateId", "Abbr");
var citys = new SelectList(db.Citys.ToList(), "CityId", "Name");
var zips = new SelectList(db.Zips.ToList(), "ZipId", "Code");
var viewModel = new CustomerFormVM
{
States = states,
Citys = citys,
Zips = zips
};
return View(viewModel);
}
这篇关于ASP.NET MVC核心级联DropDownList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!