c# कैसे एक MVC.net वेब पेज में @ एचटीएमएल.लिस्टबॉक्स से बनाया गया एक चयन में सभी मानों को जारी रखता है?




asp.net-mvc listbox (3)

समस्या: मैं एक @Html.ListBoxFor मेरे HttpGet में एक डेटाबेस क्वेरी के आधार पर उत्पन्न। मेरे एचटीटीपी पोस्ट के दौरान, मुझे यह मान्य करना है कि कम से कम एक तत्व का चयन किया गया है। यदि नहीं, तो मैं सिर्फ एक सत्यापन संदेश जोड़ना चाहता हूं।

वर्तमान परिणाम: मुझे संदेश मिलता है "कृपया कम से कम एक आइटम का चयन करें" लेकिन अब चयन रिक्त है (चयन तत्व है लेकिन इसमें 0 विकल्प हैं)। मैं समझता हूं कि Model.Items । मेरी Model.Items में रिक्त हो जाएगा।

प्रश्न: मॉडल को जारी Model.Items लिए मैं अपने मॉडल का उपयोग कैसे कर सकता हूं।

अतिरिक्त जानकारी: मैं FormCollection collection और अतिरिक्त जावास्क्रिप्ट का उपयोग करने से बचने का प्रयास कर रहा हूं।

--कोड--

नियंत्रक:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        MyViewModel model = new MyViewModel
        {
            Items = Enumerable.Range(1, 5).Select(x => new SelectListItem
            {
                Value = x.ToString(),
                Text = "item " + x
            })
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {

        return View(model);
    }
}

आदर्श:

public class MyViewModel
{
    public MyViewModel()
    {
        Items = new List<SelectListItem>();
    }


    [Required(ErrorMessage = "Please select at least one item")]
    public string[] SelectedItems { get; set; }

    public IEnumerable<SelectListItem> Items { get; set; }
}

राय:

@model ProjectGenerator.Models.MyViewModel

@using (Html.BeginForm())
{
    @Html.ListBoxFor(x => x.SelectedItems, Model.Items)
    @Html.ValidationMessageFor(x => x.SelectedItems)
    <button type="submit">OK</button>
}

आप संपत्ति Items में प्रत्येक SelectListItem की प्रत्येक प्रॉपर्टी के लिए प्रपत्र नियंत्रण नहीं बना सकते हैं, न ही आपको चाहिए, इसलिए जब आप सबमिट करते हैं तब फॉर्म डेटा में शामिल नहीं किए जाते हैं। आपको देखने के लिए POST विधि में SelectList को पुन: असाइन करना SelectList

public ActionResult Index()
{
  MyViewModel model = new MyViewModel();
  ConfigureViewModel(model);
  return View(model);
}

[HttpPost]
public ActionResult Index(MyViewModel model)
{
  if (!ModelState.IsValid)
  {
    ConfigureViewModel(model);
    return View(model);
  }
  // Save and redirect
}

private void ConfigureViewModel(MyViewModel model)
{
  model.Items = Enumerable.Range(1, 5).Select(x => new SelectListItem
  {
    Value = x.ToString(),
    Text = "item " + x
  });
}

    public IEnumerable<SelectListItem> Items 
    {
        get
        {            
            if (HttpContext.Current.Session["MY_ITEMS_TO_LIST_FOR"] == null)
            {
                return null;
            }
            else
            {
                return (IEnumerable<SelectListItem>)HttpContext.Current.Session["MY_ITEMS_TO_LIST_FOR"];
            }
        }

        set
        {
            if (value.Count() > 0) //http post reset value
            {
                HttpContext.Current.Session["MY_ITEMS_TO_LIST_FOR"] = value;
            }
        }
    }

मैंने इस तरह से परीक्षण किया और अच्छी तरह से काम किया। वहाँ अन्य तरीके हैं, लेकिन मुझे यह आसान मिल गया। यदि आप आइटम्स गुणों के सेट को डिबग करते हैं, तो आप देखेंगे कि किसी कारण से आइटम को http पोस्ट पर संग्रह से हटा दिया गया है, भले ही आप सत्र का उपयोग करें। एक खाली संग्रह प्राप्त करने के लिए सत्र में संग्रह को रोकने के लिए, मैं अगर (Items.Count ()> 0) इस्तेमाल किया था। आप इस विचार को बड़ा कर सकते हैं और अपने प्राप्त और सेट को अनुकूलित कर सकते हैं।


एक उदाहरण जेसन परिणाम और टेम्पलेटदृश्य का उपयोग कर। यह एक अच्छा पैटर्न है

नियंत्रक (आप अनुमति नहीं देने के लिए जेसन को कॉन्फ़िगर कर सकते हैं):

   public class FornecedorController : BaseController
    {
        protected FornecedorServices Service = new FornecedorServices();

        [HttpGet]
        [Authorize(Roles = ApplicationRoles.FORNECEDOR_VISUALIZAR)]
        [OutputCache(NoStore = false, Duration = 3600)]
        public JsonResult ListarJson(FornecedorParameters parameters)
        {
            var model = this.Service.Search(parameters)
                .Select(x => new
                {
                    Value = x.Codigo,
                    Description = x.CodigoNomeFantasia
                });
            return this.Json(model, JsonRequestBehavior.AllowGet);
        }

    }

टेम्पलेट दृश्य (आप अपना स्वयं का अनुकूलित कर सकते हैं):

@model int[]
@{
    var id = "id" + Guid.NewGuid().ToString().Substring(0, 5);
    var disabled = (bool)(this.ViewData["disabled"] ?? false);
    var showAll = (bool)(this.ViewData["ShowAll"] ?? false);
    var state = this.ViewData.ModelState[Html.NameFor(x => x).ToString()];
    var size = (Size)(this.ViewData["Size"] ?? Size.Big);
    string css = (state != null && state.Errors.Count > 0) ? "input-validation-error" : string.Empty;

    List<SelectListItem> listValues;
    if (this.Model == null)
    {
        listValues = new List<SelectListItem>();
    }
    else
    {
        listValues = this.Model.Select(x => new SelectListItem { Selected = true, Value = x.ToString(), Text = x.ToString() }).ToList();
    }
}
<div class="[email protected] @css">
    <h3>@Html.LabelFor(model => model):</h3>
        @Html.ListBox("", listValues, new { id = id })
</div>
<script language="javascript" type="text/javascript">
    $("#@id").turnAutoComplete("@Url.Action("ListarJson", "Fornecedor", new { ShowAll = showAll })"@if (showAll) { <text>, checkSelectAll</text> })
        .change(function () {
            @Html.Raw(this.ViewData["OnChange"])
        });
</script>