gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 中具有动态数量文本框的表单

转载 作者:行者123 更新时间:2023-12-02 18:08:10 26 4
gpt4 key购买 nike

考虑以下模型和 Controller :

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);
}
}

...以及匹配 View 中的相关部分:

    <% 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>
<% } %>

修改模型、 View 和 Controller 以支持 Controller 定义的动态电子邮件地址数量的最佳方法是什么。

最佳答案

基于 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 方法的 Controller 方法需要使用所需数量的条目预先填充模型:

[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);
}
}

View 也需要更改:

    <% 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>
<% } %>

...并且需要创建一个新的局部 View 。请注意,该 View 与集合项的类型是强类型的。

<% 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}]", collectionName, 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 方法的 Controller 操作。

请注意,使用此解决方案,包括验证在内的所有属性都按预期工作。

关于asp.net-mvc - ASP.NET MVC 中具有动态数量文本框的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5236251/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com