TextBoxFor值在发布后未更新

本文关键字:更新 TextBoxFor | 更新日期: 2023-09-27 18:29:16

我有一个简单的强类型视图,但我似乎无法在发布后更新表单上的文本框。

这是我的型号:

public class Repair
  {
    public string Number { get; set; }      
  }

在我看来是一个文本框:

   @Html.TextBoxFor(x => x.Number)

我正试图在我的控制器上发帖后更新文本框:

 [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(Repair r)
        {
          r.Number = "New Value";
          return View(r);
        }

即使我将Number设置为一个新值,文本框中的文本也不会更改。我做错了什么?

TextBoxFor值在发布后未更新

在设置值之前使用ModelState.Clear()

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(Repair r)
{
    ModelState.Clear(); //Added here
    r.Number = "New Value";
    return View(r);
}

当您将模型发布回ActionResult并返回相同的View时,模型对象的值包含在ModelState中。ModelState包含有关有效/无效字段以及实际POSTed值的信息。如果你想更新模型值,你可以做两件事之一:

ModelState.Clear()

ModelState["Number"].Value = new ValueProviderResult("New Value", "New Value", CultureInfo.CurrentCulture)

从我处理这个问题的过程中,我觉得这是框架中的设计错误。IMO:

@Html.TextBoxFor(x => x.Number) 

不应该从ModelState中获取值,而是直接从模型中获取值。至少当我更改模型和return View(model)时,这将是我的期望。

ModelState.Clear() 

不是答案,因为它清除了正在擦除ValidationSummary的ModelState。从ModelState中删除密钥既不好,因为它会删除该密钥的ValidationSummary。

ModelState["Number"].Value = 
new ValueProviderResult("New Value", "New Value", CultureInfo.CurrentCulture)

是正确的,但太晦涩了。因此,在这种情况下,我倾向于使用:

<input type="text" name="Number" id="Number" value="@Model.Number"/>

而不是

@Html.TextBoxFor(x => x.Number)  

如果您发现ModelState.Clear()破坏性太强,您可以只针对正在更改的项,而使用ModelState.Remove()保留其余项

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(Repair r)
{
    r.Number = "New Value";
    ModelState.Remove("Number");
    return View(r);
}

此外,无论是在更新模型之前还是在之后调用该方法,Remove()还是Clear()似乎都无关紧要

试试这个。如果你愿意,你可以把它放在一个基本控制器里。它对我来说运行得很好。它使它变得如此不引人注目。验证仍然有效,但模型中的值显示得很好,正如预期的那样。

public class BaseController : Controller
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        ModelState.ToList().Select(x => x.Value).ToList().ForEach(x => { x.AttemptedValue = null; x.RawValue = null; });
        // Do a bunch of stuff here if needed. Stuff like validation.
        base.OnActionExecuted(context);
    }
}