0

セッションにラッパーを実装しようとしています (疎結合なので、後で簡単に変更できます) が、セッションへの保存に失敗するか、取得に問題がありますが、どちらかわかりません。

私のコードを見て、明らかに間違っている点があるかどうか、または私がやろうとしていることを行うためのより良い方法があるかどうかを教えていただければ幸いです。基本的には、さまざまなタイプのユーザーにさまざまなものを表示したいのですが、ViewContext でユーザーにアクセスしようとすると null になります。

チュートリアルや例へのリンクは、ありがたく受け入れられます。

これが私のコードです:

  • ユーザーと WEB_USER_LEVEL には 1 対多の関係があります
  • Entity Framework を使用して、既存のデータベースからモデルを作成しました
  • 私は現在プロジェクトの初期段階にあり、ユーザーはまだデータベースから来ていないので (構造が変更されるため)、新しいユーザーを作成して、CurrentUserService.Login(user) を使用する前にデータを入力しています。ユーザーをデータベースから引き出して、そのユーザーをログインさせようとしましたが、それでもうまくいきません。

ICurrentUserService.cs (Infrastructure フォルダー内)

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 (Infrastructure フォルダー内)

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 (Infrastructure フォルダー内)

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

Home ビューが読み込まれているときに _Layout.cshtml の ViewContext でアクセスしようとしています

@using MyProject.Infrastructure

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

ただし、ViewContext.CurrentUser() は常に null です。

ご協力ありがとうございました!

4

1 に答える 1

0

ViewContext の上に拡張メソッドを作成する代わりに、ビューの ViewModel を作成し、ビューに必要なデータを渡すことをお勧めします。ビューが必要とする外部データは、ViewModel を介してフィードする必要があることに注意してください。これにより、フォローしやすいクリーンな 1 対 1 の関係が確立されます。

于 2013-05-22T22:13:00.667 に答える