ASP.NET MVC Html.DropDownList SelectValue


103

मैंने कोशिश की है यह आरसी 1 है और फिर आरसी 2 में अपग्रेड किया गया जो समस्या का समाधान नहीं करता है।

// in my controller
ViewData["UserId"] = new SelectList(
    users, 
    "UserId", 
    "DisplayName", 
    selectedUserId.Value); // this has a value

परिणाम: SelectValue गुण ऑब्जेक्ट पर सेट किया गया है

// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["UserId"])%>

परिणाम: सभी अपेक्षित विकल्प क्लाइंट को दिए जाते हैं, लेकिन चयनित विशेषता सेट नहीं की जाती है। चयनितवैल्यू में आइटम सूची के भीतर मौजूद है, लेकिन सूची में पहला आइटम हमेशा चयनित के लिए डिफ़ॉल्ट है।

मुझे यह कैसे करना चाहिए?

अपडेट जॉन फेमिनेला के जवाब के लिए धन्यवाद मुझे पता चला कि मुद्दा क्या है। "UserId" मॉडल में एक संपत्ति है जिसे मेरा दृश्य दृढ़ता से टाइप किया गया है। जब Html.DropDownList ("UserId" को किसी अन्य नाम पर बदल दिया जाता है, लेकिन "UserId", चयनित मान सही रूप से प्रदान किया जाता है।

हालांकि यह मूल्य मॉडल के लिए बाध्य नहीं है।


क्या आप निश्चित हैं कि मूल्य सूची में है?
जॉन शीहान

यह समस्या अभी भी ASP.NET MVC के रिलीज़ 1 में मौजूद है
Mathias F

क्या चयनित है !?
फुलवियो

मान लिया जाता है कि आप अपडेट पर मूल्य कैसे बांध सकते हैं, यदि आपके इनपुट का नाम आपकी संपत्ति के समान नहीं है?
ryudice

जवाबों:


68

इस तरह मैंने इस समस्या को ठीक किया:

मेरे पास निम्नलिखित थे:

नियंत्रक:

ViewData["DealerTypes"] = Helper.SetSelectedValue(listOfValues, selectedValue) ;

राय

<%=Html.DropDownList("DealerTypes", ViewData["DealerTypes"] as SelectList)%>

निम्नलिखित द्वारा परिवर्तित:

राय

<%=Html.DropDownList("DealerTypesDD", ViewData["DealerTypes"] as SelectList)%>

ऐसा प्रतीत होता है कि DropDown में समान नाम नहीं होना चाहिए ViewData नाम: S अजीब है लेकिन यह काम किया है।


19
+1 के लिए "ड्रॉपडाउन में एक ही नाम नहीं होना चाहिए ViewData नाम" बिग धन्यवाद
डैनियल डायसन

धन्यवाद!!! आपने मेरी समस्या को हल करने के कई घंटों के बाद हल किया कि यह क्यों काम नहीं किया :)
जेन जेन

1
यह चयनित मूल्य के लिए काम करता है, लेकिन एक समस्या तब उत्पन्न होती है जब आप db में "DealerTypes" को अपडेट करने का प्रयास करते हैं क्योंकि यह DropDownList अब "DealerTypesDD" के लिए बाध्य है जो मॉडल में मौजूद नहीं है। एक वर्कअराउंड एक हिडन फील्ड और htmlAttributes को DropDownList में जोड़ना है: <input type = "hidden" name = "DealerTypes" id = "DealerTypes" value = "" /> <% = Hodml.DropDownList ("DealerTypesDD", ViewData] "DealerTypes"] SelectList के रूप में, नया {@onchange = "DealerTypes.value = this.value"})%>
Zim

3
आप दृश्य नाम में 'DS' जोड़ने से बेहतर हैं, इस प्रकार मॉडल बाइंडिंग को बर्बाद नहीं कर रहे हैं ...
noocyte

1
क्या बकवास है! यह MVC5 में तय नहीं है ??? @Paul हैचर द्वारा उल्लिखित एक और चाल के रूप में, चयनित आईडी को ViewData ["DealerTypes"] में कॉपी करें।
jsgoupil

51

इसे इस्तेमाल करे:

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

और तब:

