如何获得强类型 MVC 视图以 post 返回它传递的模型实例?
How do I get a Strongly typed MVC view to post back the instance of the model it's passed?
因此,我正在尝试采用我编写的视图来创建模型的实例,并使用它来编辑数据库中的现有实例。
因此,只需通过 ID 传入现有实例就非常简单
public ActionResult Index(int id)
{
return View(EntityContext.Policies.Where(x => x.ID == id).First());
}
我遇到的问题是当表单 posts:
@using (Html.BeginForm("Index", "Save", FormMethod.Post, new { @id = "form" }))
{
<fieldset>
...
@Html.TextBox("property")
@Html.TextBoxFor("otherProperty")
...
<input id="submit" type="submit" value="Save" />
</fieldset>
}
它post连接到的控制器:
public class SaveController : Controller
{
VectorDaemonContext vdContext = new VectorDaemonContext();
//
// POST: /Save/
[HttpPost]
public ActionResult Index(Policy policy, string property, int otherProperty) {
//Stuff to do with the policy
}
}
控制器获得了一个 Policy 对象,但它只设置了我在视图上显示并允许编辑的字段
我想做的是查看 post 从原始控制器获取的实例。这是我可以简单地做的事情吗?
据我所知,执行此操作的最简单方法是在视图中为策略 ID 创建一个隐藏字段,然后访问数据库以拉回原始实例。由于某些领域特定的问题,我已经不得不比我想要的更多地访问数据库,所以如果我能避免这种情况,我愿意。
我会把它贴在一个隐藏的字段中。是的,你可以简单地做到这一点。
@Html.HiddenFor(m => m.ID)
我只是胡乱猜测您在模型中定义了一个 ID
。但是你可以把它改成任何你想要的。
更正:
The simplest safest way I know of to do this would be to make a hidden field on the view for the ID of the Policy, then hit the database to pull back the original instance.
如果您将整个记录发送给客户,然后允许该客户 post 返回,即使您没有 "allow" 他们编辑字段。因为偷偷摸摸的客户可以绕过您的应用程序并直接 post 他们想要的任何数据并更改这些字段。因此,这样做是危险且不安全的。即使您信任您的客户,这也不是一个好主意。
安全的做法是只获取您希望他们输入的字段,并将它们应用于您从数据库服务器端检索的记录。这样,只有您允许他们更新的数据才会更改。
但是,如果您受约束并下定决心,那么执行此操作的方法是为您不希望用户看到或编辑的所有变量创建隐藏字段。如果您希望他们看到这些字段,但不能编辑,您可以使用文本框并将这些字段设置为只读(同样,用户可以绕过它,所以这不是真正的安全)。或者只显示数据并使用隐藏输入。
Web 浏览器只会 post 存在于表单元素中未被禁用的表单控件中的数据。 (或您在 ajax 请求中发送的数据)。因此,您想要 post 返回服务器的任何数据都必须存在于控件中。
您有多种选择,其中一些您已经知道:
- 通过
id
,重新从数据库中检索
- 将对象存储在模型中,将其值隐藏在隐藏字段中,然后将其整个传回
- 以某种方式缓存对象,在会话中或其他可用的缓存机制中(在会话中存储对象并不是一个好主意)。
由于 HTTP 无状态,您的控制器不会保留有关将哪个模型发送到哪个客户端的信息。
因此,我正在尝试采用我编写的视图来创建模型的实例,并使用它来编辑数据库中的现有实例。
因此,只需通过 ID 传入现有实例就非常简单
public ActionResult Index(int id)
{
return View(EntityContext.Policies.Where(x => x.ID == id).First());
}
我遇到的问题是当表单 posts:
@using (Html.BeginForm("Index", "Save", FormMethod.Post, new { @id = "form" }))
{
<fieldset>
...
@Html.TextBox("property")
@Html.TextBoxFor("otherProperty")
...
<input id="submit" type="submit" value="Save" />
</fieldset>
}
它post连接到的控制器:
public class SaveController : Controller
{
VectorDaemonContext vdContext = new VectorDaemonContext();
//
// POST: /Save/
[HttpPost]
public ActionResult Index(Policy policy, string property, int otherProperty) {
//Stuff to do with the policy
}
}
控制器获得了一个 Policy 对象,但它只设置了我在视图上显示并允许编辑的字段
我想做的是查看 post 从原始控制器获取的实例。这是我可以简单地做的事情吗?
据我所知,执行此操作的最简单方法是在视图中为策略 ID 创建一个隐藏字段,然后访问数据库以拉回原始实例。由于某些领域特定的问题,我已经不得不比我想要的更多地访问数据库,所以如果我能避免这种情况,我愿意。
我会把它贴在一个隐藏的字段中。是的,你可以简单地做到这一点。
@Html.HiddenFor(m => m.ID)
我只是胡乱猜测您在模型中定义了一个 ID
。但是你可以把它改成任何你想要的。
更正:
The
simplestsafest way I know of to do this would be to make a hidden field on the view for the ID of the Policy, then hit the database to pull back the original instance.
如果您将整个记录发送给客户,然后允许该客户 post 返回,即使您没有 "allow" 他们编辑字段。因为偷偷摸摸的客户可以绕过您的应用程序并直接 post 他们想要的任何数据并更改这些字段。因此,这样做是危险且不安全的。即使您信任您的客户,这也不是一个好主意。
安全的做法是只获取您希望他们输入的字段,并将它们应用于您从数据库服务器端检索的记录。这样,只有您允许他们更新的数据才会更改。
但是,如果您受约束并下定决心,那么执行此操作的方法是为您不希望用户看到或编辑的所有变量创建隐藏字段。如果您希望他们看到这些字段,但不能编辑,您可以使用文本框并将这些字段设置为只读(同样,用户可以绕过它,所以这不是真正的安全)。或者只显示数据并使用隐藏输入。
Web 浏览器只会 post 存在于表单元素中未被禁用的表单控件中的数据。 (或您在 ajax 请求中发送的数据)。因此,您想要 post 返回服务器的任何数据都必须存在于控件中。
您有多种选择,其中一些您已经知道:
- 通过
id
,重新从数据库中检索 - 将对象存储在模型中,将其值隐藏在隐藏字段中,然后将其整个传回
- 以某种方式缓存对象,在会话中或其他可用的缓存机制中(在会话中存储对象并不是一个好主意)。
由于 HTTP 无状态,您的控制器不会保留有关将哪个模型发送到哪个客户端的信息。