如何使用Api Controller中的GET方法返回的IEnumerable填充DropDownList?

时间:2017-11-18 02:30:17

标签: c# jquery asp.net-mvc

我不熟悉MVC中的网络应用。在过去的两天里,我研究过很多东西,但没有一个适用于我;我使用的是ApiController,而不是Controller,所以我不能做像"返回View(模型)"这样的事情。

如果您可以帮助我了解如何将这些内容联系在一起或显示我的问题,那将非常感激!

情况: 我想创建一个具有级联下拉列表的Web应用程序;用于选择汽车品牌的第一个列表,以及显示所选品牌的汽车型号的第二个列表。列表和提交按钮将在AJAX表单中。

问题: 我只是想知道,如何在我的ApiController中使用GET方法填充第一个下拉列表 on page load ,它返回一个IEnumerable的汽车制作? 然后我可以从那里去。请记住,稍后我会有第二个下拉列表根据第一个填充/更新,所以我希望下拉列表的填充在客户端完成。

我尝试了什么:

  1. 使用HTML.DropDownListFor创建列表,但是 HTML.DropDownListFor始终得到"对象引用未设置为 对象的实例"。我也使用Ajax.BeginForm,但不确定是否可以 实际上调用返回IEnumerable的GET方法并将其添加到 列表。
  2. 使用$(document).ready()来使用getJSON来获取汽车 ApiController方法,但getJSON不会触发。
  3. 我可能在某处出现了一些非常严重的错误,因为我无法填写任何内容,我仍在学习。非常感谢你的帮助!我现在将展示我的代码,以及我尝试过的一些替代代码。

    首先是我的Model类:

        public class Make
        {
            public int MakeId { get; set; }
            public string MakeName { get; set; }
        }
    
        public class Model
        {
            public int ModelId { get; set; }
            public string ModelName { get; set; }
            public int MakeId { get; set; }
        }
    
        public class MakeViewModel
        {
            public int SelectedMakeId { get; set; }
            public IEnumerable<Make> MakesList { get; set; }
        }
    

    这是我的带有两个GET方法的Vehicle ApiController,Makes()和Models(int makeID),每个返回IEnumerable。它们最终将使用本地xml,但为了简单起见,我将其删除,每个只返回一个Make或Model项的List。

    public class VehicleController : ApiController
    {
        [System.Web.Http.HttpGet]
        public IEnumerable<Make> Makes()
        {
            List<Make> makesList = new List<Make>();
    
            //Code for consuming from xml file will go here
    
            //For now, add one test make to the list
            Make maketest = new Make();
            maketest.MakeId = 1;
            maketest.MakeName = "MakeTest";
            makesList.Add(maketest);
    
            //return List of the one test make
            return makesList;
        }
    
        [System.Web.Http.HttpGet]
        public IEnumerable<Model> Models(int id)
        {
            List<Model> modelsList = new List<Model>();
    
            //Code for consuming from xml file will go here
    
            //For now, add one test model to the list
            Model modeltest = new Model();
            modeltest.ModelId = 1;
            modeltest.ModelName = "ModelTest";
            modeltest.MakeId = 1;
            modelsList.Add(modeltest);
    
            //return List of the one test model
            return modelsList;
        }
    }
    

    这是我的Index.cshtml,它加载了部分视图_Form.cshtml

    <h2>Vehicle Selector</h2>
    @{
        ViewBag.Title = "Home Page";
        @Html.Partial("_Form");
    }
    

    最后是我的部分视图_Form.cshtml;我将只显示第一个下拉列表的文件的前半部分。 在顶部,我包括模型MakeViewModel,我们可以在这里找到我们的汽车制造列表..

    @model VehicleMVC.Models.MakeViewModel
    <script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" 
        type="text/javascript"></script>
    

    我使用Ajax.BeginForm()从我的VehicleController调用GET方法Makes()来更新我的make_DDL,因为我希望在加载页面时填充列表。老实说问题可能在这里,因为我不相信它是对的。

    @using (Ajax.BeginForm("Makes", "Vehicle", new AjaxOptions
        {
            HttpMethod = "GET",
            UpdateTargetId = "makes_DDL"
        }))
    

    我使用Html.DropDownListFor()来创建makes_DDL列表,尽管它总是给我&#34;对象引用未设置为对象的实例&#34;错误。

    @Html.DropDownListFor(model => model.SelectedMakeId,
        (SelectList)Model.MakesList, new { @class = "makes_DDL" })
    

    提前非常感谢你!

    我试过的一些事情: 我尝试使用新的SelectList,但没有运气:

    @Html.DropDownListFor(model => model.SelectedMakeId, new 
        SelectList(Model.MakesList, "MakeId", "MakeName"))
    

    然后我尝试对make的测试列表进行硬编码,但同样的&#34;对象引用未设置为对象的实例&#34;错误。

    @Html.DropDownListFor(model => model.SelectedMakeId,
        new SelectList( new List<VehicleMVC.Models.Make>
        {
            new VehicleMVC.Models.Make { MakeId = 0, MakeName = "SmallCar"},
            new VehicleMVC.Models.Make { MakeId = 1, MakeName = "BigCar"}
        },
        "value", "text", 0), new { @class = "makes_DDL" })
    

    由于我非常确定Ajax.BeginForm没有按照我的意愿行事(从我的VehicleController调用GET Makes()方法来填充makes_DDL列表),我尝试使用$(document).ready()来使用getJSON使用路线&#34; api / vehicle&#34;应该调用Makes(),但它似乎不会触发getJSON,因为我放入的警报并不会触发。

    <script type="text/javascript">
        function getMakes() {
            $.getJSON("api/vehicle",
                function (data) {
                    //This alert doesn't fire, so it seems getJSON is not firing?             
                     window.alert(1);
                    //Code would later go here for appending the makes from the 
                      returned IEnumerable to the makes_DDL list
                });
        }
    
    $(document).ready(getMakes);
    </script>
    

