[英]how to save items of cascading drop down list in database with asp.net mvc
我的下拉菜单效果很好,问题是当我要保存表单时。
这是我的控制器
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,TourId,StartDate,EndDate")] TourDate tourDate)
{
if (ModelState.IsValid)
{
db.TourDates.Add(tourDate);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
ViewBag.TourId = new SelectList(db.Tours, "Id", "TourName", tourDate.TourId);
return RedirectToAction("Index", "test");
}
[HttpPost]
public JsonResult GetT(int? id)
{
var tours = db.Tours.Where(e => e.CountryId == id).ToList()
.Select(e => new
{
Id = e.Id,
TourName= e.TourName
}).ToList();
return Json(tours);
}
这是我的表格。 在此From中, id=TourId
select
标签从外部下拉列表dropdownId
填充了ajax中的数据,并且工作正常
@Html.DropDownList("dropdownId",
Model.Countries.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.CountryName
}),
new { @class = "form-control" })
@using (Html.BeginForm("Create", "test"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TourDate</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.TourDate.TourId, "TourId", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<select class="form-control" id="TourId"></select>
@Html.ValidationMessageFor(model => model.TourDate.TourId, "", new { @class = "text-danger" })
</div>
</div>
<br />
<div class="form-group">
@Html.LabelFor(model => model.TourDate.StartDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.TourDate.StartDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.TourDate.StartDate, "", new { @class = "text-danger" })
</div>
</div>
<br />
<div class="form-group">
@Html.LabelFor(model => model.TourDate.EndDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.TourDate.EndDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.TourDate.EndDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
问题是当我提交没有区别的表格时,总是选择了TourId = 0。
感谢任何帮助,如果需要,这里也是ajax
$("#dropdownId").change(function () {
$('#TourId').empty();
var countrySelected = $(this).val();
$.ajax
({
url: '/test/GetT/' + countrySelected,
type: 'POST',
data: {
'countryId': countrySelected
},
success: function (data)
{
var $select = $('#TourId');
for (var i = 0; i < data.length; i++)
{
$('<option/>').attr('value', data[i].Id).html(data[i].TourName).appendTo('#TourId');
}
}
});
});
第二个<select>
元素不提交值的原因是因为它没有name
属性。 它需要是
<select class="form-control" name="TourDate.TourId" id="TourId"></select>
但是,您的代码还有许多其他错误和问题。 仅需注意其中几个:
TourDate
(它的模型包含一个属性TourDate
),因此您的控件都不能绑定到POST方法中的TourDate tourDate
参数(该参数中的模型必须与视图中的模型,或者您需要使用[Bind(Prefix = "TourDate")]
属性,还需要删除[Bind(Include = "..")]
属性)。 ModelState
无效,则仅进行重定向(用户将仅假定对象已保存并且不了解发生了什么)。 您需要返回视图,以便可以纠正错误,但是在您的情况下,用户输入的值将重置为默认值(令人讨厌的用户体验)。 您的编辑数据,因此您应该始终使用视图模型,并且在控制器方法中,需要填充SelectList来考虑初始值和已编辑的值(用于何时需要返回视图)。 您的代码应该是
public class TourDateVM
{
[Required(ErrorMessage = "Please select a country")]
[Display(Name = "Country")]
public int? SelectedCountry { get; set; }
[Required(ErrorMessage = "Please select a tour")]
[Display(Name = "Country")]
public int? SelectedTour { get; set; }
[Required(ErrorMessage = "Please enter a start date")]
[Display(Name = "Start date")]
public DateTime? StartDate { get; set; }
.... // ditto above for EndDate
public IEnumerable<SelectListItem> CountryList { get; set; }
public IEnumerable<SelectListItem> TourList { get; set; }
}
并在控制器中
public ActionResult Create()
{
TourDateVM model = new TourDateVM();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Create(TourDateVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
TourDate tour = new TourDate()
{
TourId = model.SelectedTour,
StartDate = model.StartDate,
EndDate= model.EndDate
};
db.TourDates.Add(tour);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
private ConfigureViewModel(TourDateVM model)
{
var counties = db.Countries;
model.CountryList = new SelectList(counties, "ID", "Name"); // adjust to suit your property names
if (model.SelectedCountry.HasValue)
{
var tours = db.Tours.Where(e => e.CountryId == model.SelectedCountry);
model.TourList = new SelectList(tours, "Id", "TourName");
}
else
{
model.TourList = new SelectList(Enumerable.Empty<SelectListItem>());
}
}
最后是视图(请注意,两个下拉列表都必须在<form>
元素内)
@model TourDateVM
....
@using Html.BeginForm())
{
....
<div class="form-group">
@Html.LabelFor(m => m.SelectedCountry, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.SelectedCountry, Model.CountryList, "- Please select -", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedCountry, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedTour, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.SelectedTour, Model.TourList, "- Please select -", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SelectedTour, "", new { @class = "text-danger" })
</div>
</div>
....
}
并且脚本应该是
var url = '@Url.Action("GetT")'; // assumes its in the same controller
var tours = $('#SelectedTour');
$('#SelectedCountry').change(function() {
tours.empty();
$.post(url , { id: $(this).val() }, function(data) {
if (!data) {
return;
}
tours.append($('<option></option>').val('').text('- Please select -'));
$.each(data, function(index, item) {
tours.append($('<option></option>').val(item.Id).text(item.TourName));
});
});
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.