1
\$\begingroup\$

I have login page that looks like:

enter image description here

It has a ViewModelBase and a ViewModel as:

public abstract class UserViewModelBase
{
    private string userId;

    private LdapDirectory ldapDir;

    private XXXPerson userDetails;

    public UserViewModelBase()
    {
        ldapDir = new LdapDirectory();

        if (HttpContext.Current.Request.IsAuthenticated)
        {
            userDetails = ldapDir.GetUser(UserId, DirectoryInfoDepth.Roles);
        }
    }

    [Required]
    [Display(Name = "User Name")]
    [StringLength(20)]
    public string UserName { get; set; }

    [Required]
    [Display(Name = "Password")]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    public string UserId
    {
        get
        {
            return HttpContext.Current.User.Identity.Name;
        }
    }

    public string FirstName
    {
        get
        {
            return userDetails.FirstName;
        }
    }

    public string LastName
    {
        get
        {
            return userDetails.LastName;
        }
    }

    public string Country
    {
        get
        {
            return userDetails.Country;
        }
    }

    public bool CanViewXXX
    {
        get 
        { 
            return true; //Will call an API to get values 
        }
    }

    public bool CanViewRequiredXXX
    {
        get
        {
            return true; //Will call an API to get values
        }
    }

    public bool CanViewActualXXX
    {
        get { return true; } //Will call an API to get values
    }

    public bool CanViewReports
    {
        get { return true; } //Will call an API to get values
    }

    public bool CanViewAggregations
    {
        get { return true; } //Will call an API to get values
    }

    public bool CanViewSystemParameter
    {
        get { return true; } //Will call an API to get values
    }

    public string PreferedReportFormat { get; set; }

    public string PreferedEmailId { get; set; }
}

public class UserViewModel : UserViewModelBase
{
    public bool IsValid(string userName, string password)
    {
        LdapDirectory ldapDir = new LdapDirectory();

        if (ldapDir.AuthenticateUser(userName, password))
        {
            var userDetails = ldapDir.GetUser(userName, DirectoryInfoDepth.Roles);
            FormsAuthentication.SetAuthCookie(userDetails.Uid, false);
            return true;
        }
        else
            return false;
    }

    public void Logout()
    {
        FormsAuthentication.SignOut();
    }
}

Controller as:

    public class AccountController : Controller
{
    // GET: Account/Account
    [AllowAnonymous]
    public ActionResult Login()
    {
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(ViewModel.UserViewModel user)
    {
        if (ModelState.IsValid)
        {
            if (user.IsValid(user.UserName, user.Password))
            {
                return RedirectToAction("Index", "SystemParameter", new { area = "SystemParameter" });
            }
            else
            {
                ModelState.AddModelError("", "Login data is incorrect!");
            }
        }
        return View(user);
    }

    [Authorize]
    public ActionResult LogOut()
    {
        ViewModel.UserViewModel xUser = new ViewModel.UserViewModel();
        xUser.Logout();
        return RedirectToAction("Login", "Account", new { area = "Account" });
    }
}

Login.cshtml

    @model XXX.Areas.Account.ViewModel.UserViewModel

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>XXX - Login - @System.Configuration.ConfigurationManager.AppSettings["AppVersion"]</title>

    @Styles.Render("~/Content/css")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryui")
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/bootstrap")

    <script>
        $(function () {
            $("#UserName").on("keypress", function () {
                //$(this).parent().find('div[class=popover]').html("");
                $("[data-valmsg-for=UserName]").html("");
            });

            $("#Password").on("keypress", function () {
                $(this).parent().find('div[class=popover]').remove();
                //$(this).parent().find('div[class=popover]').html("");
                $("[data-valmsg-for=Password]").html("");
            });
        });
    </script>
</head>
<body>

    <div class="container">
        <div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <div class="panel-title">XXX</div>
                    <div style="float:right;  position: relative; top:-20px">Log In</div>
                </div>

                <div style="padding-top:30px" class="panel-body">

