如何在ASP.NET MVC中更轻松地访问我的自定义IPrincipal?

Vik*_*tor 9 c# asp.net-mvc casting iprincipal razor

我编写了一个自定义主体对象,其中包含一些额外的字段(除了用户名之外的电子邮件和用户ID).

为了访问这些属性,我必须将Context.User对象转换为我的自定义主体.

@Html.GetGravitarImage((User as CustomPrincipal).Email)
Run Code Online (Sandbox Code Playgroud)

通过我的global.ascx中的Application_AuthenticateRequest创建/反序列化此自定义主体.您可以在此处查看此问题以获取更多信息.

private void Application_AuthenticateRequest(Object source, EventArgs e)
{
    var application = (HttpApplication)source;
    var context = application.Context;

    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = context.Request.Cookies[cookieName];
    if (authCookie == null)
        return;

    var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    context.User = CustomPrincipal.CreatePrincipalFromCookieData(authTicket.UserData);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果用户未经过身份验证,那么我对CustomPrincipal的强制转换将失败(因为它不会在上面的方法中注入),并且(User as CustomPrincipal)的结果将返回null,从而给我一个空引用我上面的方法尝试获取电子邮件时的异常.

什么是这个问题的干净解决方案?我想让访问我的自定义主体变得容易,并且必须执行以下操作似乎很麻烦:

@Html.GetGravitarIcon((User is CustomPrincipal) ? (User as CustomPrincipal).Email : "Default Email")
Run Code Online (Sandbox Code Playgroud)

这是处理这种情况的唯一方法吗?

Joh*_*rer 2

您可以创建一个基类并使用“new”关键字覆盖“User”属性,或者创建一个扩展方法,如下所示:

public static class ControllerExtensions
{
    public static CustomPrincipal CustomPrincipal(this Controller controller)
    {
        if(controller.User is CustomPrincipal)
        {
            return controller.User as CustomPrincipal;
        }
        return null; // maybe return an empty object instead to get around null reference...
    }
}
Run Code Online (Sandbox Code Playgroud)