views:

2584

answers:

1

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>
+3  A: 

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:

public class RegistrationForm {
 string EmailAddress {get;set;}
 string FirstName {get;set;}
 string LastName {get;set;}
 string Password {get;set;} 
 string ConfirmPassword {get;set;}
}

Then you can change your signature to:

public ActionResult Register(RegistrationForm register) {
...
}