TextBoxFor显示初始值,而不是从代码更新的值

Adr*_*rez 47 c# asp.net-mvc

我有一个显示值的MVC应用程序.这是控制器:

public ActionResult Index(DataSites DataSiteList)
{
    if (DataSiteList.Latitude != null)
    {
        DataSites test = new DataSites();
        test.Latitude = "LATITUDE";

        return View(test);
    }
    return View(DataSiteList);
}
public ActionResult SomeInformation()
{
    DataSites test1 = new DataSites();
    test1.Latitude = "LATITUDE2";

     return RedirectToAction("Index", test1);
}
Run Code Online (Sandbox Code Playgroud)

风景:

@model miniproj2.Models.DataSites

<p>
    @Html.TextBoxFor(x => x.Latitude)
</p>
Run Code Online (Sandbox Code Playgroud)

而型号:

public class DataSites
{
    public string Latitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我转到/ Home/SomeInformation时,DataSites' Latitude属性设置为"LATITUDE2".然后重定向到Index()控制器中的操作,将属性设置为"LATITUDE"并返回视图.

当它显示视图时,它显示重定向中设置的值"LATITUDE2".不应该显示"LATITUDE"吗?

小智 95

你的问题是(一步一步)

  1. 您的SomeInformation()方法将值设置test1.Latitude 为"LATITUDE2".
  2. 然后Index()使用RedirectToAction接受对象的重载将该模型传递给您的方法.在内部,它使用反射来构建RouteValueDictionary基于模型属性的(在这种情况下简单地说latitude="LATITUDE2").
  3. 当你点击Index方法时,模型被绑定DefaultModelBinder,现在值为DataSiteList.Latitude"LATITUDE2"(这就是你输入if块的原因)
  4. 在绑定过程中,DefaultModelBinderModelState值设置Latitude为"LATITUDE2".Latitude现在忽略任何设置值的尝试,因为视图使用 ModelState值来呈现控件.

不清楚你在这里尝试做什么.您可以通过添加ModelState.Clear();方法的第一行来使其按预期工作Index().这将清除所有现有ModelState值,您现在可以将值设置为"LATITUDE".

但你的if阻碍是没有意义的.也许您只是在进行某种测试,但您也可以从Index()方法中删除参数,并初始化方法中的新实例DataSites.

编辑

为了更新模型属性的原因提供更多信息,一旦ModelState设置就没有影响.

想象一下,您有一个表单来收集模型包含的用户信息int Age.要求用户输入他们的年龄,有人输入"我下周五点!".当然这不会绑定到int所以DefaultModelBinder添加值(the attemptedValue)并添加一个ModelStateError.

返回视图时,它通常会显示错误消息,例如"字段年龄必须是数字".如果呈现控件的html帮助器使用了模型值,那么它将显示"0"(int的默认值).如果用户在文本框中看到"0"并且接下来是一条消息,说它必须是一个数字(什么!但是零是一个数字以及我输入的内容发生了什么?),这有点令人困惑.因此,帮助者使用来自的值ModelState,现在用户看到"我下周五点!" 以及对值有意义的关联错误消息.

因此,即使你认为"它不合逻辑",这种行为实际上也有一些逻辑.