3

MVCデザインを改善しようとしています。すべてのページで、Cookieを読み取り、それに基づいてさまざまな値(認証関連ではない)でUserオブジェクトを設定する必要があります。

私が現在行っているのは、すべてのコントローラーがBaseControllerから継承し、BaseControllerでUserオブジェクトを使用することです。

public class BaseController : Controller
{
    protected User thisUser { get; private set; }

    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
         // ... read cookie, set values of thisUser
    }
}

これは悪いデザインですか?User一度だけ定義するのが好きですが、ASP.NET MVCのベースコントローラークラスの適切な候補は何ですか?に関する回答を読みました。、そしてもっと良い方法があれば、やり直してもかまいません。しかし、私は絶対に各コントローラーで繰り返すことを意味するアプローチを望んでいませんUser thisUser = new User();、そして私はベースコントローラーなしでそのように実装する方法を見ることができません。このようにActionFiltersを使用する良い例を見つけることができません。

私はまだDIフレームワークを使用していませんが、問題が解決すれば使用します。それが各コントローラーまたはアクションにパラメーターとして渡すことを意味する場合、それUserがDRYの賭け金の改善であるかどうかはわかりません。

私が見逃しているものがあると確信しています。どんな助けもいただければ幸いです...

4

1 に答える 1

3

インターフェイスを作成する

interface ICustomPrincipal : IPrincipal
{
    int UserId { get; set; }
    string FirstName { get; set; }
    string LastName { get; set; }
}

カスタムプリンシパル

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }
    public bool IsInRole(string role) { return false; }

    public CustomPrincipal(string email)
    {
        this.Identity = new GenericIdentity(email);
    }

    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

CustomPrincipalSerializeModel - カスタム情報を FormsAuthenticationTicket オブジェクトの userdata フィールドにシリアル化するため。

public class CustomPrincipalSerializeModel
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

LogIn メソッド - カスタム情報を使用して Cookie を設定する

if (Membership.ValidateUser(viewModel.Email, viewModel.Password))
{
    var user = userRepository.Users.Where(u => u.Email == viewModel.Email).First();

    CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
    serializeModel.UserId = user.Id;
    serializeModel.FirstName = user.FirstName;
    serializeModel.LastName = user.LastName;

    JavaScriptSerializer serializer = new JavaScriptSerializer();

    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
             1,
             viewModel.Email,
             DateTime.Now,
             DateTime.Now.AddMinutes(15),
             false,
             userData);

    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);

    return RedirectToAction("Index", "Home");
}

Global.asax.cs - Cookie を読み取り、HttpContext.User オブジェクトを置き換えます。これは、PostAuthenticateRequest をオーバーライドすることによって行われます。

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);

        CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
        newUser.UserId = serializeModel.UserId;
        newUser.FirstName = serializeModel.FirstName;
        newUser.LastName = serializeModel.LastName;

        HttpContext.Current.User = newUser;
    }
}

Razor ビューでのアクセス

@((User as CustomPrincipal).Id)
@((User as CustomPrincipal).FirstName)
@((User as CustomPrincipal).LastName)

完全な回答については、このトピックを使用してください: ASP.NET MVC - カスタム IIdentity または IPrincipal の設定

于 2013-02-04T12:37:56.327 に答える