在ASP.NET MVC4中,我想用值初始化字段。当用户获取页面时,在他将其发回之前,我想让它从某些字段中的值开始。值将从查询字符串中提取,而不是硬编码。假设用户正在填写表格:他已登录,您知道他的姓名和地址。出于礼貌,将这些设为默认值。无论它们来自哪里,真的,除了它是一组键值对,并且值是字符串。我只是想在没有用户首先发布表单的情况下在字段中放置一些东西而且我真的很想在没有对一个相当复杂的模型中的每个属性的长而长的分配列表进行硬编码的情况下这样做。
现在它已在$(document).ready()
的JS循环中完成,但它属于服务器。但是,我想复制那个逻辑:将查询参数名称视为唯一标识符。
在我的控制器的Index()
方法中,我尝试调用ModelState.TrySetModelValue()
(填充ModelState
时,通过一个唯一字符串标识每个字段)但在此阶段{{1}是空的,所以当然没有用。我尝试更改Index()以期望模型的实例作为参数,但这没有帮助。
我必须重写每个ModelState
/ @Html.EditorFor()
/等。打电话申请?这看起来很疯狂。恰当地说,这是我在一个循环中做的事情,在一个地方,不是分散在越来越多的视图中的每个视图中的多个点。
我有一种感觉,我没有理解MVC4的工作方式。
更新2
事实证明,如果您使用TextBoxFor()
修饰您的操作方法,并且您希望将模型作为参数,那么如果您使用字段名称({{1} })而不是查询字符串中的ID([HttpGet]
),它会自动执行我想要的操作。 foo.bar
已填充。当我查看foo_bar
时,我必须没有用ModelState
修饰的操作方法。
如果通过查询字符串自动设置字段,则会取代模型中的任何内容。那是合理的;重点是覆盖模型的默认值。但是如果你想反过来覆盖可能的查询字符串值(例如,说“电子签名”有一个复选框;那应该总是需要用户的明确努力),那么你必须通过{{ 1}}。
这意味着我的第一个解决方案在下面没有实际效果(如果我在action方法上有[HttpGet]
属性)。它仅设置已由框架在ModelState
中设置的模型的属性,因此忽略了模型中的值。
有点奇怪的是ModelState
如果字段在查询字符串中不,则为字段提供不同的密钥。如果[HttpGet]
位于查询字符串中,则ModelState
仅将其用作键,但如果不是,则键变为ModelState
。如果属性的名称与其类型相同,则会出现异常:我有一个foo.bar.baz
模型类,另一个模型类有一个属性foo.footypename.bar.bartypename.baz
。名为名称的Name
类型的属性在public Name Name { get; set }
键中的类型名称后面永远不会跟随它们。但是,我还没有排除其特定属性排除其类型名称的其他可能原因。这是猜测。在我的模型中,所有情况下的“叶子”属性都不包括类型名称。是因为它们是系统已知的类型,还是“离开”,或者是什么?我不知道。
在任何情况下,模型的“root”类的叶属性始终使用自己的名称作为Name
中的键。
因此,您可以为模型分配广义答案。但是从查询字符串初始化有一个不同的具体答案。
更新
解决方案 - 修剪了很多代码
ModelState
答案 0 :(得分:1)
您可以使用默认值在控制器中初始化模型,然后像
一样使用它@Html.TextBoxFor(m => Model.Name)
控制器中的初始化:
public ActionResult Index()
{
MyModel model = new MyModel();
model.Name = "myname";
return View("myview", model);
}
您还可以在TextBoxFor
中设置属性@Html.TextBoxFor(m => Model.Name, new { value = "myname"})
<强>更新强>
如果您的网址看起来像mysite/Edit?id=123
,请尝试判断您的控制器操作,如
public ActionResult Edit(string id)
{ ...
还尝试使用HttpPost
或HttpGet
属性