2011-01-18 15 views
6

के बजाय DropDownListFor में व्यूबैग संपत्ति मूल्य ड्रॉपडाउन लिस्टफ़ोर (एएसपी.नेट एमवीसी 3 रिलीज) में हमें अजीब व्यवहार मिला। यह ड्रॉपडाउन में मॉडल प्रॉपर्टी वैल्यू के बजाय व्यूबैग प्रॉपर्टी वैल्यू का चयन करता है।मॉडल संपत्ति मूल्य

मॉडल:

public class Country { 
    public string Name { get; set; } 
} 
public class User { 
    public Country Country { get; set; } 
} 

नियंत्रक सूचकांक कार्रवाई:

ViewBag.CountryList = new List<Country> { /* Dropdown collection */ 
    new Country() { Name = "Danmark" }, 
    new Country() { Name = "Russia" } }; 

var user = new User(); 
user.Country = new Country(){Name = "Russia"}; /* User value */ 
ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */ 
return View(user); 

दृश्य:

@Html.EditorFor(user => user.Country.Name)  
@Html.DropDownListFor(user => user.Country.Name, 
    new SelectList(ViewBag.CountryList, "Name", "Name", Model.Country), "...") 

यह साथ "Danmark" मूल्य "रूस" मूल्य और ड्रॉप डाउन से पाठ बॉक्स में दिखाई देंगे "रूस" के बजाय चुना गया।

मुझे इस व्यवहार के बारे में कोई दस्तावेज नहीं मिला। क्या यह व्यवहार सामान्य है? और यह सामान्य क्यों है? क्योंकि व्यूबैग और मॉडल गुणों के नामों को नियंत्रित करना बहुत मुश्किल है।

ViewBag.Country = new Country() { Name = "Danmark" }; /* It affects user */ 

है ऐसा इसलिए है क्योंकि एचटीएमएल सहायकों कुछ विभिन्न स्थानों पर गौर उत्पन्न नियंत्रण के लिए मूल्यों को लेने के लिए:

This sample MVC3 project sources

उत्तर

5

मुझे यकीन नहीं है कि यह निर्णय क्यों बनाया गया था, लेकिन ऐसा इसलिए हुआ क्योंकि एमवीसी ढांचे ने पैरामीटर-आपूर्ति मूल्य का उपयोग करने से पहले व्यूडेटा-आपूर्ति मूल्य का उपयोग करने की कोशिश की। यही कारण है कि ViewBag.Country पैरामीटर-आपूर्ति मूल्य Model.Country ओवरराइड करें।

यह कैसे निजी विधि SelectInternal में MVC ढांचे में written था था।

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 (!usedViewData) { 
    if (defaultValue == null) { 
     defaultValue = htmlHelper.ViewData.Eval(fullName); 
    } 
} 

if (defaultValue != null) { 
    IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue }; 
    IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture); 
    HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase); 
    List<SelectListItem> newSelectList = new List<SelectListItem>(); 

    foreach (SelectListItem item in selectList) { 
     item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text); 
     newSelectList.Add(item); 
    } 
    selectList = newSelectList; 
} 

इस कोड defaultValue = htmlHelper.ViewData.Eval(fullName);ViewData से मूल्य प्राप्त करने की कोशिश की और अगर यह मूल्य प्राप्त कर सकते हैं, यह नई सूची के साथ आपूर्ति पैरामीटर selectList पार कर जाएगी।

उम्मीद है कि यह मदद कर सकता है। धन्यवाद।

साइड-नोड: व्यूबैग व्यूडाटा का एक गतिशील रैपर वर्ग है।

4

अपनी कार्रवाई विधि से निम्न पंक्ति क्या कोड भ्रामक है। इस मामले में ViewData["Country"]ModelState["Country"] के साथ संघर्ष कर रहा है उस संपत्ति को किसी अन्य चीज़ का नाम दें और सब कुछ काम करना चाहिए।

+0

क्या आप हमेशा नामकरण से बचने के लिए व्यूबैग संपत्ति नाम के उपसर्ग का सुझाव देते हैं? पूर्व। ViewBag.ViewBag_Country –

+0

पवित्र बकवास, आप सही हैं। इसके लिए धन्यवाद ... मेरे दिन बचाया ... :) – dizzwave

संबंधित मुद्दे