1

我目前正在尝试修改默认 MVC 项目的注册组件以适应我的项目。为此,我修改了 RegisterModel、Register.aspx 和 AccountController。我可以很好地查看注册视图,但是当我提交时,我在标题中收到错误,并且它几乎没有给我带来问题的根源。有人可以引导我朝着正确的方向解决这个问题吗?

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

更新 2: 我修改了代码以更好地适应神秘人的建议。我为表单创建了一个 ViewModel 以将模型与逻辑分开。我仍然收到同样的错误。

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

注册型号:

[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; }

 }    

帐户控制器:

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

注册.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>

用户窗体模型:

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
4

2 回答 2

2

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

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

System.MissingMethodException:没有为此对象定义无参数构造函数。

您可以通过以下方式处理它:

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

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

于 2012-04-11T17:07:38.927 回答
0

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

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

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

这些都不会导致您看到的错误,尽管我不确定属性。尝试删除它并查看它是否有效。

于 2012-04-10T16:59:38.240 回答