为什么我的C#MVC4会话包装服务不起作用?

时间:2013-05-22 16:24:06

标签: c# asp.net-mvc session wrapper

我正在尝试为我的会话实现一个包装器(松散耦合因此以后很容易进行更改)但是我遇到了问题,要么存储到会话中失败,要么检索但我不知道哪个。

如果您能查看我的代码并告诉我是否有任何明显的错误,或者更好的方式来做我想做的事情,我将不胜感激。我基本上想要向不同类型的用户显示不同的东西,但是当我尝试在ViewContext中访问用户时它是null。

感谢接受教程或示例的任何链接。

这是我的代码:

  • 用户和WEB_USER_LEVEL具有一对多的关系
  • 我使用Entity Framework从现有数据库创建模型
  • 我目前处于项目的早期阶段,用户尚未从数据库进入(因为结构将发生变化)所以我在创建新用户并在使用CurrentUserService.Login(用户)之前填充它。我已经尝试将用户从数据库中拉出来并记录该用户,但它仍然不起作用。

ICurrentUserService.cs (在基础架构文件夹中)

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

CurrentUserService.cs (在基础架构文件夹中)

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

Extensions.cs (在基础架构文件夹中)

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

HomeController.cs

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

加载主页视图时,尝试在_Layout.cshtml中的ViewContext中访问

@using MyProject.Infrastructure

@if (ViewContext.CurrentUser() != null && ViewContext.CurrentUser().WEB_USER_LEVEL.IsManager) 
{
    @RenderPage("~/Views/Shared/_Menu.cshtml")
}

但ViewContext.CurrentUser()始终为null。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我建议您不要在ViewContext上创建扩展方法,而是为视图创建一个ViewModel,并将视图所需的数据传递给它。请记住,视图所需的任何外部数据都应通过ViewModel提供给它。这使得一对一的关系很容易理解。