我有一个带有姓名,电子邮件和电话的简单联系表格的视图。我在同一个父页面上重复使用此表单两到三次。当用户提交其中一个表单时,我会检测提交的表单,并使用Dapper通过javascript / jQuery将内容发布到数据库。
问题是当我在任何页面上重复使用联系表单时,将不会使用唯一ID生成输入字段。这会导致w3验证失败,说Duplicate ID
。在这种特殊情况下,我需要页面通过w3验证。
我将如何解决这个问题?我尝试使用ViewData.TemplateInfo.HtmlFieldPrefix
为输入字段添加前缀,但由于前缀值是静态的,因此无法真正解决问题。如果我做一个随机前缀值,那么如何在HttpPost控制器中捕获它?
这是我的代码。
Index.cshtml
- 多次引用ContactForm.cshtml
:
<html>
<head>...</head>
<body>
....
@{Html.RenderAction("ContactForm")}
....
@{Html.RenderAction("ContactForm")}
....
</body>
</html>
ContactForm.cshtml
@model ProjectX.Models.CaseModel
@using (Html.BeginForm("SendMessage", "Home", FormMethod.Post))
{
@Html.TextInputFor(model => model.Name, Res.Name, new { placeholder = Res.Name } )
@Html.TextInputFor(model => model.Phone, Res.Phone, new { placeholder = Res.Phone, type = "tel" })
@Html.TextInputFor(model => model.Email, Res.Email, new { placeholder = Res.Email, type = "email" })
<input type="submit" value="Send" onclick="jsSaveForm(event);" />
}
// @Html.TextInputFor MvcHtmlString helper method
public static MvcHtmlString TextInputFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string title, Object htmlAttributes = null)
{
var req = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).IsRequired;
var name = helper.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
if (req)
title += " *";
string html = String.Format("<div class=\"inp\"><label for=\"{2}\">{0}</label>{1}</div>", helper.ValidationMessageFor(expression), helper.TextBoxFor(expression, htmlAttributes), name);
return new MvcHtmlString(html);
}
CaseModel.cs
public class CaseModel
{
[Required(ErrorMessageResourceType = typeof(Res), ErrorMessageResourceName = "ValidationRequired")]
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
}
的HomeController
// GET
[ChildActionOnly]
[Route("~/Home/ContactForm")]
public ActionResult ContactForm()
{
// tried this but this is a static value.
// ViewData.TemplateInfo.HtmlFieldPrefix = "SomePrefix";
return PartialView(new CaseModel());
}
// POST
[HttpPost]
[Route("~/Home/SendMessage")]
public async Task<PartialViewResult> SendMessage(CaseModel model)
{
... brevity...
await SaveData(model);
}
答案 0 :(得分:1)
您可以通过在id
参数中将其设置为空字符串来删除htmlAttributes
属性,例如
@Html.TextInputFor(model => model.Name, Res.Name, new { id = "", placeholder = Res.Name } )
虽然您可能需要考虑在TextInputFor()
扩展方法中执行此操作。
作为旁注,您的扩展方法没有考虑属性的显示名称(使用[Display(Name = "...")]
属性时,并且title
参数是不必要的。我建议您的代码应该是
public static MvcHtmlString TextInputFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string displayName = metaData.DisplayName;
if (metaData.IsRequired)
{
displayName += " *";
}
StringBuilder html = new StringBuilder();
html.Append(helper.LabelFor(expression, displayName).ToString());
html.Append(helper.TextBoxFor(expression, htmlAttributes).ToString());
html.Append(helper.ValidationMessageFor(expression).ToString());
TagBuilder container = new TagBuilder("div");
container.AddCssClass("inp");
container.InnerHtml = html.ToString();
return new MvcHtmlString(container.ToString());
}