My null checker fails, whats wrong here ?
I am trying to check if the user claims does exist for the variable sID which is just the staffID of the postback model
So I added a try catch statement to stop it crashing
var sID = ViewModel_CreateNewAgent.Tbl_Brands_Staff.BranchStaffID.ToString();
var staffIDExists = _context.AspNetUserClaims.Where(c => c.ClaimValue == sID).FirstOrDefaultAsync();
/// VALIDATE STAFF ID
var claimsExists = await _userManager.GetClaimsAsync(user);
var doesStaffIDExist ="";
try
{
doesStaffIDExist = staffIDExists.Result.ClaimValue ?? doesStaffIDExist;
//doesStaffIDExist = staffIDExists.Result.ClaimValue != null ? staffIDExists.Result.ClaimValue : doesStaffIDExist ;
}catch(Exception err) { }
Don't use try-catch for normal workflow, try to fix the real problem.
Here staffIDExists and/or staffIDExists.Result and/or ClaimValue could be null. Use the null conditional operator ? to make your code safe and readable:
var staffIDExists = _context.AspNetUserClaims.Where(c => c.ClaimValue == sID).FirstOrDefaultAsync();
string doesStaffIDExist = claimsExists?.Result?.ClaimValue ?? "";
However, does that code make sense? The Where checks for c.ClaimValue == sID, so doesStaffIDExist is always either ""(if there is no such claim) or sid.
I am trying to check if the user claims does exist for the variable
sID
Well, then this code would be easier:
return _context.AspNetUserClaims.Any(c => c.ClaimValue == sID);
Related
I keep getting null exceptions when iterating over my foreach loop and I think it is because they
way I am trying to check, iterate and skip over the nulll values is incorrects. Basically when it doesnt fine "New" it throws an exception.
public async Task<IActionResult> NewRequisitionsEntryList()
{
//var requisitions = _repositoryWrapper.Requisition.GetAllNewRequisitions();
//UserInformation UserInformation = await _userManager.GetUserAsync(User);
var newReqList = _context.Requisition.OrderByDescending(r => r.Status.Equals("New")).ToList();
foreach (var reqList in newReqList ?? Enumerable.Empty<Requisition>())
{
UserInformation identityUser = await _userManager.GetUserAsync(User);
var departmentId = _context.Department.Where(x => x.DepartmentName == identityUser.Department).FirstOrDefault();
var userDepartmentId = departmentId.DepartmentId;
if (departmentId.DepartmentId == reqList.DepartmentId)
{
if (_context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault().ProcessStepName == "New")
{
CurrentStepName = _context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault().ProcessStepName;
requistionsNew.Add(new NewRequistionModel()
{
RequistionNo = reqList.RequisitionNo,
RequisitionTitle = reqList.RequisitionTitle,
DateCreated = reqList.DateCreated,
ProcessStepName = CurrentStepName,
RequestedBy = reqList.QueriesEmail,
});
}
}
}
await Task.Run(() =>
{
Console.WriteLine("workspace");
});
ViewData["requistionsNew"] = requistionsNew;
return View(newReqList);
}
Its breaking on the second if clause on the line that has the where statement
So you mean the second if clause makes error. We can analysis that firstly you use the _context before the if clause without any error, so it will not be null for the context. Then we can see you use FirstOrDefault which can get the model data, here can receive null value. Null value is acceptbale but if you want to get the property of the null object, it will throw exception.
You can simply use ? to avoid null exception:
_context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault()?.ProcessStepName;
Or change the if clause:
var model = _context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault();
if (model !=null && model .ProcessStepName == "New")
Suggestions:
Actually debugging code is the most efficient way to find out the error and know how to modify. You need set the breakpoint to your action and quick watch the line which makes error, step by step to find where is the real error. For example, right-click and choose quick watch, then in the search bar type the _context.ProcessStepLog to check the value or Results View. If it contains value, then type Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault() to check it. Step by Step.....
Refer to:
Use breakpoints in the Visual Studio debugger
Watch variables with Watch windows and QuickWatch
I'm a greenhorn when it comes to LINQ. I've read some null exceptions and most of them pointed out
... in sth.AsEnumerable() ...
as root of the problem.
I've run into:
The function evaluation requires all threads to run.
I tried to retrieve
fieldname
from TrashPlaces (it has 2 fields only - id and name) by string Id I get from UserPlace record (UserPlace has 2 keys - 1 is userId that can be retrieved from AspNetUsers and the other is TrashPlace id). I've run into null problem on this LINQ code:
public ActionResult JsonResult()
{
var users = db.AspNetUsers;
//this was added, so I could root out mismatch in the queryId
var nameformyuser = User.Identity.Name;
//the null starts here and no-shock it goes further (meaning query is null and
//can't do nothing later)
var queryId = from user in users.AsEnumerable()
where user.Email == User.Identity.Name
select user.Id;
var placerecord = db.UserPlace;
var userplace = from uplace in placerecord.AsEnumerable()
where uplace.usersId == queryId.ToString()
select uplace.placesId;
var places = db.TrashPlaces;
var field = from blah in places.AsEnumerable()
where blah.Id == userplace.ToString()
select blah.nameOfThePlace;
TempData["username"] = User.Identity.Name;
TempData["fieldname"] = field.ToString();
TempData["datename"] = DateTime.Now;
List<TrashViewModel> json = (List<TrashViewModel>)TempData["jsonList"];
return View(json);
}
Would be grateful for help and or/advice what's the best approach towards cascading LINQ.
Thanks!
You could do all in one (don't enumerate to early by the way, this is not good for performance).
Not sure why you use ToString() you shouldn't have to if your ids are of the same type.
var query = from u in db.AspNetUsers
join up in db.db.UserPlace on u.Id equals up.usersId
join tp in db.TrashPlaces on up.placesId equals tp.Id
where u.Email == User.Identity.Name
select tp.nameOfThePlace;//or more data if you need to.
var result = query.FirstOrDefault(); //or query.AsEnumerable()
Then you can do a null check
if (result == null)
In your case, for TempData, you may just do
TempData["fieldname"] = result == null ? string.Empty : result;
or
TempData["fieldname"] = result;
But then you'll have to check if TempData["fieldname"] is not null before using it.
...
The code below works for cases where there are already records in the Credit card table for the user who is logged in; however, when a user doesn't have an entry in the credit card table, the query finds zero records as expected. The problem is, the statement maxccid = query.Maxccid(); returns a Null and an InvalidOpeation exception is thrown. I can't make the ccid field in the database nullable as it is part of a primary key. I need a way to detect if this query will return a null before I run it, or a way to trap it (preferably without a try catch, as this condition will happen for every new customer (Best practices for Try/Catch state this is not a proper use of Try/Catch). Just a note to add that I'm using Entity Framework.
UPDATE 4/9/14: I modified the query to fix the problem I reported in comments to Usesr FailedProgramming and Mike. I still have the null problem though.
// Create CreditCard - Write to DB
public ActionResult Create(CreditCard model)
{
EntitiesContext context = new EntitiesContext();
int uid = (int)WebSecurity.GetUserId(User.Identity.Name); // Currently logged-in user
short? maxccid = 0; //this will be the max ccid for this user
var query = from c in context.CreditCards
where c != null && c.UserId == uid select c.CCID;
maxccid = query.Max();
if(query.Any())
maxccid = query.Max();
First of all use using for the databse objects.
Secondly, use null-coalescing operator. for handling the null Check here http://msdn.microsoft.com/en-us/library/ms173224.aspx
public ActionResult Create(CreditCard model)
{
using(EntitiesContext context = new EntitiesContext()) // using keyword will dispose the object properly.
{
int uid = (int)WebSecurity.GetUserId(User.Identity.Name); // Currently logged-in user
short? maxccid = 0; //this will be the max ccid for this user
var query = from c in context.CreditCards
where c.UserId == uid && c.CCID == (context.CreditCards.Max(c1 => c1.CCID) ) select c.CCID ;
maxccid = query.Max() ?? 0; //use null-coalescing operator.
}
}
You can optimize this code more as per your needs.
Hope, It may help you at some point. Have a nice day.
I have a scenario that I am getting the result properly .But i have to search it in that result.Here is my code.
if(productSearch.Keyword !=null || productSearch.Code!=null)
{
var key = productSearch.Keyword;
var cod = productSearch.Code;
if (productSearch.Code != null)
{
var Selected_Result = result.Results.Where(s => s.Code.ToLower().Contains(cod.ToLower())).ToList();
result.Results = Selected_Result;
}
else
{
var Selected_Result = result.Results.Where(s => s.Keyword.ToLower().Contains(key.ToLower())).ToList();
result.Results = Selected_Result;
}
}
But it gives following exception :
Object reference not set to an instance of an object on result.Results.Where(s => s.Code.ToLower().Contains(cod.ToLower())).ToList();
I know s => s.Code.ToLower() is coming NULL, but i dont know why, result has records.
Thanks in advance.
If it's null in the query then chances are it's null in the DB. To be on the safe side you can use the null coalescing operator to make sure you have at least something to call ToLower on e.g.
result.Results.Where(s => (s.Code ?? "").ToLower().Contains(cod.ToLower()))
.ToList();
Okay so I am trying to compare a login textbox password and username with a custom validator using linq to get information from the database it always returns false though on the validator could someone please tell me where my code below is going wrong. This will be very much appreciated... thank you in advanced...
protected void LoginValidate(object source, ServerValidateEventArgs args)
{
TiamoDataContext context = new TiamoDataContext();
var UsernameCheck = from User in context.Users
where User.Username == TextBoxLoginUsername.Text && User.Password == TextBoxLogInPassword.Text
select User.Username;
var PasswordCheck = from User in context.Users
where User.Username == TextBoxLoginUsername.Text && User.Password == TextBoxLogInPassword.Text
select User.Password;
String test1 = PasswordCheck.ToString();
String test2 = UsernameCheck.ToString();
if (test1 == TextBoxLogInPassword.Text && test2 == TextBoxLoginUsername.Text)
{
args.IsValid = true;
Session["Username"] = TextBoxLoginUsername;
Response.Redirect("UserProfile.aspx");
}
else
{
args.IsValid = false;
}
}
I dont know where I am going wrong I know its most probably some sort of silly mistake and me being inexperienced at this...
UsernameCheck and PasswordCheck are going to be collections, not single values. Therefore the ToString() method isn't returning what you think it should.
It's probably returning "IEnumerable<string>"
You need to force your LINQ queries to return a single result rather than a collection.
var user = context.Users.Where(u => u.Username==TextBoxLoginUsername.Text &&
u.Password == TextBoxLogInPassword.Text)
.FirstOrDefault();
string userNameCheck = user.Username;
string passwordCheck = user.Password;
As a side note, this is why using the var keyword is a little dangerous if you're not absolutely positive of the return type of the statement you're writing. If you would change your vars to strings, the compiler would have caught the type mismatch at compile time.