使用MVC Razor实体框架和存储过程的级联下拉列表

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

我是MVC和Razor的新手,已经看过很多这方面的例子和教程,但却无法让它发挥作用。它似乎很简单,但我认为我尝试使用存储过程这一事实使一切变得复杂。

我试图使用存储过程和实体框架在MVC中创建一些简单的级联下拉列表。

我的实体包含以下存储过程:

enter image description here

exec prcGetMakes
exec prcGetModels 'BMW'
exec prcGetVariants '1 SERIES 5-DOOR'

我创建了一个名为VehicleViewModel的视图模型类:

public class VehicleViewModel
{
    [Display(Name = "Manufacturer")]
    public string BrandName { get; set; }
    public string BrandID { get; set; }

    [Display(Name = "Model")]
    public string ModelName { get; set; }
    public string ModelID { get; set; }

    [Display(Name = "Variant")]
    public string VariantName { get; set; }

    public IEnumerable<SelectListItem> Manufacturer { get; set; }
    public IEnumerable<SelectListItem> Model { get; set; }
    public IEnumerable<SelectListItem> Variant { get; set; }
}

我正在使用名为HomeController.cs的默认控制器类:

public class HomeController : Controller
{
    VehicleInfoEntities db = new VehicleInfoEntities();

    public ActionResult Index()
    {
        var app = new VehicleViewModel
        {
            Manufacturer = GetMakes()
        };

        return View(app);
    }


    private IEnumerable<SelectListItem> GetMakes()
    {
        var list = new VehicleViewModel();
        IEnumerable<SelectListItem> manufacturer = from s in db.prcGetMakes(null)
                                            select new SelectListItem
                                            {
                                                Selected = s.ToString() == "Active",
                                                Text = s.BrandName,
                                                Value = s.BrandID
                                            };
        return manufacturer;

    }

    private IEnumerable<SelectListItem> GetModels(string brandName)
    {
        var list = new VehicleViewModel();
        IEnumerable<SelectListItem> models = from s in db.prcGetModels(brandName)
                                            select new SelectListItem
                                            {
                                                Selected = s.ToString() == "Active",
                                                Text = s.ModelName,
                                                Value = s.ModelID
                                            };
        return models;

    }

    private IEnumerable<SelectListItem> GetVariants(string modelName)
    {
        var list = new VehicleViewModel();
        IEnumerable<SelectListItem> variants = from s in db.prcGetVariants(modelName)
                                             select new SelectListItem
                                             {
                                                 Selected = s.ToString() == "Active",
                                                 Text = s.VariantName,
                                                 Value = s.VariantName
                                             };
        return variants;

    }
}

这是我的观点

@model WebApplication12.Models.VehicleViewModel

@{
    ViewBag.Title = "Home Page";
}
@using (Html.BeginForm("Index", "Sample", FormMethod.Post))
{
@Html.AntiForgeryToken()

@Html.ValidationSummary()
<div class="form-group" style="text-align:left;">
    @Html.Label("Manufacturer:", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownList("Manufacturer", ViewData["Manufacturer"] as SelectList, new { @class = "form-control" })
    </div>
</div><br />

}

期望的结果是

enter image description here

我现在想知道如何使用JQuery使级联DropDowns工作并过滤每个DropDown的选择。

jquery asp.net-mvc entity-framework stored-procedures cascadingdropdown
1个回答
2
投票

与胖客户端应用程序相比,Web级联下拉列表很复杂且复杂,但这是Web编程!请记住,javascript根本不关心你的MVC内容。您只需要一个Web方法(响应Web URL的方法),它接受一个参数并以正确的格式返回正确的列表。无论它在内部使用什么方法(EF存储过程,硬编码列表,PHP读取文本文件)都没有任何区别

要做你想做的事,你需要在你的下拉列表中添加一个“事件处理程序”,它调用一些调用你的方法来查找正确列表的javascript,然后用该列表填充目标下拉列表。

我会在这里放一些示例代码但是

  • 需要一定程度的“接线”(使用正确的名称)
  • 我要做一些假设
  • 我是从网上学到的,有些语法可能不正确

因此,首先在您的下拉列表中添加一个onchange事件处理程序,以便在更改某些内容时触发一些javascript代码

@Html.DropDownList("Manufacturer", 
                   ViewData["Manufacturer"] as SelectList, 
                   htmlAttributes: 
                         new { @class = "form-control" , 
                               @onchange = "refreshModelFromManufacturer()"
                             }
                   )

当下拉值改变时,它将调用javascript函数refreshModelFromManufacturer()

这是javascript函数。希望你知道如何添加它。它还要求你还有一个名为“Model”的下拉列表(你在视图中没有它,所以添加它):

function refreshModelFromManufacturer()() {
    // 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=Manufacturer
    src = $("#Manufacturer");

    // 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 manufacturer
    // The url parameter points at your web method
    $.ajax({
        type: 'GET',
        url: 'Home/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>'
                        );
                })
            }
        });
    }

这是事情出错的最可能的地方。 Javascript是无情的,区分大小写,并且有太多的括号容易搞砸了。确保你正在使用源代码控制,这样你就可以回滚了,因为有时因为代码在jquery库内部的某个地方失败而无法解决错误的括号,所以没有任何线索

最后一件事是您的Web方法需要是Json类型,以便ajax调用工作

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

    return Json(new SelectList(list, "your id column","your label column"));
}

我的代码中唯一的另一个区别是实际上定义了一个下拉列表,如下所示:

@Html.DropDownList("Customer_ID", null, htmlAttributes: new { @class = "form-
control", @onchange = "refreshProjectFromClient()" })

我认为如果您的ViewBag名称与您的下拉列表相同,那么您不需要显式定义viewbag(我的第二个参数为null)

对于调试(因为这不会第一次工作),请确保您知道如何使用F12调试器来调试javascript以及观察内部Web调用(网络选项卡)。例如,当您运行此命令时,您应该会在网络选项卡中看到对Home/GetModels方法的调用

© www.soinside.com 2019 - 2024. All rights reserved.