3

I am new to MVC and I am trying to build a small test application to get a clear idea about how the SimpleMembershipProvider works in MVC 4. I have created two Roles - Student and Teacher. I have only one user with Teacher Role assigned(hard coded in Configuration.cs), who is going to create Students and while creating a new student, the Teacher will also generate the UserID and password for that student.The newly created student will then log on to the application with the userid and password as created by the Teacher and will do certain tasks. The problem is whenever the user with Teacher Role creates a student, the current logged in user with Teacher Role gets logged out and the newly created student gets logged in. What I have done is, I have not kept any field for userid and password in Student Model. I have used a partial view bound to RegisterModel(from AccountModels) to generate the fields for Username and password while creating new Student. I have kept StudentID in UserProfile Model. This is my code as shown below for further clarity.

Student Model

public class Student 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

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

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

    [DisplayName("Date of Birth")]
    public string DateOfBirth { get; set; }

    public Gender Gender { get; set; }

    public virtual ICollection<Course> Courses { get; set; }
}

UserProfile Model

    public class UserProfile
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public int StudentId { get; set; }
    }

This is from Configuration.cs where I am creating the Roles and a user with Teacher Role

        private void SeedMemebership()
        {
            WebSecurity.InitializeDatabaseConnection("DefaultConnection1",
                "UserProfile", "UserId", "UserName", autoCreateTables: true);

            var roles = (SimpleRoleProvider)Roles.Provider;
            var membership = (SimpleMembershipProvider)Membership.Provider;

            if (!roles.RoleExists("Teacher"))
            {
                roles.CreateRole("Teacher");
            }
            if (!roles.RoleExists("Student"))
            {
                roles.CreateRole("Student");
            }
            if (membership.GetUser("UserFoo", false) == null)
            {
                membership.CreateUserAndAccount("UserFoo", "Password");
            }
            if (!roles.GetRolesForUser("UserFoo").Contains("Teacher"))
            {
                roles.AddUsersToRoles(new[] { "UserFoo" }, new[] { "Teacher" });
            }
        }

Controller Actions To Create Student-

//
        // GET: /Student/Create
        [Authorize(Roles = "Teacher", Users = "UserFoo")]
        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Student/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Student student, RegisterModel model)
        {

            if (ModelState.IsValid)
            {
                try
                {
                    db.Students.Add(student);
                    db.SaveChanges();
                    WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { StudentId = student.Id });
                    WebSecurity.Login(model.UserName, model.Password);
                    return RedirectToAction("Index", "Student");
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }

            }

            return View(student);
        }

Corresponding Views -

@model TestApp.Models.Student

@{
    ViewBag.Title = "Create";
}



<script type="text/javascript" src="~/Scripts/MyCustom.js"></script>

<h2>Create</h2>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Student</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.DateOfBirth)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.DateOfBirth)
            @Html.ValidationMessageFor(model => model.DateOfBirth)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Gender)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(typeof(TestApp.Models.Gender))))
            @Html.ValidationMessageFor(model => model.Gender)
        </div>



        <div class="float-right-top">
            @Html.Partial("_PartialRegisterStudent")
        </div>


        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

}


<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Partial View "_PartialRegisterStudent.cshtml

@model TestApp.Models.RegisterModel

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
        </ol>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

What will be the best way to create students with Teacher Role without the logged in user logging out of the application? I thought about using inheritance(Parent - UserProfile, Child-Student) and one to one relationship between student model and userprofile model but could not make out how to make it work. Code Samples will be very much appreciated!

P.S. Parden me if this post is a bit lengthy. Thank you.

Aritra B
  • 1,726
  • 6
  • 29
  • 45

1 Answers1

3

Just delete below line in Create Action, it should work.

WebSecurity.Login(model.UserName, model.Password);
Lin
  • 15,078
  • 4
  • 47
  • 49
  • Thank you very much for the comment. I need to use this one `WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { StudentId = student.Id });` The above line of code is just creating a new object of UserProfile and Membership class, everytime a new student is created.I believe, I very much need this line of code for authorising logins. – user2997006 Nov 29 '13 at 19:54
  • Just delete one line like I posted. – Lin Nov 29 '13 at 19:56
  • I am not sure about the `Websecurity.login` method. I will try and let you know. – user2997006 Nov 29 '13 at 19:56
  • I know, it's because you have "WebSecurity.Login" in your create Action method, that's why it kicks teacher role users out. – Lin Nov 29 '13 at 19:58
  • Lin, incase your suggestion works, I will definitely mark your post as the answer. – user2997006 Nov 29 '13 at 20:25
  • It works,thank you Lin. What would have been the best approach? I mean how could have I used UserProfile class in other ways to get the same result? If I want to use inheritance, how should i go about it? – user2997006 Nov 30 '13 at 06:05
  • You can use UserProfile to store extra information for the users, not only like names but also you can store foreign key properties. Your question is a bit broad, I'm not sure exactly what you want to achieve. Below link might help you. If you want, you can give me a more specific example. http://stackoverflow.com/questions/12435252/how-to-create-custom-additional-fields-in-userprofile-in-mvc4 – Lin Nov 30 '13 at 19:51