                    @using (Html.BeginForm(null, null, FormMethod.Post, new { @class = "form-horizontal", id = "loginForm", @role = "form" }))
                    {

                        @Html.AntiForgeryToken()


                        <div style="margin-bottom: 25px" class="input-group">
                            <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                            @Html.TextBoxFor(u => u.UserName, new { @id = "login-username", @class = "form-control", @placeholder = "User Name", @data_toggle = "popover", @data_placement = "top" })

                        </div>
                        @Html.ValidationMessageFor(u => u.UserName)

                        <div style="margin-bottom: 25px" class="input-group">
                            <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                            @Html.PasswordFor(u => u.Password, new { @id = "login-password", @class = "form-control", @placeholder = "Password", @data_toggle = "popover", @data_placement = "top" })

                        </div>
                        @Html.ValidationMessageFor(u => u.Password)

                        <div style="margin-top:10px" class="form-group">
                            <!-- Button -->
                            <div class="col-sm-12 controls">
                                <button type="submit" id="btn-login" class="btn btn-primary btn-success">Log In</button>
                            </div>
                        </div>


                        <div class="form-group">
                            <div class="col-md-12 control">
                                <div style="border-top: 1px solid#888; padding-top:15px;">
                                    @Html.ValidationSummary(true, null, new { @class = "text-danger" })
                                </div>
                            </div>
                        </div>
                    }
                </div>
            </div>
        </div>
    </div>
</body>
</html>

Now after login user is redirected to one of the main page of the site that has a _Layout file:

@model XXX.Areas.Account.ViewModel.UserViewModelBase

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <title>XXX - @System.Configuration.ConfigurationManager.AppSettings["AppVersion"]</title>

    @Styles.Render("~/Content/css")
    @Styles.Render("~/Content/jqwidgets")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/jqueryui")
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/jqwidgets")

    <script>
        $(function () {
            $("#userPreferences").click(function () {
                $("#dialog").html('<img src="../Styles/images/CircularProgressAnimation.gif" alt="Please wait..." />');
                $("#dialog").css("display", "");//show the dialog div
                $('#dialog').dialog({
                    dragable: true,
                    resizable: false,
                    title: this.title,
                    modal: true,
                    width: Math.min(450, $(window).width() * .8),
                    position: {
                        my: "center top",
                        at: ("center top+" + ($(window).height() * .1)),
                        collision: "none"
                    },
                    open: function (event, ui) {
                        //Load the UserPreferences action which will return the partial view UserPreferences
                        $(this).load('/Common/UserPreferences' + "?t=" + new Date().getTime());
                    },
                    close: function () {
                        $(this).dialog('destroy').html('');
                    }
                });
            });
        });
    </script>

</head>
<body>

