使用Entity Framework和ViewModel的MVC级联DropDowns

问题描述 投票:0回答:1

我正在尝试创建一个页面,其中包含3个级联下拉列表,用于车辆制造,模型和变体。

单击“搜索”按钮必须将页面发布到另一个控制器并使用ViewModel进行查看,ViewModel将显示在索引页面上选择的车辆的详细信息。

楷模

public class Vehicle
{
    public IEnumerable<SelectListItem> Make{ get; set; }
    public IEnumerable<SelectListItem> Model { get; set; }
    public IEnumerable<SelectListItem> Variant { get; set; }
}

public class Details
{
    public string PowerOutput{ get; set; }
    public string NumberOfDoors{ get; set; }
    public string VariantName { get; set; }
}

HomeController的

VehicleEntities db = new VehicleEntities();

public ActionResult Index()
{
    var model = new Vehicle
    {
        BrandName = GetMakes()
    };

    return View(model);
}


private IEnumerable<SelectListItem> GetMakes()
{
    IEnumerable<SelectListItem> brandname = from s in db.prcGetMakes(null)
                                            select new SelectListItem
                                            {
                                                Selected = s.Make.ToString() == "Active",
                                                Text = s.Make,
                                                Value = s.Make
                                            };
    return new SelectList(brandname, "Value", "Text");
}

public JsonResult GetModels(string make)
{
    var list = db.prcGetModels(make);

    return Json(new SelectList(list, "Model", "Model"), JsonRequestBehavior.AllowGet);
}

public JsonResult GetVariants(string model)
{
    var list = db.prcGetVariants(model);

    return Json(new SelectList(list, "Variant", "Variant"), JsonRequestBehavior.AllowGet);
}

视图

@model WebApplication7.ViewModels.VehicleDetailsViewModel**
@using (Html.BeginForm("Index", "Vehicle", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

<div class="form-group">
    <div class="col-md-3">
        @Html.Label("Make", new { @class = "col-md-2 control-label" })
        @Html.DropDownList("Make", Model.Make as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "refreshModelFromBrandName()" })
    </div>
    <div class="col-md-3">
        @Html.LabelFor(model => model.Model, htmlAttributes: new { @class = "control-label col-md-2" })
        @Html.DropDownList("Model", Model.Model as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "refreshVariantFromModel()" })*@
    </div>
    <div class="col-md-3">
        @Html.LabelFor(model => model.Brand, htmlAttributes: new { @class = "control-label col-md-2" })
        @Html.DropDownList("Variant", Model.Variant as SelectList, htmlAttributes: new { @class = "form-control minimal", @onchange = "" })*@
    </div>
    <div class="col-md-3">
        <input id="search" type="submit" value="Search" />
    </div>
</div>
}

<script type="text/javascript">

    function refreshBrandName() {
        // get references to the source and target drop downs html controls
        // These are jquery searches to find the drop down controls

        // find a control with id=BrandName
        src = $("#Make");

        // find a control with id=Model (you need to add this to your view)
        tgt = $("#BrandName");

        // clear drop down
        tgt.empty();

        // Get new model dataset via ajax
        // based on BrandName
        // The url parameter points at your web method
        $.ajax({
            type: 'GET',
            //url: 'GetMakes',
            url: 'GetMakes',
            dataType: 'json',
            data: { brandName: src.val() },
            // success is called when dataset returns
            success: function (p) {
                // Populate with each returned member
                $.each(p, function (i, pr) {
                    tgt.append(
                        '<option value="' + pr.Value + '">' +
                        pr.Text + '</option>'
                    );
                })
            }
        });
    }

    function refreshModelFromBrandName() {
        // get references to the source and target drop downs html controls
        // These are jquery searches to find the drop down controls

        // find a control with id=BrandName
        src = $("#Make");

        // find a control with id=Model (you need to add this to your view)
        tgt = $("#Model");

        // clear drop down
        tgt.empty();

        // Get new model dataset via ajax
        // based on BrandName
        // The url parameter points at your web method
        $.ajax({
            type: 'GET',
            url: 'GetModels',
            dataType: 'json',
            data: { brandName: src.val() },
            // success is called when dataset returns
            success: function (p) {
                // Populate with each returned member
                $.each(p, function (i, pr) {
                    tgt.append(
                        '<option value="' + pr.Value + '">' +
                        pr.Text + '</option>'
                    );
                })
            }
        });
    }

    function refreshVariantFromModel() {
        // get references to the source and target drop downs html controls
        // These are jquery searches to find the drop down controls

        // find a control with id=BrandName
        src = $("#Model");

        // find a control with id=Model (you need to add this to your view)
        tgt = $("#Variant");

        // clear drop down
        tgt.empty();

        // Get new model dataset via ajax
        // based on BrandName
        // The url parameter points at your web method
        $.ajax({
            type: 'GET',
            url: 'GetVariants',
            dataType: 'json',
            data: { modelName: src.val() },
            // success is called when dataset returns
            success: function (p) {
                // Populate with each returned member
                $.each(p, function (i, pr) {
                    tgt.append(
                        '<option value="' + pr.Value + '">' +
                        pr.Text + '</option>'
                    );
                })
            }
        });
    }
</script>

这很好地工作,级联下拉菜单按预期执行,表单发布到正确的控制器

VehicleController

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Index(Details model)
{

    return View(model);
}

但这是我被卡住的地方。如何让Vehicle Controller将VehicleDetail ViewModel传递给连接到Vehicle Controller的View?

我知道它与我在HomeController中仅使用Vehicle类的事实有关,但我不知道如何创建VehicleDetailsViewController的实现,以便ViewModel在HomeController视图和VehicleController视图上工作。

我认为ViewModel必须是这样的

public class VehicleDetailsViewModel
{
    public IEnumerable<SelectListItem> Brands { get; set; }
    public IEnumerable<SelectListItem> Models { get; set; }
    public IEnumerable<SelectListItem> Variants { get; set; }

    public string PowerOutput { get; set; }
    public string NumberOfDoors { get; set; }
    public string VariantName { get; set; }

    public VehicleDetailsViewModel()
    {
        this.Brands = new List<SelectListItem>();
        this.Models = new List<SelectListItem>();
        this.Variants = new List<SelectListItem>();
    }
}

任何帮助都感激不尽 :)

c# asp.net-mvc entity-framework razor
1个回答
2
投票

通常我会做下一个:

public ActionResult Index()
{
   var vm = new VehicleDetailsViewController();
   return View(vm);
}

[HttpPost]
public ActionResult Index(VehicleDetailsViewController vm)
{
   //Validation something wrong
    if (!ModelState.IsValid) return View(vm);

   //Make what you want with all OK
    return View("AllOk");
}
© www.soinside.com 2019 - 2024. All rights reserved.