Reputation:
I have the following model class inside my asp.net mvc web application:
public class SecurityRoleGroupAssign
{
public IEnumerable<TechnologyType> TechnologyType {get; set;}
public IEnumerable<PermisionLevel> PermisionLevel {get; set;}
public SecurityRole SecurityRole { get; set; }
public Nullable<int> rackPermisionLevel { get; set; }
public Nullable<int> serverPermisionLevel { get; set; }
public Nullable<int> routerPermisionLevel { get; set; }
public Nullable<int> virtualMachinePermisionLevel { get; set; }
public Nullable<int> switchPermisionLevel { get; set; }
}
But when I tried to populate this class I got a Null Exception:-
public SecurityRoleGroupAssign populateSecurityRolePermisionLevelAssign(int RoleID)
{
SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
{
SecurityRole = FindAllRole(RoleID),
PermisionLevel = tms.PermisionLevels.ToList(),
TechnologyType = tms.TechnologyTypes.ToList(),
serverPermisionLevel = tms.SecurityroleTypePermisions
.Where(a=>a.SecurityRoleID == RoleID)
.Where(a2=>a2.TechnologyType.Name.ToLower() == "server")
.SingleOrDefault().PermisionLevelID,
rackPermisionLevel = tms.SecurityroleTypePermisions
.Where(a => a.SecurityRoleID == RoleID)
.Where(a2 => a2.TechnologyType.Name.ToLower() == "rack")
.SingleOrDefault().PermisionLevelID,
virtualMachinePermisionLevel = tms.SecurityroleTypePermisions
.Where(a=>a.SecurityRoleID == RoleID)
.Where(a2=>a2.TechnologyType.Name.ToLower() == "virtual machine")
.SingleOrDefault().PermisionLevelID,
routerPermisionLevel = tms.SecurityroleTypePermisions
.Where(a=>a.SecurityRoleID == RoleID)
.Where(a2=>a2.TechnologyType.Name.ToLower() == "router")
.SingleOrDefault().PermisionLevelID,
switchPermisionLevel = tms.SecurityroleTypePermisions
.Where(a => a.SecurityRoleID == RoleID)
.Where(a2 => a2.TechnologyType.Name.ToLower() == "switch")
.SingleOrDefault().PermisionLevelID
};
return c;
}
Upvotes: 0
Views: 112
Reputation: 148980
The problem is that SingleOrDefault
will return null
(for reference types) if no items exist. So any time you call .SingleOrDefault().PermisionLevelID
you're in danger of a null reference exception. you can fix this by placing the .SingleOrDefault()
after the selected the result—e.g.(... select p.PermissionLevelID).SingleOrDefault()
.
Try this:
var permissions = tms.SecurityroleTypePermisions.Where(a => a.SecurityRoleID == RoleID);
SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
{
SecurityRole = FindAllRole(RoleID),
PermisionLevel = tms.PermisionLevels.ToList(),
TechnologyType = tms.TechnologyTypes.ToList(),
serverPermisionLevel =
(from p in permissions
where p.TechnologyType.Name.ToLower() == "server"
select p.PermisionLevelID)
.SingleOrDefault(),
rackPermisionLevel =
(from p in permissions
where p.TechnologyType.Name.ToLower() == "rack"
select p.PermisionLevelID)
.SingleOrDefault(),
virtualMachinePermisionLevel =
(from p in permissions
where p.TechnologyType.Name.ToLower() == "virtual"
select p.PermisionLevelID)
.SingleOrDefault(),
routerPermisionLevel =
(from p in permissions
where p.TechnologyType.Name.ToLower() == "router")
select p.PermisionLevelID
.SingleOrDefault(),
switchPermisionLevel =
(from p in permissions
where p.TechnologyType.Name.ToLower() == "switch"
select p.PermisionLevelID
.SingleOrDefault()
};
Or better yet:
var permissions = tms.SecurityroleTypePermisions
.Where(a => a.SecurityRoleID == RoleID)
.ToLookup(a => a.TechnologyType.Name.ToLower(),
a => a.PermisionLevelID);
SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
{
SecurityRole = FindAllRole(RoleID),
PermisionLevel = tms.PermisionLevels.ToList(),
TechnologyType = tms.TechnologyTypes.ToList(),
serverPermisionLevel = permissions["server"].SingleOrDefault(),
rackPermisionLevel = permissions["rack"].SingleOrDefault(),
virtualMachinePermisionLevel = permissions["virtual"].SingleOrDefault(),
routerPermisionLevel = permissions["router"].SingleOrDefault(),
switchPermisionLevel = permissions["switch"].SingleOrDefault()
};
Upvotes: 2
Reputation: 6638
.SingleOrDefault():
Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.
serverPermisionLevel = tms.SecurityroleTypePermisions.Where(a=>a.SecurityRoleID == RoleID).Where(a2=>a2.TechnologyType.Name.ToLower() == "server").SingleOrDefault().PermisionLevelID;
The problem here is that the .SingleOrDefault();
call returned the default "null" value. The error is thrown when you try to call the PermissionLevelID
on that null reference.
What you could change it into:
serverPermisionLevel = tms.SecurityroleTypePermisions
.Where(a=>a.SecurityRoleID == RoleID)
.Where(a2=>a2.TechnologyType.Name.ToLower() == "server")
.Select(r => r.PermissionLevelID).SingleOrDefault();
this way, your nullable ints will be filled when .SingleOrDefault actually returns null, or with the actual value of the PermissionLevelId
if there is one.
Upvotes: 1