我的方法可能完全错误,但我正在慢慢学习MVC ...我有一个表单,用户必须根据此模型选择一些(或没有)模块:
public class MyProductModule
{
public string ModuleName { get; set; }
public bool Checked { get; set; }
}
public class ProductRequest
{
public ProductRequest()
{
Modules = LoadModules();
}
public static List<MyProductModule> LoadModules()
{
return new List<MyProductModule>()
{
new MyProductModule() { ModuleName = "Module One", Checked = false },
new MyProductModule() { ModuleName = "Module Two", Checked = false },
new MyProductModule() { ModuleName = "Module Three", Checked = false }
};
}
[Required]
[EmailAddress]
public string Email { get; set; }
[DisplayName("MyProduct Modules")]
public List<MyProductModule> Modules { get; set; }
}
呈现复选框列表以显示每个模块:
@for (int i = 0; i < Model.Modules.Count; i++)
{
@Html.CheckBoxFor(m => m.Modules[i].Checked)
@Html.HiddenFor(m => m.Modules[i].ModuleName)
@Html.LabelFor(m => m.Modules[i].Checked, Model.Modules[i].ModuleName)
}
最后,表单按如下方式处理:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ProcessRequest(ProductRequest qd)
{
if (!ModelState.IsValid)
{
return View("Index", qd);
}
else
{
// check email domains
List<string> badDomains = new List<string>();
badDomains.Add("gmail");
badDomains.Add("yahoo");
badDomains.Add("hotmail");
foreach (string s in badDomains)
{
if (qd.Email.Contains(string.Format("@{0}.", s)))
{
ModelState.AddModelError(string.Empty, string.Format("Please use your work email address.", s));
}
}
if (!ModelState.IsValid)
{
return View("Index", qd);
}
else
{
// process
}
}
}
除非由于某种原因我的服务器端验证失败,并且模型被发回(return View("Index", qd);
),否则一切都工作正常。那时,复选框列表神秘地改变了:
[x] Module One
[ ] Module Two
[ ] Module Three
......对此:
[ ] Module One
[ ] Module Two
[ ] Module Three
所有复选框值都将丢失。如果我检查Firebug中的原始发布数据,我发现由于某种原因,对于选中的框发布了true和false,并且#34;已检查&#34;值:
答案 0 :(得分:1)
在服务器端,变量qd
包含您从视图中发布的值:
对于每个MyProductModule
,您只发布Checked
成员。
因此,当您使用return View("Index", qd);
时,您只向视图提供您拥有的值:Checked
成员。
如果您想拥有ModuleName
成员,则必须将其发布到Checked
成员
@Html.LabelFor(model => model.Modules, htmlAttributes: new { @class = "required" })
@for (int i = 0; i < Model.Modules.Count; i++)
{
@Html.CheckBoxFor(m => m.Modules[i].Checked)
@Html.HiddenFor(m => m.Modules[i].ModuleName)
@Html.LabelFor(m => m.Modules[i].Checked, Model.Modules[i].ModuleName)
}
好的,我无法重现您的错误,但我可以建议另一种方式来编写它:使用编辑器模板
使用@Html.EditorFor(m => m.Modules)
而不是for循环
你会有像
@using (Html.BeginForm("ProcessRequest", "Home"))
{
@Html.AntiForgeryToken()
@Html.TextBoxFor(m => m.Email)
@Html.EditorFor(m => m.Modules)
<input type="submit" value="send" />
}
然后创建一个EditorTemplates文件夹和一个名为MyProductModule.cshtml
MyProductModule.cshtml:
@model MyNamespace.MyProductModule
@Html.CheckBoxFor(m => m.Checked)
@Html.HiddenFor(m => m.ModuleName)
@Html.LabelFor(m => m.Checked, Model.ModuleName)