ASP.NET MVC2:“System.MissingMethodException:没有为此对象定义的无参数构造函数。”

时间:2012-04-10 16:45:03

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-2

我目前正在尝试修改默认MVC项目的注册组件,以便为我的项目提供更多功能。我修改了RegisterModel,Register.aspx和AccountController这样做。我可以很好地查看寄存器视图,但是当我提交时,我会在标题中看到错误,并且它在问题源自何处的方式上几乎没有任何帮助。有人可以指导我正确的方向让我解决这个问题吗?

更新: 我已添加了内部异常

更新2: 我修改了代码以更好地形成Mystere Man的建议。我为表单创建了一个ViewModel,以便将模型与逻辑分开。我仍然收到同样的错误。

这是模型,视图和控制器代码:

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");
    }
}

内部例外:

[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 个答案:

答案 0 :(得分:2)

我知道你现在有这个工作 - 这很棒。

只想在此处发布注释:在模型中使用SelectList时要小心。您的模型将期望一个SelectList,但您的操作可能返回所选对象的id - 这将抛出

  

System.MissingMethodException:未定义无参数构造函数   对于这个对象。

您可以按照以下方式处理:

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

很容易错过并且可能会令人沮丧地追逐参数构造函数错误 - 所以我想在这里注意。

答案 1 :(得分:0)

首先,在模型中进行数据访问是个坏主意。模特应该是愚蠢的,他们不应该填充自己。可以在构造函数中创建空列表等,但不要进行数据访问。

其次,在进行数据访问的地方,你不会处理上下文。你应该在那里有一个using语句来自动调用上下文中的Dispose。

第三,不要使用“PropertiesMustMatch”属性,而是使用ConfirmPassword属性上的Compare属性。

这些东西都不应该导致你看到的错误,虽然我不确定属性。尝试删除它,看看它是否有效。