Search code examples
c#asp.net-mvcasp.net-mvc-5roleprovider

Value can not be null on Role Provider


I am beginner at MVC C#. Now I am trying to build a custom authentication with role provider, but when it check for user role its getting an error that "Value can not be null". Here is my RoleProvider:

public class MyRoleProvider:RoleProvider
{
    private int _cacheTimeoutInMinute = 20;
    LoginGateway gateway=new LoginGateway();


public override string[] GetRolesForUser(string username)
    {
        if (!HttpContext.Current.User.Identity.IsAuthenticated)
        {
            return null;
        }

        //check cache
        var cacheKey = string.Format("{0}_role", username);
        if (HttpRuntime.Cache[cacheKey] != null)
        {
            return (string[])HttpRuntime.Cache[cacheKey];
        }
        string[] roles

            = gateway.GetUserRole(username).ToArray();
            if (roles.Any())
            {
                HttpRuntime.Cache.Insert(cacheKey, roles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinute), Cache.NoSlidingExpiration);

            }

        return roles;
    }
public override bool IsUserInRole(string username, string roleName)
    {
        var userRoles = GetRolesForUser(username);
            return userRoles.Contains(roleName);   

    }

Its always Getting error on reurn userRoles.Contains(roleName); (value can not be null(userName)) line. I used debug pointer, it shows gateway never been invoked.I,e: string[] roles = gateway.GetUserRole(username).ToArray(); so roles always remain null. Although I am not sure that my GetUserRole method on gateway is correct or not: here is my gateway:

public string[] GetUserRole(string userName)
    {

        string role = null;
        SqlConnection connection = new SqlConnection(connectionString);
        string query = "select r.RoleType from RoleTable r join UserRoleTable ur on ur.RoleId=r.Id join UserTable u on u.UserId=ur.UserId where u.UserName='"+userName+"'";
        SqlCommand command = new SqlCommand(query, connection);
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        {
            role = reader["RoleType"].ToString();

        }
        string[] roles = {role};
        reader.Close();
        connection.Close();
        return roles;
    }  

Is there any problem with my code? and how could I solve this error?


Solution

  • it works if I delete or comment out httpContext and all code for cache...Is there Anything wrong with cache portion code?? @Win

    I won't worry about hitting database, unless you are developing Enterprise Application in which speed is an issue and every query count. Original ASP.Net Membership Provider doesn't use Cache at all.

    Besides, ASP.Net Membership Provider is an very old technology - more than a decade old. If you are implementing for Enterprise Application, you might want to consider using Claim-Based Authentication.

    Here is the cache service if you want to use -

    using System;
    using System.Collections.Generic;
    using System.Runtime.Caching;
    
    public class CacheService 
    {
        protected ObjectCache Cache => MemoryCache.Default;
    
        public T Get<T>(string key)
        {
            return (T) Cache[key];
        }
    
        public void Set(string key, object data, int cacheTime)
        {
            if (data == null)
                return;
    
            var policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
            Cache.Add(new CacheItem(key, data), policy);
        }
    
        public void Remove(string key)
        {
            Cache.Remove(key);
        }
    }