asp.net-mvc – ASP.NET MVC中具有动态数量的texbox的表单
发布时间:2020-12-16 09:21:56 所属栏目:asp.Net 来源:网络整理
导读:考虑以下模型和控制器: public class SimpleModel{ [Required(ErrorMessage="Email Address is required.")] [DataType(DataType.EmailAddress)] [DisplayName("EmailAddress")] public string EmailAddress { get; set; }}[HandleError]public class Simpl
|
考虑以下模型和控制器:
public class SimpleModel
{
[Required(ErrorMessage="Email Address is required.")]
[DataType(DataType.EmailAddress)]
[DisplayName("EmailAddress")]
public string EmailAddress { get; set; }
}
[HandleError]
public class SimpleController : Controller
{
public ActionResult Simple()
{
return View();
}
[HttpPost]
public ActionResult Simple(SimpleModel model)
{
if (ModelState.IsValid)
{
// handling code here
}
return View(model);
}
}
…以及匹配视图中的相关部分: <% using (Html.BeginForm()) { %>
<%= Html.ValidationSummary(true,"The form submitted is not valid.") %>
<div>
<fieldset>
<div class="editor-label">
<%= Html.LabelFor(m => m.EmailAddress)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(m => m.EmailAddress)%>
<%= Html.ValidationMessageFor(m => m.EmailAddress)%>
</div>
<div class="editor-field">
<input type="submit" value="Submit" />
</div>
</fieldset>
</div>
<% } %>
修改模型,视图和控制器以支持控制器定义的动态数量的电子邮件地址的最佳方法是什么. 解决方法
根据
Steve Sanderson的文章,我能够找到我想要的优雅解决方案:
首先,模型需要修改如下: public class SimpleModel
{
public IEnumerable<EmailAddress> EmailAddresses { get; set; }
}
public class EmailAddress
{
[Required(ErrorMessage = "Email Address is required.")]
[DataType(DataType.EmailAddress)]
[DisplayName("Email Address")]
public string Value { get; set; }
}
处理GET方法的控制器方法需要根据需要使用尽可能多的条目预填充模型: [HandleError]
public class SimpleController : Controller
{
public ActionResult Simple()
{
SimpleModel model = new SimpleModel
{
EmailAddresses =
new List<EmailAddress>
{
// as many as required
new EmailAddress { Value = string.Empty },new EmailAddress { Value = string.Empty },new EmailAddress { Value = string.Empty }
}
};
return View(model);
}
[HttpPost]
public ActionResult Simple(SimpleModel model)
{
if (ModelState.IsValid)
{
// handling code here
}
return View(model);
}
}
视图还需要改变: <% using (Html.BeginForm()) { %>
<%= Html.ValidationSummary(true,"The form submitted is not valid.") %>
<div>
<fieldset>
<% foreach (var item in Model.EmailAddresses)
Html.RenderPartial("SimpleRows",item);
%>
<div class="editor-field">
<input type="submit" value="Submit" />
</div>
</fieldset>
</div>
<% } %>
……需要创建一个新的局部视图.请注意,视图是强类型的,具有集合项的类型. <% using(Html.BeginCollectionItem("EmailAddresses")) { %>
<div class="editor-label">
<%= Html.LabelFor(x => x.Value)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(x => x.Value)%>
<%= Html.ValidationMessageFor(x => x.Value)%>
</div>
<% }%>
BeginCollectionItem是Sanderson创建的Helper方法: public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html,string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext,collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back",which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type="hidden" name="{0}.index" autocomplete="off" value="{1}" />",collectionName,html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html,string.Format("{0}[{1}]",itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html,string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo,htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext,string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null) {
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo,string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
…就是这样……当您发布表单时,模型将自动填充并传递给处理POST方法的控制器操作. 请注意,使用此解决方案,所有属性(包括验证)都按预期工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- entity-framework-6 – 带有EF6的ASP.NET-5
- .net – 如何动态清除用户控件中的所有控件?
- 会话处理在asp.net
- ASP.Net从CodeBehind打开浏览器中的新标签页
- 【 .Net码农】ASP.NET MVC中使用Dropzone.js实现图片的批量
- asp.net-3.5 – “回复视图状态MAC失败”回发到另一个页面
- ASP.NET Core框架揭秘(持续更新中…)
- asp.net-mvc – 确定是否在布局页面中调用了RenderSection(
- ASP.NET缓存的方法和最佳实践
- asp.net-mvc-4 – 将ASP.NET Core与旧版.Net Framework代码
推荐文章
站长推荐
- asp.net – 在IIS 7.5上挂在Session模块上的请求
- 电子邮件 – 邮箱不可用,客户端没有权限作为此发
- asp.net – 为什么我需要PUT或DELETE Http Verbs
- asp.net – 谷歌Chrome在崩溃后恢复会话cookie,如
- asp.net – 为什么不调用我的IHttpHandler?
- ASP.NET c#获取屏幕宽度(以像素为单位)
- asp.net-mvc – 添加ELMAH并更改elmah.mvc.route
- asp.net-mvc – 是否有一种方法来创建一个Action
- asp.net-mvc – 允许使用ASP-MVC和表单身份验证访
- asp.net-mvc – 模型支持DB上下文已更改;考虑代码
热点阅读