var list = new[] {   
    new Person { Id = 1, Name = "Name1" }, 
    new Person { Id = 2, Name = "Name2" }, 
    new Person { Id = 3, Name = "Name3" } 
};

var selectList = new SelectList(list, "Id", "Name", 2);
ViewData["People"] = selectList;

Html.DropDownList("PeopleClass", (SelectList)ViewData["People"])

MVC RC2 के साथ, मुझे मिलता है:

<select id="PeopleClass" name="PeopleClass">
    <option value="1">Name1</option>
    <option selected="selected" value="2">Name2</option>
    <option value="3">Name3</option>
</select>

यह कारण को ट्रैक करने में मददगार था। मैंने परिवर्धन को प्रतिबिंबित करने के लिए अपना प्रश्न अपडेट किया है।
ब्लू

मॉडल में पहली बार है? नियंत्रक में दूसरा? और यह देखने में तीसरा स्पष्ट है, लेकिन 2 पहले वाले .. ???
rr

अच्छा जवाब है, लेकिन क्या ViewModel का उपयोग करना बेहतर है?
जेस

@ जेसे: मैंने यह उत्तर मार्च २०० ९ में ५ साल पहले लिखा था। समय बदल गया है! अद्यतन करने के लिए स्वतंत्र महसूस करें। :)
जॉन फेमिनाला

5

आप अभी भी ड्रॉपडाउन को "UserId" नाम दे सकते हैं और अभी भी मॉडल बाइंडिंग आपके लिए सही तरीके से काम कर रहा है।

इसके लिए काम करने के लिए एकमात्र आवश्यकता यह है कि ViewData कुंजी जिसमें SelectList सम्‍मिलित है, मॉडल गुण के समान नाम नहीं है जिसे आप बाइंड करना चाहते हैं। आपके विशिष्ट मामले में यह होगा:

// in my controller
ViewData["Users"] = new SelectList(
    users, 
    "UserId", 
    "DisplayName", 
    selectedUserId.Value); // this has a value

// in my view
<%=Html.DropDownList("UserId", (SelectList)ViewData["Users"])%>

यह एक चयनित तत्व का उत्पादन करेगा जिसका नाम UserId है, जिसका आपके मॉडल में UserId गुण के समान नाम है और इसलिए मॉडल बाइंडर इसे HTML के चयन तत्व में चयनित मान के साथ सेट करेगा, जो कि Html.DropDownerist सहायक द्वारा उत्पन्न किया गया है।

मुझे यकीन नहीं है कि उस विशेष Html.DropDownList कंस्ट्रक्टर को SelectList में निर्दिष्ट मूल्य का चयन नहीं किया जाएगा, जब आप संपत्ति के नाम के बराबर कुंजी सूची के साथ ViewData में चयन सूची डालते हैं। मुझे संदेह है कि इसका कुछ और है कि कैसे ड्रॉपडाउनिस्ट हेल्पर का उपयोग अन्य परिदृश्यों में किया जाता है, जहां सम्मेलन यह है कि आपके पास अपने मॉडल में संपत्ति के समान नाम के साथ ViewData में एक SelectList है। यह सही ढंग से काम करेगा:

// in my controller
ViewData["UserId"] = new SelectList(
    users, 
    "UserId", 
    "DisplayName", 
    selectedUserId.Value); // this has a value

// in my view
<%=Html.DropDownList("UserId")%>

बहुत बहुत धन्यवाद, सभी जवाबों के लिए यह मेरे लिए काम किया है, न जाने क्यों लेकिन यह किया
Lamin Sanneh

आखिरकार! घंटों की कोशिश के बाद आखिरकार मुझे आपकी "केवल आवश्यकता" ही मिली। यही किया।
स्टीवकेव

2

अगर हमें नहीं लगता कि यह एक बग है जिसे टीम को ठीक करना चाहिए, तो पट्टे पर MSDN को दस्तावेज़ में सुधार करना चाहिए। भ्रामक वास्तव में इस के खराब दस्तावेज़ से आता है। में MSDN , यह मापदंडों बताते हैं नाम , के रूप में

Type: System.String
The name of the form field to return.