    <div id="navbar" class="navbar navbar-custom navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            @*Class container must be modified as per need*@
            <div class="navbar-header">

                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("XXX", "Login", "Account", new { area = "Account" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse"  id="MainMenu" aria-expanded="false" style="height: 1px;">
                <ul class="nav navbar-nav">
                    @if (Model.CanViewXXX)
                    {
                    <li class="dropdown">@Html.ActionLink("View XXX", "Index", "View", new { area = "View" }, null)</li>
                    }
                    @if (Model.CanViewRequiredXXX)
                    {
                    <li>@Html.ActionLink("Required XXX", "Index", "Required", new { area = "Required" }, null)</li>
                    }
                    @if (Model.CanViewActualXXX)
                    {
                    <li>@Html.ActionLink("Actual XXX", "Index", "Actual", new { area = "Actual" }, null)</li>
                    }
                    @if (Model.CanViewReports)
                    {
                    <li>@Html.ActionLink("Reports", "Index", "Report", new { area = "Report" }, null)</li>
                    }
                    @if (Model.CanViewAggregations)
                    {
                    <li>@Html.ActionLink("Aggregations", "Index", "Aggregation", new { area = "Aggregation" }, null)</li>
                    }
                    @if (Model.CanViewSystemParameter)
                    {
                    <li class="active">@Html.ActionLink("XXX Parameters", "Index", "SystemParameter", new { area = "SystemParameter" }, null)</li>
                    }
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                            <span class="glyphicon glyphicon-user"></span>
                            <strong>
                                @if (Request.IsAuthenticated)
                                {
                                @Model.UserId
                                }
                                else
                                {
                                @: Hello!!!
                                }
                            </strong>
                            <span class="glyphicon glyphicon-chevron-down"></span>
                        </a>
                        <ul class="dropdown-menu">
                            <li>
                                <div class="navbar-login">
                                    <div class="row">
                                        <div class="col-lg-4">
                                            <p class="text-center">
                                                <span class="glyphicon glyphicon-user icon-size"></span>
                                            </p>
                                        </div>
                                        <div class="col-lg-8">
                                            <p class="text-left small"><strong>Name:</strong> @Model.FirstName @Model.LastName</p>
                                            <p class="text-left small"><strong>Country:</strong> @Model.Country</p>
                                            <p class="text-left small"><strong>Prefered E-mail:</strong> @Model.PreferedEmailId</p>
                                            <p class="text-left small"><strong>Prefered Reporting Format:</strong> @Model.PreferedReportFormat</p>
                                            <p class="text-left">
                                                <a id="userPreferences" href="#" class="btn btn-primary btn-block btn-sm">User Preference</a>
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </li>
                            <li class="divider"></li>
                            <li>
                                <div class="navbar-login navbar-login-session">
                                    <div class="row">
                                        <div class="col-lg-12">
                                            <p>
                                                @if (Request.IsAuthenticated)
                                                {
                                                @Html.ActionLink("Log Out", "LogOut", "Account", new { area = "Account" }, null)
                                                }
                                                else
                                                {
                                                @Html.ActionLink("Log In", "Login", "Account", new { area = "Account" }, null)
                                                }
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>

        </div>
    </div>

    <div class="container-fluid body-content">
        @RenderBody()
    </div>
    <div id="dialog" title="User Preferences" style="display:none">
    </div>
    <div id="shadowBox" style="display: none;">
        <img src="../Styles/images/CircularProgressAnimation.gif" alt="Please wait..." />
    </div>
    @RenderSection("viewScripts", required: false)
</body>
</html>

It has a menu option as:

enter image description here

where userid is displayed and opening it displays a partial view as:

enter image description here

Controller for this is:

public class SystemParameterController : Controller
    {
        // GET: SystemParameter/SystemParameter
        [Authorize]
        public ActionResult Index()
        {
            decimal emailIdKey = 2;
            decimal reportFormatKey = 1;

            var user = new Account.ViewModel.UserViewModel();

            using (var userPreferencesDB = new Models.UserPreferencesDbContext())
            {
                var userPreferences = userPreferencesDB.DWP_USER_PREF_T.Where(u => u.USER_ID.Equals(user.UserId, StringComparison.OrdinalIgnoreCase)).ToList();
                var excelFormats = userPreferencesDB.DWP_REP_FORMAT_T.ToList();

                if (userPreferences.Count > 0)
                {
                    user.PreferedEmailId = userPreferences.Where(u => u.PREF_KEY == emailIdKey).SingleOrDefault().PREF_VALUE;
                    var reportFormatId = userPreferences.Where(u => u.PREF_KEY == reportFormatKey).SingleOrDefault().PREF_VALUE;
                    user.PreferedReportFormat = excelFormats.Where(e => e.FORMAT_ID.ToString() == reportFormatId).SingleOrDefault().REP_FORMAT;
                }
                else
                {
                    user.PreferedEmailId = user.UserId.ToLower() + "@yyy.com";
                    user.PreferedReportFormat = excelFormats.Where(e => e.FORMAT_ID.ToString() == "1").SingleOrDefault().REP_FORMAT;
                }
            }

            return View(user);
        }
    }

On click of User Preference, the following opens:

enter image description here

Using controller:

public class CommonController : Controller
    {
        public PartialViewResult UserPreferences()
        {
            decimal emailIdKey = 2;
            decimal reportFormatKey = 1;

            var userPreferenceVM = new ViewModels.UserPreferenceViewModel();

            using (var userPreferencesDB = new Models.UserPreferencesDbContext())
            {
                var userPreferences = userPreferencesDB.XXX_USER_PREF_T.Where(u => u.USER_ID.Equals(userPreferenceVM.UserId, StringComparison.OrdinalIgnoreCase)).ToList();
                var excelFormats = userPreferenceVM.Format = userPreferencesDB.XXX_REP_FORMAT_T.ToList();

                if (userPreferences.Count > 0)
                {
                    userPreferenceVM.PreferedEmailId = userPreferences.Where(u => u.PREF_KEY == emailIdKey).SingleOrDefault().PREF_VALUE;
                    var reportFormatId = userPreferences.Where(u => u.PREF_KEY == reportFormatKey).SingleOrDefault().PREF_VALUE;
                    userPreferenceVM.PreferedReportFormat = excelFormats.Where(e => e.FORMAT_ID.ToString() == reportFormatId).SingleOrDefault().REP_FORMAT;
                }
                else
                {
                    userPreferenceVM.PreferedEmailId = userPreferenceVM.UserId.ToLower() + "@yyy.com";
                    userPreferenceVM.PreferedReportFormat = excelFormats.Where(e => e.FORMAT_ID.ToString() == "1").SingleOrDefault().REP_FORMAT;
                }
            }

            return PartialView(userPreferenceVM);
        }
    }

Questions:

  1. Is UserViewModelBase and UserViewModel the correct approach to go for displaying login, User Preferences and Edit User Preference? I mean, what can I add in UserViewModelBase and UserViewModel?

  2. I am using two different Actions to display User Preferences as partial view and Edit User Preferences as view. Is that ok or something needs to be corrected here?

It's like I somehow am not liking this. It seems like redoing work rather than reusing it.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Implemented a better design by converting the navigation section into a PartialView and converted UserViewModelBase and UserViewModel to User (the Model), and used it with RenderAction in the _Layout page.

Now I feel a bit more satisfied with this implementation.

\$\endgroup\$
1
  • \$\begingroup\$ I would have suggested the same. +1 for working it out on you own. \$\endgroup\$
    – RubberDuck
    Commented May 15, 2016 at 14:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.