ASP.NET MVC Custom RoleProvider cannot retrieve roles from database for username

て烟熏妆下的殇ゞ 提交于 2020-01-25 20:15:07

问题


i cant seem to find the right solution for the above issue. I keep getting System.NullReferenceException: Object reference not set to an instance of an object.

i followed this guide http://techbrij.com/custom-roleprovider-authorization-asp-net-mvc

The error message is from my custom roleprovider from the GetRolesForUser(string username) at line var user = _VisitorService.GetVisitors().FirstOrDefault(u => u.Username == username);

The VisitorService works in the Controller but not in the RoleProvider.

below are the code please advice as required. Thanks you in advance.

Custom RoleProvider

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TamilLeague.Service;

namespace TamilLeague.WebUI
{
    public class myRoleProvider : System.Web.Security.RoleProvider
    {
        private readonly IVisitorService _VisitorService;
        public myRoleProvider(IVisitorService visitorservice)
        {
            _VisitorService = visitorservice;
        }
        public myRoleProvider() { }

        public override string[] GetRolesForUser(string username)
        {            
            var user = _VisitorService.GetVisitors().FirstOrDefault(u => u.Username == username);
            if (user == null)
                return null;
            else
            {
                string role = user.Role.Title;
                string[] rol = { role };
                return rol;
            }
        }
}

My Controller

[AllowAnonymous]
        [HttpPost]
        public ActionResult Login(UserLoginVM thisUser, string returnUrl)
        {
            var visitor = _VisitorService.GetVisitors().FirstOrDefault(v => v.Username.ToLower() == thisUser.Username.ToLower());

            if (visitor == null)
            {
                ModelState.AddModelError("Username", "Username not found in system. Please register or change the username.");
            }
            if(!visitor.checkPassword(thisUser.HashedPassword))
            {
                ModelState.AddModelError("Username", "Username or password is incorrect.");
            }

            if (visitor.IsFreezed == true)
            {
                ModelState.AddModelError("Username", "Account is freezed. Contact the administrator please.");
            }

            if (visitor.IsConfirmed == false)
            {
                ModelState.AddModelError("Username", "Account is not activated. Contact the administrator please or log into your email to activate your account.");
            }

            if (ModelState.IsValid)
            {
                FormsAuthentication.SetAuthCookie(thisUser.Username, true);
                if (!string.IsNullOrWhiteSpace(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("GiveAccess", new { id = visitor.ID });
                }
            }
            return Content("Testing");
        }

GiveAccess method

public ActionResult GiveAccess(int ID)
        {
            var user = _VisitorService.GetVisitor(ID);
            String[] roles = Roles.Provider.GetRolesForUser(user.Username);

            if(roles.Contains("Administrator"))
            {
                return RedirectToAction("SysUser", "Admin");
            }
            else
            {
                return RedirectToAction("Index", "Member");
            }
            //RedirectToAction("Index", "Member");
        }

Web.config

<system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/User/Login"/>
    </authentication>
    <roleManager enabled="true" defaultProvider="TamilLeagueRoleProvider">
      <providers>
        <clear/>
        <add name="TamilLeagueRoleProvider" type="TamilLeague.WebUI.myRoleProvider" cacheRolesInCookie="false"/>
      </providers>
    </roleManager>
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5"/>
  </system.web>

回答1:


You have a parameterless constructor in myRoleProvider which does not instantiate the service. Are you sure the class isn't entering that constructor? If it is, then you'll get a null reference exception when you try to use the service.




回答2:


You cannot inject dependencies to RoleProvider via constructor. In other words, Provider Model doesn't now allow parameterized constructor.

In order to solve it, you want to use Service Locator Pattern.

For example, in Autofac -

private IVisitorService VisitorService { get; set; }

public MyRoleProvider()
{
   var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
   var cp = cpa.ContainerProvider;

   VisitorService = cp.RequestLifetime.Resolve<IVisitorService>();
}


来源:https://stackoverflow.com/questions/36795803/asp-net-mvc-custom-roleprovider-cannot-retrieve-roles-from-database-for-username

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!