इसका मतलब यह है कि अंतिम html जो उत्पन्न करता है, उस पैरामीटर का चयन इनपुट के नाम के रूप में करेगा। लेकिन, इसका असल में मतलब इससे कहीं ज्यादा है।

मुझे लगता है कि डिज़ाइनर मानता है कि उपयोगकर्ता ड्रॉपडेललिस्ट को प्रदर्शित करने के लिए एक दृश्य मॉडल का उपयोग करेगा, पोस्ट व्यू का भी उसी मॉडल से उपयोग करेगा । लेकिन कई मामलों में, हम वास्तव में उस धारणा का पालन नहीं करते हैं।

उपरोक्त उदाहरण का उपयोग करें,

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

यदि हम धारणा का पालन करते हैं, तो हमें इस ड्रॉपडेलिस्ट से संबंधित दृश्य के लिए एक दृश्य मॉडल को परिभाषित करना चाहिए

public class PersonsSelectViewModel{
    public string SelectedPersonId,
    public List<SelectListItem> Persons;
}

क्योंकि जब वापस पोस्ट किया जाता है, तो केवल चयनित मान वापस आ जाएगा, इसलिए यह मान लें कि यह मॉडल की संपत्ति के लिए वापस चुना जाना चाहिए SelectPersonId, जिसका अर्थ है कि Html.DropDownList का पहला पैरामीटर नाम ' SelectPersonId ' होना चाहिए। इसलिए, डिज़ाइनर को लगता है कि जब दृश्य में मॉडल दृश्य प्रदर्शित होता है, तो मॉडल की संपत्ति चयनितPersonId को उस ड्रॉपडाउन सूची का डिफ़ॉल्ट मान रखना चाहिए। यहां तक ​​कि आपकी सूची <SelectListItem> व्यक्तियों ने पहले से ही चयनित ध्वज को यह निर्धारित करने के लिए निर्धारित किया है कि कौन सा चयनित / डिफ़ॉल्ट है, tml.DropDownList वास्तव में इसे अनदेखा करेगा और इसे स्वयं IEnumerable <SelectListItem> के पुनर्निर्माण और नाम के आधार पर डिफ़ॉल्ट / चयनित आइटम सेट करेगा।

यहाँ asp.net mvc से कोड है

private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
            string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
            IDictionary<string, object> htmlAttributes)
{
    ...

    bool usedViewData = false;

    // If we got a null selectList, try to use ViewData to get the list of items.
    if (selectList == null)
    {
        selectList = htmlHelper.GetSelectData(name);
        usedViewData = true;
    }

    object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));

    // If we haven't already used ViewData to get the entire list of items then we need to
    // use the ViewData-supplied value before using the parameter-supplied value.
    if (defaultValue == null && !String.IsNullOrEmpty(name))
    {
        if (!usedViewData)
        {
            defaultValue = htmlHelper.ViewData.Eval(name);
        }
        else if (metadata != null)
        {
            defaultValue = metadata.Model;
        }
    }

    if (defaultValue != null)
    {
        selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
    }

    ...

    return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}

तो, कोड वास्तव में और आगे बढ़ गया, यह न केवल मॉडल में नाम देखने की कोशिश करता है, बल्कि व्यूडेटा में भी, जैसे ही यह एक पाता है, यह चयनकर्ता को फिर से बनाएगा और आपके मूल चयनित को अनदेखा करेगा।

समस्या यह है कि बहुत सारे मामलों में, हम वास्तव में इसका उपयोग नहीं करते हैं। हम सिर्फ एक / एक से अधिक आइटम के साथ एक चयन सूची में फेंकना चाहते हैं।

बेशक समाधान सरल है, एक नाम का उपयोग करें जो न तो मॉडल में और न ही दृश्यता में। जब यह एक मैच नहीं मिल सकता है, तो यह मूल चयनकर्ता का उपयोग करेगा और मूल चयनित प्रभावित करेगा।

लेकिन मुझे अभी भी लगता है कि पीवीसी को एक और शर्त जोड़कर इसे सुधारना चाहिए

if ((defaultValue != null) && (!selectList.Any(i=>i.Selected)))
{
    selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}

क्योंकि, यदि मूल चयनकर्ता पहले से ही एक का चयन कर चुका है, तो आप उसे अनदेखा क्यों करेंगे?

