0

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>
Aatish Kumar
  • 149
  • 2
  • 15

2 Answers2

0

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.

John Mc
  • 2,862
  • 1
  • 22
  • 37
  • Thats what i thought.. but when i remove the parameterless constructor i get the error "No parameterless constructor defined for this object." :( – Aatish Kumar Apr 22 '16 at 14:07
  • See Wins answer below. You need to instantiate the service in the parameterless constructor – John Mc Apr 22 '16 at 14:08
0

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>();
}
Win
  • 61,100
  • 13
  • 102
  • 181
  • hi i implemented autofac now i get IContainerProviderAccessor could not be found. 'private IVisitorService VisitorService { get; set; } public myRoleProvider(IVisitorService visitorservice) { _VisitorService = visitorservice; } public myRoleProvider() { var cpa = (IContainerProviderAccessor) HttpContext.Current.ApplicationInstance; }' – Aatish Kumar Apr 22 '16 at 16:10
  • Could you try `var visitorService = DependencyResolver.Current.GetService();`? – Win Apr 22 '16 at 16:25
  • when i enter the namespace Autofac.Integration.Web; it says that Web does not exist in the namespace Autofac.Integration – Aatish Kumar Apr 22 '16 at 16:26
  • You want to download [Autofac.Mvc5 from NuGet](https://www.nuget.org/packages/Autofac.Mvc5/). If you want more information, look at [here](http://docs.autofac.org/en/latest/integration/webforms.html#implement-icontainerprovideraccessor-in-global-asax). – Win Apr 22 '16 at 16:33
  • Autofac.MVC5 is already installed. Now i get `None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'TamilLeague.WebUI.Controllers.UserController` .heres a part of my bootstrapper which is run by global ` builder.RegisterAssemblyTypes(typeof(VisitorService).Assembly) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces().InstancePerRequest();` – Aatish Kumar Apr 22 '16 at 16:46
  • You question becomes sidetracked, and becomes autofac issue. Please search in Stack Overflow regarding [Autofac](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=site%3Astackoverflow.com+autofac+None+of+the+constructors+found). – Win Apr 22 '16 at 18:21