2017-11-18 91 views
0

我是MVC中的web應用程序的新手。在過去的兩天裏,我研究並嘗試了很多東西,但沒有一個適用於我;我使用ApiController,而不是控制器,所以我不能做像「返回視圖(模型)」的東西。如何使用從Api控制器中的GET方法返回的IEnumerable填充DropDownList?

如果你能幫助我理解如何將這些東西連接在一起或顯示我的問題在哪裏將非常感謝!

情況: 我想製作一個具有級聯下拉列表的網絡應用程序;第一個選擇汽車製造商名單,第二個名單顯示所選製造商的汽車型號。列表和提交按鈕將在AJAX表單中。

問題: 我只是想知道,我怎麼能填充第一個下拉頁面加載列表,用我的ApiController一個GET方法返回的汽車製造一個IEnumerable? 然後我可以從那裏去。請記住,稍後我將有第二個下拉列表根據第一個下拉列表填充/更新,因此我希望下拉列表的填充位置在客戶端完成。

我試了一下:

  1. 使用HTML.DropDownListFor創建列表,但 HTML.DropDownListFor總是得到「未將對象引用設置到對象的實例 」。我也使用Ajax.BeginForm,但不知道 是否可以實際調用返回IEnumerable的GET方法,並將其添加到 列表中。
  2. 使用$(document).ready()來使用getJSON來獲取從我的 ApiController方法獲得的汽車,但getJSON不會觸發。

我可能在某個地方發生了很大的錯誤,因爲我無法獲得任何東西來填充我的列表,而且我仍在學習。非常感謝您的幫助!我現在將顯示我的代碼,以及我嘗試過的一些替代代碼。


首先是我的模型類:

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方法,使()和模式(INT makeID),每個返回IEnumerable的車輛ApiController。他們最終會從本地xml中消費,但現在爲了簡單起見,我將其刪除,每個只返回一個Make或Model項目的列表。

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()調用GET方法使()從我VehicleController更新我的makes_DDL,因爲我希望頁面加載時填充列表。老實說問題可能在這裏,因爲我不確定它是正確的。

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

我用Html.DropDownListFor()創建makes_DDL列表,雖然它總是給我的錯誤「不設置到對象的實例對象引用」。

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

非常感謝你提前!


有些事情我想: 我嘗試使用新的SelectList,但沒有運氣:

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

然後我試圖硬編碼品牌的測試列表,但相同的「對象未設置到一個對象的實例「錯誤。

@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_DDL列表)是什麼,我試圖用$(文件)。就緒()使用getJSON來使用應該調用Makes()的路由「api/vehicle」,但它似乎不會觸發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> 
+0

你爲什麼不能填充你的第一個下拉列表中的內容在你的MVC操作方法,使您的看法?您正在獲取空引用異常,因爲「Model.MakesList」可能爲空。或'Model'可能爲空。您尚未分享GET操作的外觀。 – Shyju

+0

建議你看看[這個DotNetFiddle](https://dotnetfiddle.net/1bPZym)中的代碼 - 它的MVC,但應該給你的基本綱要 –

+0

拍攝,我認爲你是對的。我只是意識到我似乎沒有任何實際將製作放入我的MakesViewModel中的MakesList中的任何東西。我記得其他人使用Controller類而不是ApiController似乎做了類似「return View(obj)」的事情。 能否詳細介紹一下我將如何將從我的VehicleController中的方法返回的汽車的IEnumerable存儲到我的Model(我的MakeViewModel類中的MakesList)中?我很困惑,因爲它似乎不應該使用像ActionResult Index()這樣的東西。 謝謝你的回覆! –

回答

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方法

添加GetMakers()方法消耗API方法。使用此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" }) 
+0

噢謝謝你的回覆!我創建了第二個類似的列表,但沒有想到只是完全刪除Html.DropDownListFor並且還使用getJSON作爲第一個列表。謝謝,我會試試看! –

+0

@YoshiKirishima查看最新的答案.. –

+0

再次感謝你!我將探索這兩種選擇。第一個對我來說效果不錯!我的getJSON遇到問題,因爲我認爲我應該遵循RouteConfig中的路由URL,而不是WebApiConfig中的URL。一旦我使用地址API /車輛/而不是API /車輛,它的工作! –

相關問題