gpt4 book ai didi

c# - 处理回发数据中的数组 - MVC3

转载 作者:行者123 更新时间:2023-11-30 21:13:54 28 4
gpt4 key购买 nike

我目前是一名 WebForms 开发人员,正在尝试迁移到 MVC。我对 MVC 非常兴奋,我真的很开心,但我遇到了一个奇怪的问题。所以我想做的是为“小部件”创建一个高级编辑器。我已经在下面发布了代码。

当您添加前 4-5 个项目时,一切似乎都工作正常,但当您删除第 2 个项目时,问题就出现了。这是一个可视化示例。

首先添加 4 个值。

enter image description here

但是当我们删除第二个值时,问题就出现了。我们最终得到这个......

enter image description here

我似乎无法理解的是为什么此属性在以下两行代码之间的行为不同。

@Model.Values[i]
@Html.TextBoxFor(m => m.Values[i])

我的猜测是 @Model 和 (m =>m) 没有引用同一个对象?

这是我的小部件类。

public class Widget
{
#region Constructor

public Widget()
{
ID = 0;
Name = string.Empty;
Values = new List<string>();
}

#endregion

#region Properties

[Required]
[Display(Name = "ID")]
public int ID { get; set; }

[Required]
[Display(Name = "Name")]
public string Name { get; set; }

[Required]
[Display(Name = "Values")]
public List<string> Values { get; set; }

#endregion
}

我的 Controller 看起来像这样。

public ViewResult EditWidget(int id)
{
return View(_widgets.GetWidgetByID(id));
}

[HttpPost]
public ActionResult EditWidget(Widget widget)
{
if (!TryUpdateModel(widget))
{
ViewBag.Message = "Error...";
return View(widget);
}

if (Request.Form["AddWidgetValue"] != null)
{
widget.Values.Add(Request.Form["TextBoxWidgetValue"]);
return View("EditWidget", widget);
}

if (Request.Form["DeleteWidgetValue"] != null)
{
widget.Values.Remove(Request.Form["ListBoxWidgetValues"]);
return View("EditWidget", widget);
}

_widgets.UpdateWidget(widget);
_widgets.Save();

return RedirectToAction("Index");
}

最后是我的观点。

@model MvcTestApplication.Models.Widget

@{
ViewBag.Title = "EditWidget";
}

<h2>EditWidget</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Widget</legend>

@Html.HiddenFor(model => model.ID)

<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>

@for (var i = 0; i < Model.Values.Count; i++)
{
@Model.Values[i]
@Html.TextBoxFor(m => m.Values[i])
@Html.HiddenFor(m => m.Values[i])
<br />
}

@Html.ListBox("ListBoxWidgetValues", new SelectList(Model.Values), new { style = "width: 100%" })<br />
@Html.TextBox("TextBoxWidgetValue", string.Empty, new { style = "width: 100%" })
<input type="submit" value="Add" id="AddWidgetValue" name="AddWidgetValue" class="submitButton" />
<input type="submit" value="Delete" id="DeleteWidgetValue" name="DeleteWidgetValue" class="submitButton" />

<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

最佳答案

发生这种情况的原因是因为 HTML 帮助程序在绑定(bind)时首先查看 ModelState 发布的值,然后在模型中查看。这意味着如果在您的 POST Controller 操作中您尝试修改某个值,而这个相同的值是初始发布请求的一部分,HTML 帮助程序将使用初始值而不是您修改的值。

例如,在您的 EditWidget 操作中,您这样做:

if (Request.Form["DeleteWidgetValue"] != null)
{
widget.Values.Remove(Request.Form["ListBoxWidgetValues"]);
return View("EditWidget", widget);
}

您应该从模型状态中删除最初发布的值:

if (Request.Form["DeleteWidgetValue"] != null)
{
var itemToRemove = Request.Form["ListBoxWidgetValues"];
var index = widget.Values.IndexOf(itemToRemove);
ModelState.Remove("Values[" + index + "]");
widget.Values.Remove(itemToRemove);
return View("EditWidget", widget);
}

因此 POST 请求包含:

Values[0] = 1
Values[1] = 2
Values[2] = 3
Values[3] = 4

在 POST 操作中,您删除了例如第二个项目,因此您也应该将其从模型状态中删除,否则 TextBoxFor 助手仍将使用旧的。

您还可以找到 following blog post有用。它适用于 ASP.NET MVC 2 WebForms,但将它改编为 Razor 是微不足道的。

关于c# - 处理回发数据中的数组 - MVC3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6552196/

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