Asp.NET MVC 模型绑定 - 使用绑定参数属性为简单类型分配前缀
我有一个 .net mvc 应用程序,带有一个接受用户注册帖子的控制器操作。 我有以下 UI 字段:电子邮件地址、名字、姓氏、密码和确认密码。 其中一些字段不属于模型对象(即确认密码不属于用户模型,仅属于密码)。 我的注册表单与登录表单位于同一视图中。 所以我必须在同一视图上建立独立的表单,每个表单发回不同的操作。
我想我可以为表单元素分配前缀,以分隔注册和登录之间的类似字段。 我遇到的问题是验证,如果发生错误,则会重新加载视图,显示验证消息,但电子邮件等字段(存在于登录和注册中)都将使用之前输入的地址填充。 此外,我在登录和注册字段上方都有一个验证摘要。 当注册期间发生错误时,两个验证摘要都会填充错误消息。 我认为为字段分配前缀(register.fieldname 和 login.fieldname)可能会帮助解决这些问题。
因此,当注册操作处理帖子时,它不再找到注册表字段的值,而是返回 null。 以下是用于此操作的方法签名...
任何有关此处发生的情况的输入都会很棒。
谢谢 Jeremy
public ActionResult Register([Bind(Prefix = "Register")] string emailAddress, [Bind(Prefix = "Register")] string firstName, [Bind(Prefix = "Register")] string LastName, [Bind(Prefix = "Register")] string password, [Bind(Prefix = "Register")] string confirmPassword)
和以下内容来自我的用户界面,它代表注册表单....
<h2>Create a New Account</h2>
<p>
Use the form below to create a new account.
</p>
<p>
Passwords are required to be a minimum of <%=Html.Encode(ViewData["PasswordLength"])%> characters in length.
</p>
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm("register", "account")) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<table>
<tr>
<td><label for="EmailAddress">Email Address:</label></td>
<td>
<%= Html.TextBox("Register.EmailAddress") %>
<%= Html.ValidationMessage("Register.EmailAddress")%>
</td>
</tr>
<tr>
<td><label for="FirstName">First Name</label></td>
<td>
<%= Html.TextBox("Register.FirstName")%>
<%= Html.ValidationMessage("Register.FirstName")%>
</td>
</tr>
<tr>
<td><label for="LastName">Last Name</label></td>
<td>
<%= Html.TextBox("Register.LastName")%>
<%= Html.ValidationMessage("Register.LastName")%>
</td>
</tr>
<tr>
<td><label for="password">Password:</label></td>
<td>
<%= Html.Password("Register.password")%>
<%= Html.ValidationMessage("Register.password")%>
</td>
</tr>
<tr>
<td><label for="confirmPassword">Confirm password:</label></td>
<td>
<%= Html.Password("Register.confirmPassword")%>
<%= Html.ValidationMessage("Register.confirmPassword")%>
</td>
</tr>
<tr>
<td colspan="2" class="alignright">
<input type="submit" value="Register" />
</td>
</tr>
</table>
</fieldset>
</div>
<% } %>
</div>
I have a .net mvc app with an controller action which accepts user registration posts.
I have the following UI fields: emailaddress, firstname, lastname, password, and confirmpassword. Some of these fields do not belong to a model object (i.e. confirm password does not belong to the user model, only password). My registration form resides on the same view as the login form. So I have to independent forms on the same view, each posting back to different actions.
I figured i could assign prefixes to the form elements to separate the like fields between register and login. The problem i had was on validation, if an error occurred, the view was re-loaded, a validation message was shown but fields like email (which exist in login and register) would both be populated with the previously entered address. In addition, i had a validation summary above both login and register fields. When an error occurred during registration, both validation summaries were populated with the error messages. I figured assigning prefixes to the fields (register.fieldname and login.fieldname) might help these problems.
So when the register action handles the post it no longer finds values for the registration form fields and instead returns null. The following is the method signature used for this action...
Any input as to what's going on here would be great.
Thanks
Jeremy
public ActionResult Register([Bind(Prefix = "Register")] string emailAddress, [Bind(Prefix = "Register")] string firstName, [Bind(Prefix = "Register")] string LastName, [Bind(Prefix = "Register")] string password, [Bind(Prefix = "Register")] string confirmPassword)
and the following is from my ui, it represents the registration form....
<h2>Create a New Account</h2>
<p>
Use the form below to create a new account.
</p>
<p>
Passwords are required to be a minimum of <%=Html.Encode(ViewData["PasswordLength"])%> characters in length.
</p>
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm("register", "account")) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<table>
<tr>
<td><label for="EmailAddress">Email Address:</label></td>
<td>
<%= Html.TextBox("Register.EmailAddress") %>
<%= Html.ValidationMessage("Register.EmailAddress")%>
</td>
</tr>
<tr>
<td><label for="FirstName">First Name</label></td>
<td>
<%= Html.TextBox("Register.FirstName")%>
<%= Html.ValidationMessage("Register.FirstName")%>
</td>
</tr>
<tr>
<td><label for="LastName">Last Name</label></td>
<td>
<%= Html.TextBox("Register.LastName")%>
<%= Html.ValidationMessage("Register.LastName")%>
</td>
</tr>
<tr>
<td><label for="password">Password:</label></td>
<td>
<%= Html.Password("Register.password")%>
<%= Html.ValidationMessage("Register.password")%>
</td>
</tr>
<tr>
<td><label for="confirmPassword">Confirm password:</label></td>
<td>
<%= Html.Password("Register.confirmPassword")%>
<%= Html.ValidationMessage("Register.confirmPassword")%>
</td>
</tr>
<tr>
<td colspan="2" class="alignright">
<input type="submit" value="Register" />
</td>
</tr>
</table>
</fieldset>
</div>
<% } %>
</div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为为了使用带前缀的 [Bind],您需要使用复杂类型。 您将相同的前缀与每个参数关联起来,这与 MVC 框架的工作方式不符。
您可以创建一个类型来处理表单帖子:
然后您可以将签名更改为:
I think in order to use [Bind] with a prefix, you need to use a complex type. You are associating the same prefix with each parameter, which doesn't work with the way that the MVC framework does it.
You can create a type to handle the form post:
Then you can change your signature to:
似乎对于 int 和 string 这样的简单类型,绑定前缀会覆盖参数的模型名称。 以您的操作方法为例,DefaultModelBinder 将查找所有参数的名称“Register”。
为了解决这个问题并且不需要复杂的类型,您需要指定完全限定名称,因为 Mvc 会将其呈现到 HTML 标记中。
将此应用到您的操作方法中,它应该如下所示:
It seems that for simple types like int and string, the Bind Prefix overrides the model name for the parameters. Using your action method as an example, the DefaultModelBinder would be looking for the name "Register" for all parameters.
In order to work around this and not require a complex type, you need to specify the fully qualified name as Mvc would render it into the HTML markup.
Applying this to your action method, it should look like this: