2012-04-10 124 views
1

我目前正在尝试修改默认MVC项目的注册组件以适应我的项目。我已经修改了RegisterModel,Register.aspx和AccountController来做到这一点。我可以很好地查看寄存器视图,但是当我提交时,我在标题中看到了错误,并且在问题源于哪里的情况下,我几乎没有任何问题。有人可以引导我正确的方向为我解决这个问题吗?ASP.NET MVC2:“System.MissingMethodException:为此对象定义的无参数构造函数。”

UPDATE:我已经添加了内部异常以及

更新2:我已经修改了代码,以更好的形式空军终于人的建议。我已经为表单创建了一个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 
+0

在你的异常中,你应该有一个更多细节的InnerException – Patrick 2012-04-10 16:56:35

+0

我已更新信息以显示内部异常。谢谢 – PatG 2012-04-10 16:58:59

回答

2

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

只是想在这里发表一个提示:在模型中使用SelectList时要小心。您的模型将期望的SelectList但是你的行动很可能返回所选对象的ID - 这将引发

system.missingMethodException而:无参数的构造函数为该对象定义 。

你可以沿着这些路线的东西处理:

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

就容易错过,可以是令人沮丧的追逐下一个参数的构造函数的错误 - 所以我想指出的是,这里。

+0

谢谢,我相信这实际上是问题的原因 – PatG 2012-04-16 18:22:49

+0

@PatG - 不完全是你的问题,但它很接近。你真正的问题是你在yoru视图中使用'Html.DropDownListFor(m => m.RoleList,Model.ActiveList)'。 'm.RoleList'在您的模型中被定义为一个SelectList,但是您的视图正在返回一个选定的项目。您也可以对所有下拉列表使用相同的RoleList,这也有点令人困惑(它们会相互覆盖)。我有一天没有注意到这一点。 – 2012-04-16 23:12:24

0

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

第二,如果您正在进行数据访问,则不会处理上下文。你应该有一个使用语句来在上下文中自动调用Dispose。

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

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

+0

谢谢你的回应。我没有在post方法的第一个语句中触发断点。当我在调试时遇到这个错误时,我的应用程序甚至不会中断。 – PatG 2012-04-10 17:02:33

+0

@PatG - 在提供堆栈跟踪后,我更新了消息。该错误发生在模型联编程序中,所以这是您模型的问题。我看到的唯一潜在问题是PropertiesMustMatch属性,将其删除并查看是否存在问题。 – 2012-04-10 17:05:47

+0

我已经注释掉了这个属性,但我仍然遇到了同样的错误。我觉得这很奇怪,因为它在调用这个错误时不会暂停调试器。 – PatG 2012-04-10 18:13:18

相关问题