使用带角色的授权时,对象引用未设置为对象的实例

时间:2017-11-01 10:41:38

标签: asp.net-mvc

我正在尝试使用带有角色的Aspnet。使用NRE,我仍然无法弄清楚要实例化的内容。 这是在控制器

[Authorize(Roles = "Admin")]
public ActionResult ForAdmin()
{
    return View();
}

这是我授权的方式

public Programmer GetLoginCredentials(Login credential)
{
    Programmer programmer = null;
    HttpContext.Current.Session["ProgrammerName"] = null;
    HttpContext.Current.Session["Roles"] = null;
    using (
        var cmd = new SqlCommand("Sp_GetLoginCredentials", _dbConnection)
        {
            CommandType = CommandType.StoredProcedure
        })
    {
        try
        {
            cmd.Parameters.AddWithValue("@Username", credential.Username);
            cmd.Parameters.AddWithValue("@Password", credential.Password);
            var da = new SqlDataAdapter(cmd);
            var ds = new DataSet();
            da.Fill(ds);

            if (ds.Tables[0].Rows.Count <= 0) return null;
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                programmer = new Programmer()
                {
                    ProgrammerId = Convert.ToInt32(row["ProgrammerId"]),
                    ProgrammerName = row["ProgrammerName"].ToString(),
                    Username = row["Username"].ToString(),
                    Password = row["Password"].ToString()
                };

                HttpContext.Current.Session["ProgrammerName"] = programmer.ProgrammerName;
            }
            if (programmer != null)
            {
                GetRoles(programmer);
            }

            return programmer;
        }
        catch
        {
            return null;
        }
    }
}

这就是我用角色填充会话的方式

public List<Role> GetRoles(Programmer credential)
{
    var roleList = new List<Role>();
    using (var cmd = new SqlCommand("Sp_GetRoles", _dbConnection) {CommandType = CommandType.StoredProcedure})
    {
        cmd.Parameters.AddWithValue("@Username", credential.Username);
        cmd.Parameters.AddWithValue("@Password", credential.Password);

        var da = new SqlDataAdapter(cmd);
        var ds = new DataSet();
        da.Fill(ds);

        if (ds.Tables[0].Rows.Count > 0)
        {
            roleList.AddRange(from DataRow row in ds.Tables[0].Rows
                select new Role()
                {
                    RoleName = row["RoleName"].ToString()
                });
        }
        HttpContext.Current.Session["Roles"] = roleList;
    }
    return roleList;
}

这是我的角色提供者

public class SiteRole : RoleProvider
{
    public override string[] GetRolesForUser(string username)
    {
        var data = HttpContext.Current.Session["Roles"];
        return data as string[];
    }
}

在我的会话[&#34;角色&#34;]中,我得到了这样的结论 enter image description here

这意味着我能够获得&#34; Admin&#34;角色,但在我的浏览器中,我收到此错误:

[NullReferenceException: Object reference not set to an instance of an object.]
   System.Web.Security.RolePrincipal.IsInRole(String role) +9803940
   System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate) +146
   System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +333
   System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +379
   System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +143
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1680
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
   System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

你能告诉我哪里弄错了吗?谢谢。

1 个答案:

答案 0 :(得分:1)

您无法将HttpContext.Current.Session["Roles"]投放到string[],因为它的类型为List<Role>

请改为尝试:

public override string[] GetRolesForUser(string username)
{
    var data = HttpContext.Current.Session["Roles"] as IEnumerable<Role>;
    return data.Select(d => d.RoleName).ToArray();
}