繁体   English   中英

如何使用asp.net mvc在数据库中保存级联下拉列表项

[英]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>

但是,您的代码还有许多其他错误和问题。 仅需注意其中几个:

  1. 您视图中的模型不是TourDate (它的模型包含一个属性TourDate ),因此您的控件都不能绑定到POST方法中的TourDate tourDate参数(该参数中的模型必须与视图中的模型,或者您需要使用[Bind(Prefix = "TourDate")]属性,还需要删除[Bind(Include = "..")]属性)。
  2. 您没有与下拉列表和POST方法相关联的客户端验证,如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM