1

I am currently trying to modify the registration component of the default MVC project to accommodate a bit more to my project. I have modified the RegisterModel, Register.aspx and AccountController to do so. I can view the register view just fine, but when I submit, i get the error in the title, and it gives me little to nothing in the way of where the problem stems from. Can someone please steer me in the correct direction for me to fix this?

UPDATE: I have added the inner exception as well

UPDATE 2: I have modified the code to better form to Mystere Man's suggestions. I have created a ViewModel for the form to separate the model from logic. I am still receiving the same error.

Here is Model, View and Controller code:

RegisterModel:

[PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")]
public class RegisterModel
{

    [Required]
    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [Required]
    [DisplayName("Last Name")]
    public string LastName { get; set; }

    [DisplayName("Phone")]
    [DataType(DataType.PhoneNumber)]
    public string Phone { get; set; }

    [DisplayName("Fax")]
    [DataType(DataType.PhoneNumber)]
    public string Fax { get; set; }

    [Required]
    [DisplayName("User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    [DisplayName("Email address")]
    public string Email { get; set; }

    [Required]
    [ValidatePasswordLength]
    [DataType(DataType.Password)]
    [DisplayName("Password")]
    public string Password { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [DisplayName("Confirm password")]
    public string ConfirmPassword { get; set; }

 }    

AccountController:

public ActionResult Register()
{
    ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
    return View(new UserFormModel());
}

[HttpPost]
public ActionResult Register(UserFormModel model)
{

    ClaritySharetrackEntities db = new ClaritySharetrackEntities();

    if (ModelState.IsValid)
    {
        // Attempt to register the user
        MembershipCreateStatus createStatus = MembershipService.CreateUser(model.RegisterModel.UserName, model.RegisterModel.Password, model.RegisterModel.Email);

        if (createStatus == MembershipCreateStatus.Success)
        {
            MembershipUser user = Membership.GetUser(model.RegisterModel.UserName);
            int userid = Convert.ToInt32(user.ProviderUserKey);
            Profile profile = new Profile()
            {
                UserID = userid,
                FirstName = model.RegisterModel.FirstName,
                LastName = model.RegisterModel.LastName,
                Phone = model.RegisterModel.Phone,
                Fax = model.RegisterModel.Fax
            };

            db.Profiles.AddObject(profile);
            db.SaveChanges();

            //FormsService.SignIn(model.UserName, false /* createPersistentCookie */);
            return RedirectToAction("Welcome", "Home");
        }
        else
        {
            ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
        }
    }

    // If we got this far, something failed, redisplay form
    ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
    return View(model);
}

Register.aspx:

<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server">
    <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 <%: ViewData["PasswordLength"] %> characters in length.
    </p>

    <% using (Html.BeginForm()) { %>
        <%: Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") %>
        <div>
            <fieldset>
                <legend>Account Information</legend>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.FirstName) %>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.FirstName)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.FirstName)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.LastName) %>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.LastName)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.LastName)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.Phone) %>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.Phone)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.Phone)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.Fax) %>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.Fax)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.Fax)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.UserName) %>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.UserName)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.UserName)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.Email)%>
                </div>
                <div class="editor-field">
                    <%: Html.TextBoxFor(m =>m.RegisterModel.Email)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.Email)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.Password)%>
                </div>
                <div class="editor-field">
                    <%: Html.PasswordFor(m =>m.RegisterModel.Password) %>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.Password)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m =>m.RegisterModel.ConfirmPassword)%>
                </div>
                <div class="editor-field">
                    <%: Html.PasswordFor(m =>m.RegisterModel.ConfirmPassword)%>
                    <%: Html.ValidationMessageFor(m =>m.RegisterModel.ConfirmPassword)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m => m.RoleList) %>
                </div>
                <div class="editor-field">
                    <%: Html.DropDownListFor(m => m.RoleList, Model.RoleList) %>
                    <%: Html.ValidationMessageFor(m => m.RoleList)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m => m.ActiveList) %>
                </div>
                <div class="editor-field">
                    <%: Html.DropDownListFor(m => m.RoleList, Model.ActiveList)%>
                    <%: Html.ValidationMessageFor(m => m.ActiveList)%>
                </div>

                <div class="editor-label">
                    <%: Html.LabelFor(m => m.CompanyList) %>
                </div>
                <div class="editor-field">
                    <%: Html.DropDownListFor(m => m.RoleList, Model.CompanyList)%>
                    <%: Html.ValidationMessageFor(m => m.CompanyList)%>
                </div>

                <p>
                    <input type="submit" value="Register" />
                </p>
            </fieldset>
        </div>
    <% } %>
</asp:Content>

UserFormModel:

public class UserFormModel
{
    private ClaritySharetrackEntities entities = new ClaritySharetrackEntities();

    public RegisterModel RegisterModel { get; private set; }
    public SelectList ActiveList { get; private set; }
    public SelectList CompanyList { get; private set; }
    public SelectList RoleList { get; private set; }

    public UserFormModel()
    {
        SetActiveList();
        SetCompanyList();
        SetRoleList();
    }

    private void SetActiveList()
    {
        var activeList = new List<SelectListItem>{  new SelectListItem{Text = "Yes", Value = "True"},
                                                    new SelectListItem{Text = "No", Value = "False"},
                                                    };

        ActiveList = new SelectList(activeList, "Value", "Text");
    }

    private void SetCompanyList()
    {
        CompanyRepository companyRepository = new CompanyRepository();
        var companies = companyRepository.GetAllCompanies().Select(c => new { Text = c.CompanyName, Value = c.CompanyID });

        this.CompanyList = new SelectList(companies, "Value", "Text");
    }

    private void SetRoleList()
    {
        string[] roles = Roles.GetAllRoles();

        List<SelectListItem> roleList = new List<SelectListItem>();

        foreach (string str in roles)
        {
            SelectListItem listItem = new SelectListItem() { Text = str, Value = str };

            roleList.Add(listItem);
        }

        RoleList = new SelectList(roleList, "Value", "Text");
    }
}

Inner Exception:

[MissingMethodException: No parameterless constructor defined for this object.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
   System.Activator.CreateInstance(Type type) +6
   System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +403
   System.Web.Mvc.DefaultModelBinder.BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult valueProviderResult) +544
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +479
   System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +45
   System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +658
   System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +147
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +98
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +2504
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +548
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +473
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +181
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830
   System.Web.Mvc.Controller.ExecuteCore() +136
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +111
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +65
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +44
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +42
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +141
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +54
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +52
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +690
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +194
2
  • In your exception you should have an InnerException with more detail Commented Apr 10, 2012 at 16:56
  • I have updated the information to show the inner exception. Thanks Commented Apr 10, 2012 at 16:58

2 Answers 2

2

I know you have this working now - which is great.

Just wanted to post a note here: Be careful when using SelectList in your Models. Your model will expect a SelectList but your action is probably returning id of the object selected - this will throw the

System.MissingMethodException: No parameterless constructor defined for this object.

You can handle it with something along these lines:

[Bind(Exclude = "List")]
public class UserFormModel
{
    public SelectList List { get; set; }
    public int SelectedItem { get; set; }
}

Just easy to miss and can be frustrating chasing down a parameter constructor error - so I wanted to note that here.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I believe this was actually the cause of the problem
@PatG - Not exactly your problem, but it's close. Your real problem was that you were using Html.DropDownListFor(m => m.RoleList, Model.ActiveList) in yoru view. m.RoleList is defined in your model as a SelectList, but your view is returning a selected item. You also use the same RoleList for all of your dropdowns, which is somewhat confusing as well (they will overwrite each other). I hadn't noticed this the other day.
0

First, it's a bad idea to do data access in your model. Models shold be dumb, and they should not populate themselves. It's ok to create empty lists and such in the constructor, but don't do data access.

Second, Where you are doing data access, you're not disposing of the context. You should have a using statement there to automatically call Dispose on the context.

Third, don't use that "PropertiesMustMatch" attribute, instead use the Compare attribute on the ConfirmPassword property.

None of those things should cause the error you're seeing, though i'm not sure about the Attribute. Try removing it and seeing if it works.

9 Comments

Thank you for responding. I do not hit the breakpoint on the first statement of the post method. My application actually doesnt even break when I get this error while debugging.
@PatG - i updated my message after you provided the stack trace. The error is occuring in the model binder, so it's a problem with your model. The only potential problem I see is the PropertiesMustMatch attribute, remove it and see if that's the problem.
I have commented out the attribute but I am still coming across with the same error. I find this weird in that it does not pause the debugger when this error is invoked.
@PatG - It doesn't pause the debugger because it's happening in the Model Binder, which occurs before your method is called. There's nothing weird about that. However, there is nothing in your model that should cause that error, unless you have TWO RegisterModel classes and the framework is seeing the wrong one.
That is my Linq2Entities object. As far as the model goes, I took out all the data access code, and put it in another ViewModel object that just exposes the RegisterModel's properties. I also noticed that I don't even use that object in the UserFormModel, it is just residue from something else
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.