ASP .NET MVC. Problems with models and forms
I am trying to post a part of my model for a view to action in another controller. I've tried to do it this way:
<% using (Html.BeginForm("Register", "User", new {createDto = Model.UserCreateDto}, FormMethod.Post))
{%>
Form code here...
<%}%>
UserCreateDto is a part of my model and it's being filled in this form. I'm trying to pass it to "Register" action in UsersController:
[HttpPost]
public ActionResult Register(UserCreateDto createDto)
The problem is that route value in Register action is null (createDto) after form submit. Maybe it is happening because route values are being attached to url before form submit event (and before model fields are filled).
Is there any way to do what I want? UPDATE Here is the actual HTML code:<form action="/User/Register" id="form1" method="post">
<input id="UserCreateDto_Username" name="UserCreateDto.Username" type="hidden" value="" />
<input id="UserCreateDto_Password" name="UserCreateDto.Password" type="hidden" value="" />
<input id="UserCreateDto_Email" name="UserCreateDto.Email" type="hidden" value="" />
<input id="UserCreateDto_Active" name="UserCreateDto.Active" type="hidden" value="" />
<span class="field-validation-valid" id="UserCreateDto_Username_validationMessage"></span><br /><label for="UserCreateDto_Username">Имя пользователя</label><br /><input id="UserCreateDto_Username" name="UserCreateDto.Username" type="text" value="" /><br />
<span class="field-validation-valid" id开发者_运维百科="UserCreateDto_Password_validationMessage"></span><br /><label for="UserCreateDto_Password">Пароль</label><br /><input id="UserCreateDto_Password" name="UserCreateDto.Password" type="text" value="" /><br />
<span class="field-validation-valid" id="UserCreateDto_Email_validationMessage"></span><br /><label for="UserCreateDto_Email">E-mail</label><br /><input id="UserCreateDto_Email" name="UserCreateDto.Email" type="text" value="" /><br />
<input type="submit" value="Register"/>
</form>
And here is the updated form code:
<% using (Html.BeginForm("Register", "User", FormMethod.Post))
{%>
<%: Html.HiddenFor(userCreateDto => Model.UserCreateDto.Username) %>
<%: Html.HiddenFor(userCreateDto => Model.UserCreateDto.Password) %>
<%: Html.HiddenFor(userCreateDto => Model.UserCreateDto.Email) %>
<%: Html.HiddenFor(userCreateDto => Model.UserCreateDto.Active) %>
<%= Html.LabeledValidatedTextBoxFor(username => Model.UserCreateDto.Username, true) %>
<%= Html.LabeledValidatedTextBoxFor(password => Model.UserCreateDto.Password, true)%>
<%= Html.LabeledValidatedTextBoxFor(email => Model.UserCreateDto.Email, true)%>
<input type="submit" value="Register"/>
<%}%>
Html.LabeledValidatedTextBoxFor
is just my custon HTML helper.
[HttpPost]
public ActionResult Register(UserCreateDto userCreateDto)
userСreateDto in this action is still null. By the way, is there any way not to use hidden fields? They are not secure enough to pass through them user registration information.
Assuming that UserCreateDto is a class, this won't work as it will serialize it to a string in the form action url. What you want to do, probably, is use hidden fields to populate the UserCreateDto fields in the form itself. This will allow the properties of the model to set in the form parameters when the form is posted back, allowing the model binder to do its work and reconstitute the object in the action method parameters.
<% using (Html.BeginForm("Register", "User"))
{%>
<%: Html.HiddenFor( model => model.UserCreateDto.UserID ) %>
<%: Html.HiddenFor( model => model.UserCreateDto.Username ) %>
...
<%}%>
On the server side it should look like this:
[HttpPost]
public ActionResult Register(UserCreateDto userCreateDto)
[Edit]
Alternatively, you could just store the UserCreateDto in the user's session and retrieve it on post since you don't trust putting the data in a hidden field.
I decided to use partial views so that all user registration logic now is incapsulated in Users controller. Also I've started to use Ajax forms (with the help of JQuery).
精彩评论