问题
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