为什么需要在ASP.NET中传递模型的隐藏值

时间:2017-01-21 13:52:35

标签: asp.net-mvc html-helper

假设我在SQL服务器中有一个City表。 这是HomeController:

  [HttpGet]
    public ActionResult Index()
    {
        SampleDBContex db = new SampleDBContex();
        return View(db.Cities);
    }
    [HttpPost]
    public string Index(IEnumerable<City> cities)
    {
        if (cities.Count(x => x.IsSelected) == 0)
        {
            return "You didn't select city";
        }
        else
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("You selected -");
            foreach (City city in cities)
            {
                if (city.IsSelected)
                {
                    sb.Append(city.Name + ", ");
                }
            }
            sb.Remove(sb.ToString().LastIndexOf(","), 1);
            return sb.ToString();
        }

    }

}

这是索引视图(get方法):

@model IEnumerable<Part38MVCCheckBoxList.Models.City>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <br />
    <input type="submit" value="Submit" />
}

这是编辑器模板:

@model Part38MVCCheckBoxList.Models.City

@Html.HiddenFor(x => x.ID)
@Html.HiddenFor(x => x.Name)



@Html.CheckBoxFor(x => x.IsSelected)
@Html.DisplayFor(x => x.Name)

我不明白为什么我们需要使用@ Html.HiddenFor(x =&gt; x.Name),否则它无法显示城市名称。我想我们传递模型IEnumerable所以我们应该有cityname存在已经从数据库中检索它们了

3 个答案:

答案 0 :(得分:1)

我们采用了隐藏属性,因为在控制器端我们需要在后端过滤某些东西,或者可能是这些属性在查询数据库时可能形成密钥。完全取决于您的设计和控制器需求。如果您不需要,可以选择删除。

答案 1 :(得分:1)

你需要一个hiddenfor,因为HTTP消息是无状态的,所以如果你从控制器获得一个对象,它将在你的页面上有完整的对象,但如果你将所有内容发送回去,除了你的Name和Id变量作为输入您表单上的值将丢失。

您的控制器只会在需要时保留它,并且在您从控制器获得HttpGet应答后控制器完成并且它将不再保留该值。

我也觉得这是违反直觉的,但这就是HTTP协议的构建方式。

答案 2 :(得分:1)

HTTP是无状态的,因此一旦将数据作为模型的一部分发送到客户端,控制器就不会拥有数据。

也没必要也必须为视图中的每个模型属性创建隐藏控件。

一般规则是作为模型的一部分需要回发的值应该在HTML中作为输入呈现(文本,密码,隐藏,复选框等)。

隐藏控件仅针对应作为模型的一部分发送回控制器中的POST操作的属性创建。

如果只是要显示属性值,为它创建标签或在跨度中渲染它就足够了。