ASP。NET MVC 3 -在视图中处理模型的最佳实践

时间:2022-09-18 08:10:37

I am using ASP.NET MVC 3 and have several pages where the majority of the View Model is read-only. An example field would be like such:

我用ASP。NET MVC 3,并且有几个页面,其中大多数视图模型是只读的。一个示例字段是这样的:

<div class="display-label">My Field</div>
<div class="display-field">@Model.MyField</div>

I then have a field where the user has to type in some verification text like so:

然后我有一个字段,用户必须输入一些验证文本,比如:

@Html.LabelFor(model => model.Verification)
@Html.PasswordFor(model => model.Verification)

When the user submits the form and it hits my controller, the ViewModel's fields are all null except for the Verification field. The way I have gotten around this, thus far, is to have several HiddenFor fields like such:

当用户提交表单并点击我的控制器时,ViewModel的字段都是空的,除了验证字段。到目前为止,我解决这一问题的方法是,在诸如此类的领域进行一些隐藏:

@Html.HiddenFor(model => model.MyField)

However, this gets ugly really fast. Is there a better way to handle the model in the view state so during the POST of the form submission, I can get all of my fields? This is important in case the verification text does not match during the POST and I need to return the view model without re-retrieving it from the database.

然而,这很快就会变得很丑。是否有更好的方法来处理视图状态下的模型,以便在提交表单时,我可以获得所有字段?如果验证文本在发布过程中不匹配,并且我需要返回视图模型而不从数据库中重新检索它,这一点很重要。

Thanks for any suggestions.

谢谢你的任何建议。

2 个解决方案

#1


3  

There is no better way around it without re-retrieving the value from the database. The reason is because MVC's model binding only looks at the GET or POST parameters to bind the MyField to the action's model, and if the GET/POST parameters don't have a MyField value then it has to keep that property as null (how else is it going to know what the value shouldbe?)

如果不从数据库中重新检索值,就没有更好的方法绕过它。原因是MVC模型绑定只看GET或POST参数绑定MyField行动的模式,如果GET / POST参数没有MyField然后继续,属性值为null(其他是怎么知道价值内涵?)

In order for the model binder to see your MyField value is to pass it in the GET/POST parameters, and to do this you have to explicitly tell your view's form to pass the value in via Html.HiddenFor(). There's no way for the view to automatically know to send that property in the post/get parameters.

为了让模型绑定器看到MyField值,必须在GET/POST参数中传递它,为此必须显式地告诉视图的窗体,通过Html.HiddenFor()传递值。视图无法自动知道如何在post/get参数中发送该属性。

However one idea you can look at is to create a Razor (or Html) helper method that takes a field name and an expression (the x => x.MyField) and writes the following output for you:

不过,您可以考虑的一个想法是创建一个Razor(或Html) helper方法,该方法接受字段名和表达式(x => x. myfield),并为您编写以下输出:

<div class="display-label">My Field</div>
<div class="display-field">@Model.MyField</div>
@Html.HiddenFor(model => model.MyField)

This means you only have to write one line of code (something like @Html.ShowReadOnlyField(x => x.MyField, "My Field") instead of those 3 lines. However, this also assumes that everywhere you want to do this will have the same div structure.

这意味着您只需编写一行代码(比如@Html)。ShowReadOnlyField x(x = >。我的领域,“我的领域”)而不是这三行。但是,这也假定您想要这样做的任何地方都具有相同的div结构。

Edit: Just keep in mind the security concerns about read-only fields, because they aren't truly read-only.. It is better to re-retrieve this data from the database if this data is going to be used for anything in the controller, because even though it's read only on the HTML form, users can still set this value to anything they want by manipulating the POST/GET data.

编辑:记住只读字段的安全性问题,因为它们不是真正的只读。如果这个数据将用于控制器中的任何内容,最好从数据库中重新检索这个数据,因为即使它仅在HTML表单上读取,用户仍然可以通过操作POST/GET数据将这个值设置为任何他们想要的值。

#2


0  

Please try to serialize the Model in the Page and then do a Post? This Should Solve the Problem.

请尝试在页面中序列化模型,然后发布一个帖子?这应该能解决问题。

<%= Html.Serialize("User",Model) %>

[HttpPost]   
public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm)
{

}

#1


3  

There is no better way around it without re-retrieving the value from the database. The reason is because MVC's model binding only looks at the GET or POST parameters to bind the MyField to the action's model, and if the GET/POST parameters don't have a MyField value then it has to keep that property as null (how else is it going to know what the value shouldbe?)

如果不从数据库中重新检索值,就没有更好的方法绕过它。原因是MVC模型绑定只看GET或POST参数绑定MyField行动的模式,如果GET / POST参数没有MyField然后继续,属性值为null(其他是怎么知道价值内涵?)

In order for the model binder to see your MyField value is to pass it in the GET/POST parameters, and to do this you have to explicitly tell your view's form to pass the value in via Html.HiddenFor(). There's no way for the view to automatically know to send that property in the post/get parameters.

为了让模型绑定器看到MyField值,必须在GET/POST参数中传递它,为此必须显式地告诉视图的窗体,通过Html.HiddenFor()传递值。视图无法自动知道如何在post/get参数中发送该属性。

However one idea you can look at is to create a Razor (or Html) helper method that takes a field name and an expression (the x => x.MyField) and writes the following output for you:

不过,您可以考虑的一个想法是创建一个Razor(或Html) helper方法,该方法接受字段名和表达式(x => x. myfield),并为您编写以下输出:

<div class="display-label">My Field</div>
<div class="display-field">@Model.MyField</div>
@Html.HiddenFor(model => model.MyField)

This means you only have to write one line of code (something like @Html.ShowReadOnlyField(x => x.MyField, "My Field") instead of those 3 lines. However, this also assumes that everywhere you want to do this will have the same div structure.

这意味着您只需编写一行代码(比如@Html)。ShowReadOnlyField x(x = >。我的领域,“我的领域”)而不是这三行。但是,这也假定您想要这样做的任何地方都具有相同的div结构。

Edit: Just keep in mind the security concerns about read-only fields, because they aren't truly read-only.. It is better to re-retrieve this data from the database if this data is going to be used for anything in the controller, because even though it's read only on the HTML form, users can still set this value to anything they want by manipulating the POST/GET data.

编辑:记住只读字段的安全性问题,因为它们不是真正的只读。如果这个数据将用于控制器中的任何内容,最好从数据库中重新检索这个数据,因为即使它仅在HTML表单上读取,用户仍然可以通过操作POST/GET数据将这个值设置为任何他们想要的值。

#2


0  

Please try to serialize the Model in the Page and then do a Post? This Should Solve the Problem.

请尝试在页面中序列化模型,然后发布一个帖子?这应该能解决问题。

<%= Html.Serialize("User",Model) %>

[HttpPost]   
public ActionResult Register([DeserializeAttribute] User user, FormCollection userForm)
{

}