अगर हमें नहीं लगता कि यह एक बग है जिसे टीम को ठीक करना चाहिए, तो पट्टे पर 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);
}
क्योंकि, यदि मूल चयनकर्ता पहले से ही एक का चयन कर चुका है, तो आप उसे अनदेखा क्यों करेंगे?
बस मेरे विचार।