बस मेरे विचार।


यह वास्तव में मैंने अब तक पढ़ा सबसे अच्छा स्पष्टीकरण है। मुझे बहुत सिरदर्द से बचाया। मुझे केवल इतना करना था कि दृश्यमॉडल की संपत्ति का मूल्य निर्धारित किया जाए और यह काम करे। धन्यवाद।
मूसा मचुआ

2

पिछले MVC 3 पोस्ट में कोड काम नहीं करता है लेकिन यह एक अच्छी शुरुआत है। मैं इसे ठीक कर दूंगा। मैंने इस कोड का परीक्षण किया है और यह MVC 3 रेजर सी # में काम करता है। यह कोड प्रॉपर्टी को पॉप्युलेट करने के लिए ViewModel पैटर्न का उपयोग करता है List<SelectListItem>

मॉडल वर्ग

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

ViewModel वर्ग

using System.Web.Mvc;

public class ProductListviewModel
{
    public List<SelectListItem> Products { get; set; }
}

नियंत्रक विधि

public ViewResult List()
{
    var productList = new List<SelectListItem>();

    foreach (Product p in Products)
    {
        productList.Add(new SelectListItem
        {
            Value = p.ProductId.ToString(),
            Text = "Product: " + p.Name + " " + p.Price.ToString(),
            // To set the selected item use the following code 
            // Note: you should not set every item to selected
            Selected = true
        });
    }

    ProductListViewModel productListVM = new ProductListViewModeld();

    productListVM.Products = productList;

    return View(productListVM);
}

दृश्य

@model MvcApp.ViewModels.ProductListViewModel

@using (Html.BeginForm())
{
    @Html.DropDownList("Products", Model.Products)
}

HTML आउटपुट कुछ इस तरह होगा

<select id="Products" name="Products">
    <option value="3">Product: Widget 10.00</option>
    <option value="4">Product: Gadget 5.95</option>
</select>

आप आउटपुट को कैसे स्वरूपित करते हैं, उसके आधार पर। आशा है कि ये आपकी मदद करेगा। कोड काम करता है।


1
यह selectedविकल्प सेट नहीं करता है ।
जेस

SelectListItem का उपयोग करके चयनित आइटम को सेट करने के लिए, चयनित संपत्ति को सही पर सेट करें।
wayne.blackmon

1

यह SelectExtensions वर्ग में एक बग प्रतीत होता है क्योंकि यह केवल चयनित आइटम के लिए मॉडल के बजाय ViewData की जांच करेगा। तो चाल संपत्ति के नाम के तहत ViewData संग्रह में मॉडल से चयनित आइटम की प्रतिलिपि बनाने के लिए है।

यह एमवीसी मंचों पर मेरे द्वारा दिए गए उत्तर से लिया गया है, मेरे पास एक ब्लॉग पोस्ट में एक और अधिक पूर्ण उत्तर है जो काजी के ड्रॉपडाउनलिस्ट विशेषता का उपयोग करता है ...

एक मॉडल दिया

public class ArticleType
{
   public Guid Id { get; set; }
   public string Description { get; set; }
}

public class Article
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public ArticleType { get; set; }
}

और एक बुनियादी दृश्य मॉडल

public class ArticleModel
{
     public Guid Id { get; set; }
     public string Name { get; set; }

     [UIHint("DropDownList")]
     public Guid ArticleType { get; set; }
}

तो हम एक DropDownList संपादक टेम्पलेट निम्नानुसार लिखते हैं ..

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script runat="server">  
    IEnumerable<SelectListItem> GetSelectList()
    {
        var metaData = ViewData.ModelMetadata;
        if (metaData == null)
        {
            return null;
        }

        var selected = Model is SelectListItem ? ((SelectListItem) Model).Value : Model.ToString();
        ViewData[metaData.PropertyName] = selected;

        var key = metaData.PropertyName + "List";
        return (IEnumerable<SelectListItem>)ViewData[key];
    }
</script>
<%= Html.DropDownList(null, GetSelectList()) %>

