bitwiser
bitwiser

Reputation: 221

Model Passing Problems

So I have a UserDisplayModel with the default MembershipUser as a property, and I'm trying to pass the whole view model to the controller, but for some reason the MembershipUser property and likely the whole model gets lost.

I found this out because I get a No parameterless constructor defined for this object error unless I manually instantiate the MembershipUser inside the display model constructor). Meaning the second action (posted below) tried to make a new UserDisplayModel and errors because MembershipUser has no default constructor.

Here's my code:

Model

public class UserDisplayModel
{
    public MembershipUser User { get; set; }

    public UserDisplayModel(string id)
    {
        this.User = Membership.GetUser(id);
    }
}

Actions

public ActionResult Delete(string id)
{
    UserDisplayModel model = new UserDisplayModel(id);

    return PartialView("Delete", model);
}

[HttpPost]
public ActionResult Delete(UserDisplayModel model)
{
    Membership.DeleteUser(model.User.UserName);
}

View

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcWebRole1.Models.UserDisplayModel>" %>

<p>Are you sure you want to delete the following user?</p>

<h2><%: Model.User.UserName%></h2>

<% using (Html.BeginForm()) { %>
    <p>
        <%: Html.HiddenFor(model => model.User.UserName)%>
        <input type="submit" value="Delete" class="small alert button" />
        <input type="button" value="Cancel" class="small secondary button cancel-action" />
    </p>
<% } %>

Is it possible to have this work, or does asp.net just not like having models inside models? Or did I just miss something silly?

Upvotes: 0

Views: 112

Answers (2)

Erik Philips
Erik Philips

Reputation: 54628

The error:

No parameterless constructor defined for this object

Is caused by

[HttpPost]
public ActionResult Delete(UserDisplayModel model)
{
    Membership.DeleteUser(model.User.UserName);
}

As UserDisplayModel has no parameterless constructor for MVC to instantiate. It only has the constructor:

public UserDisplayModel(string id)
{
    this.User = Membership.GetUser(id);
}

I would probably changed the method too look like:

[HttpPost]
public ActionResult Delete(string userName)
{
    Membership.DeleteUser(userName);
}

Or to be a little more MVC

public class DeleteUserModel
{
    public DeleteUser User { get; set; }

    public class DeleteUser
    {
        public string Username { get; set; }
    }
}

[HttpPost]
public ActionResult Delete(DeleteUserModel model)
{
    Membership.DeleteUser(model.User.UserName);
}

Upvotes: 0

Forty-Two
Forty-Two

Reputation: 7605

It looks like all you really need here is the username. So I would change the model to be

public class UserDisplayModel
{
    public string Username { get; set; }

}

Upvotes: 1

Related Questions