1 个答案:

答案 0 :(得分:0)

您可以使用@Html.DropDownListFor标记,而不是使用<select>

 <select id="SelectedMakeId" name="SelectedMakeId"></select>

然后您可以使用getJson作为

填充它
 $(document).ready(function (e) {
     $.getJSON("http://localhost:2390/api/vehicle", function (data) {
        $.each(data, function (index, value) {
             $("#SelectedMakeId").append("<option value=" + value.MakeId + ">" + value.MakeName + "</option>");
        });
    });
});

请注意,您必须提供正确的api方法网址。 http://localhost:2390/api/vehicle,你必须提供自己的路径。

你可以尝试这个

您也可以使用ViewBag。为此,请执行以下操作,

<强> 1。将路线设置为api方法Makes()

     [System.Web.Http.Route("api/Vehicle/MakersList")] 
     [System.Web.Http.HttpGet]
     public IEnumerable<Make> Makes()
     {
        ...
     }

<强> 2。更改Index方法

添加使用api方法的GetMakers()方法。使用此GetMakers()初始化ViewBag.listMakers

     private string MAKER_URL = "http://localhost:2390/api/vehicle";
     public ActionResult Index()
     {
            ViewBag.listMakers = new SelectList(GetMakers(), "MakeId","MakeName");
            return View();
     }

     public IEnumerable<Make> GetMakers()
     {
       try
            {
                HttpClient client = new HttpClient();
                client.BaseAddress = new Uri(MAKER_URL);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = client.GetAsync("vehicle/MakersList").Result;
                if (response.IsSuccessStatusCode)
                    return response.Content.ReadAsAsync<IEnumerable<Make>>().Result;
                return null;
            }
            catch
            {
                return null;
            }

     }

第3。将@Html.DropDownListFor重写为

@Html.DropDownListFor(model => model.SelectedMakeId, (IEnumerable<SelectListItem>)ViewBag.listMakers, "---Select---", new { @class = "makes_DDL" })