【发布时间】:2015-11-24 03:21:31
【问题描述】:
我的页面上有两个表格。我的视图模型如下所示:
public class HomeViewModel
{
[Required(ErrorMessage = "We kind of need an email address!")]
[EmailAddress(ErrorMessage = "This isn't an email address!")]
public string Email { get; set; }
public ContactForm ContactForm { get; set; }
}
联系方式:
public class ContactForm
{
[Required(ErrorMessage = "We need your name, please!")]
public string Name { get; set; }
[Required(ErrorMessage = "We need your email, please!")]
[EmailAddress(ErrorMessage = "This isn't an email address!")]
public string EmailAddress { get; set; }
[Required(ErrorMessage = "Please elaborate a little!")]
public string Message { get; set; }
}
第一个表单动作:
public ActionResult FreeConsultSubmit(HomeViewModel model)
{
if (ModelState.IsValid)
{
//do stuff
}
return PartialView("_SubmitResult", false);
}
第二次行动:
public ActionResult ContactSubmit(HomeViewModel model)
{
if (ModelState.IsValid)
{
//dostuff
}
return PartialView("_SubmitContactResult", false);
}
第一个 Ajax 表单
@using (Ajax.BeginForm("FreeConsultSubmit", new AjaxOptions()
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "FreeConsultResults"
}))
{
<div id="FreeConsultResults">
<div class="row">
<div class="small-4 columns small-centered text-center splashEmail">
@Html.TextBoxFor(m => m.Email, new { @placeholder = "Please enter your email..." })
@Html.ValidationMessageFor(m => m.Email)
</div>
</div>
<div class="row">
<div class="small-5 columns small-centered text-center">
<input type="submit" class="hvr-border-fade splashCallToAction" value="Get Started" />
</div>
</div>
</div>
}
第二种 Ajax 形式:
@using (Ajax.BeginForm("ContactSubmit", new AjaxOptions()
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "ContactSubmitResults"
}))
{
<div id="ContactSubmitResults">
<div class="row">
<div class="small-12 columns small-centered">
@Html.TextBoxFor(m => m.ContactForm.Name, new { @placeholder = "Your Name" })
@Html.ValidationMessageFor(m => m.ContactForm.Name)
@Html.TextBoxFor(m => m.ContactForm.EmailAddress, new { @placeholder = "Your Email Address" })
@Html.ValidationMessageFor(m => m.ContactForm.EmailAddress)
@Html.TextAreaFor(m => m.ContactForm.Message, new { @placeholder = "Your Message", @class = "contactMessage" })
@Html.ValidationMessageFor(m => m.ContactForm.Message)
</div>
</div>
<div class="row">
<div class="small-12 columns small-centered text-center">
<a href="">
<input type="submit" class="hvr-border-fade sendMessageSmall" value="Send Message" />
</a>
</div>
</div>
</div>
}
我已经把所有东西都连接好了,客户端验证也能正常工作。这可能有点矫枉过正,但我也想设置服务器端验证。
问题是,在提交第一个表单(只是电子邮件字符串)时,我检查 ModelState 是否有效,并且确实有效。如果您深入了解 ModelState,您会看到只查看了 1 个属性。
如果您提交第二个表单(ContactForm),ModelState.IsValid 返回 false,如果您向下钻取,您会看到它正在查看 4 个属性(3 个 ContactForm 属性,加上字符串电子邮件)。由于需要电子邮件字符串,因此失败。
我很困惑为什么它对一个有效,而对另一个无效。我可以删除服务器端验证,但我至少想知道为什么会这样。我也可以从 ModelState 中删除错误,但这似乎一点也不优雅。
【问题讨论】:
-
你还没有展示你的
ContactForm模型(它有验证属性吗?)或者你的视图或控制器! -
完成。非常直截了当,所有的绑定都有效。只是第二个表单尝试验证第一个表单中的第一个字符串电子邮件字段。
-
您的模型以这种方式设置是否有特殊原因?似乎您或多或少地复制了一个属性(电子邮件),即使您不使用它。
-
第二种形式尝试验证
Email属性,因为它是您模型的一部分,并且它具有[Required]属性,并且您没有为它发布值。一个非常奇怪的设计,但解决它的一种方法是将方法更改为public ActionResult ContactSubmit([Bind(Prefix = "ContactForm")]ContactForm model) -
我有一个号召性用语,只需要页面顶部的电子邮件和底部的联系表。所以我不是在复制一个属性,而是在使用它。为什么这是一个奇怪的设计?谢谢斯蒂芬,这似乎是最好的解决方案。
标签: asp.net-mvc