2012-04-12 40 views
6

mô hình của tôi là như sau:On Post, một danh sách thả xuống SelectList.SelectedValue là null

public class testCreateModel 
{ 
    public string s1 { get; set; } 
    public SelectList DL { get; set; } 

    public testCreateModel() 
    { 
     Dictionary<string, string> items = new Dictionary<string, string>(); 
     items.Add("1", "Item 1"); 
     items.Add("2", "Item 2"); 
     DL = new SelectList(items, "Key", "Value"); 
    } 
} 

hành động bắt đầu của tôi là:

public ActionResult testCreate() 
    { 
     testCreateModel model = new testCreateModel(); 
     return View(model); 
    } 

xem Razor của tôi (phần không liên quan đã bị xóa) là:

@model Tasks.Models.testCreateModel 

@using (Html.BeginForm()) { 
<fieldset> 
    <legend>testCreateModel</legend> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.s1) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.s1) 
    </div> 

    <div class="editor-label"> 
     Select an item: 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("dropdownlist", (SelectList)Model.DL) 
    </div> 

    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

hành động bài lại là:

public ActionResult testCreate(testCreateModel model, FormCollection collection) 
    { 
     if (ModelState.IsValid) 
     { 
      Console.WriteLine("SelectedValue: ",model.DL.SelectedValue); 
      Console.WriteLine("FormCollection:", collection["dropdownlist"]); 
      // update database here... 
     } 
     return View(model); 
    } 

Khi đăng lại, model.DL.SelectedValue là null. (Tuy nhiên, mục đã chọn có thể thu được từ FormCollection, nhưng đó là ngoài điểm). Đối tượng DL vẫn được điền đúng cách, Cửa sổ ngay lập tức xuất như sau:

model.DL 
{System.Web.Mvc.SelectList} 
    base {System.Web.Mvc.MultiSelectList}: {System.Web.Mvc.SelectList} 
    SelectedValue: null 
model.DL.Items 
Count = 2 
    [0]: {[1, Item 1]} 
    [1]: {[2, Item 2]} 
model.DL.SelectedValue 
null 

Q1: Làm cách nào để sử dụng thuộc tính SelectedValue?

Bây giờ, nếu trong giao diện Razor tôi thay đổi tên của thẻ Html SELECT để DL (tức là giống như tên thuộc tính trong mô hình):

@Html.DropDownList("DL", (SelectList)Model.DL) 

tôi nhận được một ngoại lệ:

No parameterless constructor defined for this object. 
Stack Trace: 
[MissingMethodException: No parameterless constructor defined for this object.] 
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98 
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69 
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +199 
System.Web.Mvc.DefaultModelBinder.BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult 
... 

Q2: Tại sao?

Cảm ơn.

Trả lời

11

MVC sẽ chỉ trả lại giá trị của tùy chọn đã chọn trong POST của bạn, vì vậy bạn cần một thuộc tính để chứa giá trị duy nhất trả về.

Là một lời khuyên tốt, hãy thử đặt SelectLists thông qua ViewBag, giúp giữ cho Chế độ xem của bạn luôn sạch sẽ khỏi dữ liệu cần điền vào biểu mẫu.

Vì vậy, ví dụ bạn có thể được giải quyết như thế này:

public class testCreateModel 
{ 
    public string s1 { get; set; } 
    public int SelectedValue { get; set; } 
} 

và trong View của bạn chỉ làm điều này:

@Html.DropDownList("SelectedValue", (SelectList)ViewBag.DL) 

trước Populating ViewBag.DL trong hành động GET của bạn.

Đối với Q2 của bạn, mặc định ModelBinder đòi hỏi tất cả các loại để ràng buộc để có một constructor mặc định (để ModelBinder có thể tạo ra chúng)

+0

Cảm ơn bạn đã sử dụng phương pháp được đề xuất sử dụng danh sách thả xuống. Nó hoạt động và có ít công việc cần thiết để nhận giá trị đã chọn! –

+0

Xin cảm ơn, đây là bài viết hay nhất mà tôi đã giới thiệu về việc sử dụng danh sách thả xuống trong mvc –

10

Một câu trả lời đã được chọn, nhưng nhìn vào cách tôi đã làm nó. Dưới đây là mã tôi thường làm như thế nào khi populating một thả xuống. Nó rất đơn giản, tôi đề nghị bạn sử dụng nó như là một cơ sở để xây dựng thả xuống của bạn.

Ở phía trên của quan điểm của tôi tôi chỉ định mô hình quan điểm của tôi:

@model MyProject.ViewModels.MyViewModel 

Theo quan điểm của tôi, tôi có một danh sách thả xuống để hiển thị tất cả các ngân hàng mà người dùng có thể lựa chọn từ:

<table> 
    <tr> 
      <td><b>Bank:</b></td> 
      <td> 
       @Html.DropDownListFor(
        x => x.BankId, 
        new SelectList(Model.Banks, "Id", "Name", Model.BankId), 
        "-- Select --" 
       ) 
       @Html.ValidationMessageFor(x => x.BankId) 
      </td> 
    </tr> 
</table> 

Tôi luôn có một kiểu xem cho một khung nhìn, tôi không bao giờ chuyển đối tượng miền trực tiếp tới khung nhìn. Trong trường hợp này mô hình quan điểm của tôi sẽ bao gồm một danh sách các ngân hàng sẽ được áp dụng từ cơ sở dữ liệu:

public class MyViewModel 
{ 
    // Other properties 

    public int BankId { get; set; } 
    public IEnumerable<Bank> Banks { get; set; } 
} 

mô hình miền ngân hàng của tôi:

public class Bank 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

Sau đó, trong phương pháp hành động của tôi, tôi tạo ra một thể hiện của tôi xem mô hình và điền danh sách ngân hàng từ cơ sở dữ liệu. Khi việc này hoàn tất, tôi trả lại kiểu xem cho chế độ xem:

public ActionResult MyActionMethod() 
{ 
    MyViewModel viewModel = new ViewModel 
    { 
      // Database call to get all the banks 
      // GetAll returns a list of Bank objects 
      Banks = bankService.GetAll() 
    }; 

    return View(viewModel); 
} 

[HttpPost] 
public ActionResult MyActionMethod(MyViewModel viewModel) 
{ 
    // If you have selected an item then BankId would have a value in it 
} 

Tôi hy vọng điều này sẽ hữu ích.

+0

Tuyệt vời và cảm ơn bạn đã chia sẻ. Tuy nhiên, tôi gặp sự cố khi truy xuất dữ liệu ở dạng đăng lại biểu mẫu. Bất kỳ ý tưởng? Cảm ơn –

Các vấn đề liên quan