Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is my C# MVC4 Session Wrapper Service not working?
    text
    copied!<p>I am trying to implement a wrapper for my session (Loose coupling so it is easy to make changes later) but I am having problems, either the storing into the session is failing, or the retrieval but I do not know which.</p> <p>I would greatly appreciate it if you could take a look at my code and tell me if there is anything obviously wrong, or a better way of doing what I am trying to do. I basically want to display different things to different types of user, but when I try to access the user in the ViewContext it is null.</p> <p>Any links to tutorials or examples would be gratefully accepted.</p> <p>Here is my code:</p> <ul> <li>User and WEB_USER_LEVEL have a one to many relationship</li> <li>I have used Entity Framework to create models from my existing database</li> <li>I am currently in the early stages of the project and the User is not coming from the database yet (as the structure will change) so I am creating a new User and populating it before using CurrentUserService.Login(user). i have tried pulling a user out of the data base and logging that user in but it still does not work.</li> </ul> <p><strong>ICurrentUserService.cs</strong> (in Infrastructure folder)</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MyProject.Infrastructure { public interface ICurrentUserService { User CurrentUser { get; } void SetCurrentUser(WEB_USER user); void SetAdminStatus(bool type); bool GetAdminStatus { get; } void SetManagerStatus(bool type); bool GetManagerStatus { get; } void Login(User user); void Logout(); int? TryGetCurrentUserId(); } } </code></pre> <p><strong>CurrentUserService.cs</strong> (in Infrastructure folder)</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Web; using MyProject.Controllers; using MyProject.Infrastructure.Filters; namespace MyProject.Infrastructure { public class CurrentUserService : ICurrentUserService { public const string CurrentUserKey = "CurrentUser"; public const string CurrentUserIdKey = "CurrentUserId"; public const string IsAdminKey = "IsAdmin"; public const string IsManagerKey = "IsManager"; private readonly IDb _db; public CurrentUserService() : this(new Db()) { } public CurrentUserService(IDb db) { _db = db; } public User CurrentUser { get { return (User)HttpContext.Current.Items[CurrentUserKey]; } } public void SetCurrentUser(User user) { HttpContext.Current.Items[CurrentUserKey] = user; } public void SetAdminStatus(bool type) { HttpContext.Current.Session[IsAdminKey] = type; } public bool GetAdminStatus { get { return (bool)HttpContext.Current.Session[IsAdminKey]; } } public void SetManagerStatus(bool type) { HttpContext.Current.Session[IsManagerKey] = type; } public bool GetManagerStatus { get { return (bool)HttpContext.Current.Session[IsManagerKey]; } } public void Login(User user) { HttpContext.Current.Session[CurrentUserIdKey] = user.ID; HttpContext.Current.Items[CurrentUserKey] = user; SetManagerStatus(user.WEB_USER_LEVEL.IsManager); SetAdminStatus(user.WEB_USER_LEVEL.RefID == 1 ? true : false); } public void Logout() { HttpContext.Current.Items[CurrentUserKey] = null; HttpContext.Current.Session[CurrentUserIdKey] = null; SetManagerStatus(false); SetAdminStatus(false); } public int? TryGetCurrentUserId() { return HttpContext.Current.Session[CurrentUserIdKey] as int?; } } } </code></pre> <p><strong>Extensions.cs</strong> (in Infrastructure folder)</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyProject.Infrastructure { public static class Extensions { public static User CurrentUser(this ViewContext view) { return (User)view.HttpContext.Items[CurrentUserService.CurrentUserKey]; } } } </code></pre> <p><strong>HomeController.cs</strong></p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MyProject.Infrastructure; using MyProject.Infrastructure.Filters; using MyProject.ViewModels; using MyProject.Models; using System.Data.Objects; namespace MyProject.Controllers { public class HomeController : BaseController { readonly IDb _db; readonly ICurrentUserService _currentUserService; readonly IErrorReporter _errorReporter; public HomeController() : this(new Db(), new CurrentUserService(), new ErrorReporter()) { } public HomeController(IDb db, ICurrentUserService currentUserService, IErrorReporter errorReporter) { _db = db; _currentUserService = currentUserService; _errorReporter = errorReporter; } public ActionResult Index() { return View(); } [HttpPost] public ActionResult Login(FormCollection form) { // Create new user and populate _currentUserService.Login(user); return RedirectToAction("Home"); } public ActionResult Home() { return View(); } } } </code></pre> <p><strong>Trying to access in ViewContext in _Layout.cshtml when the Home view is loaded</strong></p> <pre><code>@using MyProject.Infrastructure @if (ViewContext.CurrentUser() != null &amp;&amp; ViewContext.CurrentUser().WEB_USER_LEVEL.IsManager) { @RenderPage("~/Views/Shared/_Menu.cshtml") } </code></pre> <p>But ViewContext.CurrentUser() is always null.</p> <p>Thank you for your help!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload