Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在MVC.net网页中保留从@Html.ListBoxFor生成的select中的所有值?_C#_Asp.net Mvc_Listbox_Http Post_Multi Select - Fatal编程技术网

C# 如何在MVC.net网页中保留从@Html.ListBoxFor生成的select中的所有值?

C# 如何在MVC.net网页中保留从@Html.ListBoxFor生成的select中的所有值?,c#,asp.net-mvc,listbox,http-post,multi-select,C#,Asp.net Mvc,Listbox,Http Post,Multi Select,问题是:我基于HttpGet中的数据库查询生成了一个@Html.ListBoxFor。在我的HttpPost期间,我想验证是否至少选择了一个元素。如果没有,我只想添加一条验证消息 当前结果:我收到消息“请选择至少一个项目”,但现在select为空(select元素在那里,但包含0个选项)。我知道在我的HttpPost中,Model.Items将为空 问题:如何使用我的模型持久化model.Items使其不为空? 其他信息:我试图避免使用FormCollection和其他JavaScript --

问题是:我基于HttpGet中的数据库查询生成了一个
@Html.ListBoxFor
。在我的HttpPost期间,我想验证是否至少选择了一个元素。如果没有,我只想添加一条验证消息

当前结果:我收到消息“请选择至少一个项目”,但现在select为空(select元素在那里,但包含0个选项)。我知道在我的HttpPost中,
Model.Items
将为空

问题:如何使用我的模型持久化
model.Items
使其不为空?

其他信息:我试图避免使用
FormCollection
和其他JavaScript

--代码--

控制器:

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; }
}
公共类MyViewModel
{
公共MyViewModel()
{
项目=新列表();
}
[必需(ErrorMessage=“请至少选择一项”)]
公共字符串[]SelectedItems{get;set;}
公共IEnumerable项{get;set;}
}
视图:

@model ProjectGenerator.Models.MyViewModel
@使用(Html.BeginForm())
{
@Html.ListBoxFor(x=>x.SelectedItems,Model.Items)
@Html.ValidationMessageFor(x=>x.SelectedItems)
好啊
}
公共IEnumerable项
{
得到
{            
if(HttpContext.Current.Session[“我的项目到列表”]==null)
{
返回null;
}
其他的
{
返回(IEnumerable)HttpContext.Current.Session[“我的项目到列表”];
}
}
设置
{
if(value.Count()>0)//http post重置值
{
HttpContext.Current.Session[“我的项目列表”]=值;
}
}
}
我用这种方法测试,效果很好。 还有其他方法,但我发现这更容易。 如果调试项目集属性, 您将看到,由于某种原因,这些项会从HTTPPOST上的集合中删除,即使您使用了会话。 为了防止会话中的集合接收空集合,我使用If(Items.Count()>0)。
您可以扩大此想法并自定义get和set。

您现在不是,也不应该为property
Items
中每个
SelectListItem
的每个属性创建表单控件,以便在提交时不将其包含在表单数据中。您需要在返回视图的POST方法中重新指定
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
  });
}

一个使用Json结果和templateview的示例。这是一个很好的模式

控制器(您可以将json配置为不允许get):

模板视图(您可以自定义自己的模板):

@model int[]
@{
var id=“id”+Guid.NewGuid().ToString()子字符串(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);
字符串css=(state!=null&&state.Errors.Count>0)?“输入验证错误”:string.Empty;
列出列表值;
if(this.Model==null)
{
listValues=新列表();
}
其他的
{
listValues=this.Model.Select(x=>newselectListItem{Selected=true,Value=x.ToString(),Text=x.ToString()}).ToList();
}
}
@Html.LabelFor(model=>model):
@Html.ListBox(“,listValues,new{id=id})
$(“#@id”).turnAutoComplete(@Url.Action(“ListarJson”,“Fornecedor”,new{ShowAll=ShowAll})”@if(ShowAll){,checkSelectAll})
.改变(功能){
@Html.Raw(this.ViewData[“OnChange”])
});

在返回视图之前,您需要在POST方法中重新填充
SelectList
(就像在GET方法中一样)。您不会(也不应该)为每个
SelectListItem
生成输入,因此它们不会出现在表单数据中。这是否适用于并发选项卡?例如,假设用户有两个选项卡。在第一个列表中,选择列表的值为{1,2,3},第二个列表的值为{2,3,4}。然后,如果用户发回他们首先打开的页面,则在加载第二个页面时,HttpContext.Current.Session[“MY_ITEMS_TO_LIST_FOR”]将被重写。用户选择的值位于不使用Session的SelectedItems变量中。使用会话的属性项来自服务器到客户端(仅一个方向-用于填充listbox),每个请求都会带来更新的值。如果将会话用于来自客户端的变量,则需要使用会话ID,如本文所述。如果使用jquery,则可以使用json结果在控制器中创建标准操作,并在TemplateView中使用autocomplete。在菲亚特程序中,所有列表框(供应商、用户等)也使用了该程序。但你们怎么说不需要javascript…我用Json结果写了一个awnser。Ferreira,我不知道SessionId存储在页面上而不是cookie上。谢谢你的来信。我也不知道表单只发布选定的值,而不是发送整个表单。将它们存储在会话中的想法似乎仍然不太理想(当服务器重新启动时,Sessiondata会丢失)。
    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;
            }
        }
    }
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 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="field-@size @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>