2012-04-10 92 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

相關問題