यह तब भी काम करेगा जब आप ArticleType को व्यू मॉडल में SelectListItem में बदलते हैं, हालांकि आपको काज़ी के ब्लॉग के अनुसार एक प्रकार का कनवर्टर लागू करना होगा और इसे एक सरल प्रकार के रूप में व्यवहार करने के लिए बाइंडर को बाध्य करने के लिए पंजीकृत करना होगा।

आपके नियंत्रक में हम तब ...

public ArticleController 
{
     ...
     public ActionResult Edit(int id)
     {
          var entity = repository.FindOne<Article>(id);
          var model = builder.Convert<ArticleModel>(entity);

          var types = repository.FindAll<ArticleTypes>();
          ViewData["ArticleTypeList"] = builder.Convert<SelectListItem>(types);

          return VIew(model);
     }
     ...
}

उत्तर के लिए धन्यवाद, मुझे इसकी जाँच करनी होगी।
ब्लू

0

समस्या यह है कि ड्रॉपबॉक्स सूची बॉक्स के समान काम नहीं करता है, कम से कम जिस तरह से ASP.NET MVC2 डिजाइन की उम्मीद है: एक ड्रॉपबॉक्स केवल शून्य या एक मान की अनुमति देता है, क्योंकि सूची बॉक्स में एक से अधिक मूल्य चयन हो सकते हैं। इसलिए, HTML के साथ सख्त होने के कारण, यह मूल्य "चयनित" ध्वज के रूप में विकल्प सूची में नहीं होना चाहिए, लेकिन इनपुट में ही।

निम्न उदाहरण देखें:

<select id="combo" name="combo" value="id2">
  <option value="id1">This is option 1</option>
  <option value="id2" selected="selected">This is option 2</option>
  <option value="id3">This is option 3</option>
</select>

<select id="listbox" name="listbox" multiple>
  <option value="id1">This is option 1</option>
  <option value="id2" selected="selected">This is option 2</option>
  <option value="id3">This is option 3</option>
</select>

कॉम्बो में चयनित विकल्प है, लेकिन इसके मूल्य विशेषता सेट भी हैं । इसलिए, यदि आप एक ड्रॉपबॉक्स रेंडर करने के लिए ASP.NET MVC2 चाहते हैं और इसमें एक विशिष्ट मान भी चुना गया है (यानी, डिफ़ॉल्ट मान, आदि), तो आपको इसे इस तरह प्रदान करना चाहिए:

// in my view             
<%=Html.DropDownList("UserId", selectListItems /* (SelectList)ViewData["UserId"]*/, new { @Value = selectedUser.Id } /* Your selected value as an additional HTML attribute */)%>

0

ASP.NET MVC 3 में आप केवल ViewData में अपनी सूची जोड़ सकते हैं ...

var options = new List<SelectListItem>();

options.Add(new SelectListItem { Value = "1", Text = "1" });
options.Add(new SelectListItem { Value = "2", Text = "2" });
options.Add(new SelectListItem { Value = "3", Text = "3", Selected = true });

ViewData["options"] = options;

... और फिर इसे अपने रेजर व्यू में नाम से देखें ...

@Html.DropDownList("options")

आपको ड्रॉपडाउनलिस्ट कॉल में सूची को मैन्युअल रूप से "उपयोग" नहीं करना है। इस तरह से करना मेरे लिए चयनित मूल्य को भी सही ढंग से निर्धारित करता है।

अस्वीकरण:

  1. वेब रूपों दृश्य इंजन के साथ यह कोशिश नहीं की है, लेकिन यह भी काम करना चाहिए।
  2. मैंने v1 और v2 में इसका परीक्षण नहीं किया है, लेकिन यह काम कर सकता है।

0

मैं वांछित परिणाम प्राप्त करने में कामयाब रहा, लेकिन थोड़ा अलग दृष्टिकोण के साथ। ड्रॉपडेललिस्ट में मैंने मॉडल का उपयोग किया और फिर इसे संदर्भित किया। यकीन नहीं होता कि यह वही था जो आप ढूंढ रहे थे।

@Html.DropDownList("Example", new SelectList(Model.FeeStructures, "Id", "NameOfFeeStructure", Model.Matters.FeeStructures))

ऊपर में Model.Matters.FeeStructures मेरी आईडी है, जो उस आइटम का आपका मूल्य हो सकता है जिसे चुना जाना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.