I have a linq WHERE statment where I'm wanting to use a cookie value string (aspxauth) to match up to a string in a table, however I'm getting an "Object reference not set to an instance of an object." error.
The code is:
HttpCookie authCookie = Request.Cookies[".aspxauth"];
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
string cookieUser = authCookie.Value;
if (User.Identity.IsAuthenticated)
{
if (Request.Cookies[".aspxauth"] != null)
{
var loginStatus = new UsersDataContext();
var loginstatus = from s in loginStatus.sessions
where s.aspxauth == cookieUser
select s;
var x = loginstatus.FirstOrDefault().UserId.ToString();
If I remove the where statement I dont get the error.
Any ideas on where I'm going wrong here??
Any help is appreciated, thanks.
My guess would be that none of the elements in the loginStatus.sessions sequence match the condition of the where clause, causing loginstatus.FirstOrDefault() to return null, so when you try to access .UserId, you get the null reference exception.
You should check for null yourself and handle the case:
var firstLoginStatusMatch = loginstatus.FirstOrDefault();
if (firstLoginStatusMatch == null)
{
// Handle no match
}
var userId = firstLoginStatusMatch.UserId.ToString()
I would also suggest naming your variables to be more descriptive. You have two variables of the same name but with different casing, making the code very hard to scan.
It's telling you that at least one of the sessions items is null, or that your where statement filtered the collection down to zero items.
You will get this error if no elements match, that is where where s.aspxauth == cookieUser is false for every element in loginStatus.sessions. FirstOrDefault() will return the default value for an object, which is null.
Related
I already use linq but search id only and it worked perfectly
var obj = (from VAR in db.infos
where VAR.id == 22
select new
{
title = VAR.title,
}).SingleOrDefault();
Label2.Text = obj.title.Trim();
If I try to search by location get a error
var obj = (from VAR in db.infos
where VAR.location.Trim() == "Lim"
select new
{
title = VAR.title.Trim(),
}).SingleOrDefault();
SearchJob.Items.Add(obj.title.Trim());
Label2.Text = obj.title;
Have a error in label2 line
Object reference not set to an instance of an object.
How do I fix it?
if (obj.title != null)
{
SearchJob.Items.Add(obj.title.Trim());
Label2.Text = obj.title;
}
Object reference not set to an instance of an object.
SOLUTION
Change SingleOrDefault() to FirstOrDefault()
You're doing some nasty stuff there, VERY bad habits. For instance this:
var obj = (from VAR in db.infos
where VAR.location.Trim() == "Lim"
select new
{
title = VAR.title.Trim(),
}).SingleOrDefault();
SearchJob.Items.Add(obj.title.Trim());
Label2.Text = obj.title;
Is a nonsense! Let me tell you why:
Always check the data BEFORE you insert it into your database, not AFTER. You're creating a lot of unnecessary overhead this way, which could be avoided altogether. Trim the data before, never after.
Next thing - you need only a single string value, yet you create an anonymous object. WHY? Do this instead:
string title = (from o in db.infos
where o.location == "Lim"
select o.title).SingleOrDefault();
Use SingleOrDefault if you expect a single result or none. However, if you expect multiple results and want only the first, use FirstOrDefault.
As you can see, I'm using o instead of VAR. It's true it doesn't really matter that much, BUT, it's never a good idea to use a word that's very similar to one of the reserved words (var).
If you get an exception Object reference not set to an instance of an object., it means that your query returned a null and you're trying to access a non-existing object. If your query may return null at some point, always check for null when accessing a member!
EDIT
if ( obj.title != null )
is bad too, because you need to check for null the object itself!
if (obj != null)
if you really want to use your bad approach.
I think the error occurred in the query
In first query you have source db.infos
In second you have source db.jobinfos
The source is changed
If we assign empty text to Label it will show, It looks like that obj.title does not exist or you are getting error in your query due to wrong source.
The obj is not returning title field. Check obj by debugging.
Try to skip exception :)
public static class LINQException {
public static void TryExample() {
var LsWithEx = from p in Enumerable.Range(0, 10) select int.Parse("dsfksdj");
var LsSkipEx = (from p in Enumerable.Range(0, 10) select int.Parse("dsfksdj")).SkipExceptions();
}
public static IEnumerable<T> SkipExceptions<T>(this IEnumerable<T> values)
{
using (var enumerator = values.GetEnumerator())
{
bool next = true;
while (next)
{
try
{ next = enumerator.MoveNext();}
catch
{ continue;}
if (next) yield return enumerator.Current;
}
}
}
}
var obj = (from VAR in db.infos
where VAR.location.Trim() == "Lim"
select new
{
title = VAR.title.Trim(),
}).SkipExce.SingleOrDefault();
Example
Have a look at the following code:
private void DeDuplicateOrganisations()
{
var profileOrgs = _organisations.Where(o => o.ExistsInProfile).ToList();
var kvkOrgs = _organisations.Where(o => !o.ExistsInProfile).ToList();
profileOrgs.ForEach(o =>
{
var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
if (duplicate != null)
{
o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
o.ExistsInBoth = true;
kvkOrgs.Remove(duplicate);
}
});
_organisations = profileOrgs.Concat(kvkOrgs).OrderBy(o => o.Title).ToList();
}
In this example the property CompanyInfoOrganisation (simply a get; set; property) is copied when an organisation is considered a duplicate. This all works as expected, duplicates are nicely deduplicated.
Also this is true inside this message:
_organisations.First(o => o.ExistsInBoth).CompanyInfoOrganisation != null;
Problem
Now I bind the _organisations list to a listbox
lbxCompanies.DataSource = null;
lbxCompanies.DataSource = _organisations;
lbxCompanies.DisplayMember = "Title";
lbxCompanies.SelectedIndex = -1;
and later on get the selected value:
var org = lbxCompanies.SelectedValue as Organisation;
gbxCompanyInfo.Visible = org != null;
if (gbxCompanyInfo.Visible)
if (org.CompanyInfoOrganisation != null)
// NEVER GETS HERE (but gbxComanpyInfo is visible)
If I try to read the CompanyInfoOrganisation property I always get null while I know the property was set.
Question
What is happening here? How come the property reference is destroyed? How can I prevent this from happening?
The reference you're using only has immediate scope and as soon as the query ends it exits scope and your reference disappears. So when you bind later, the reference is exactly right -- null.
profileOrgs.ForEach(o =>
{
// Right here -- var duplicate has scope ONLY within your query.
// As soon as the query is executed it leaves scope and the reference
// pointer will be null
var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
if (duplicate != null)
{
o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
o.ExistsInBoth = true;
kvkOrgs.Remove(duplicate);
}
});
Because you're using a class, you need to perform a deep MemberwiseClone on it to get a NEW copy of the object:
o.CompanyInfoOrganisation = (YourInfoType)duplicate.CompanyInfoOrganisation.MemberwiseClone();
When you load the data, load the CompanyInfoOrganisation property along with the root entity; that way it will be already loaded into memory. If using LINQ to SQL, you load via DataLoadOptions, and pass this to the context. If using Entity Framework, you use the Include method in the LINQ query.
It might have to do with capturing of variables inside the lambda. Try substituting the .ForEach to a regular foreach().
Or maybe the CompanyInfoOrganisation in duplicate was null to begin with.
The problem was I used string.Join() to show the values, and the first value to join was null (which is really annoying), resulting in an empty string, leaving me thinking the property was null. However it turned out the property was not null, but has a perfectly valid reference to the object needed. Using the debugger with a little more care would have saved me an hour or so...
Sorry!
EPiServer only:
How do I search for pages with any value in a given property? I can do a search for pages with a specific value in the property, but I can't figure out how to search for "not empty".
For example, this doesn't work:
var criterias = newPropertyCriteriaCollection
{
new PropertyCriteria()
{
Condition = CompareCondition.NotEqual,
Name = "MyProperty",
IsNull = false,
Type = PropertyDataType.String,
Value = ""
}
};
var pages = DataFactory.Instance.FindPagesWithCriteria(PageReference.StartPage, criterias);
An exception is thrown, "The crieria value cannot be null or empty. Set the IsNull property to search for null."
Any ideas?
Yeah, this is confusing. In case anyone else stumbles on this, here's how to search for pages with a certain PageReference property set to something:
new PropertyCriteria()
{
createdCriteria.Name = "MyProperty";
createdCriteria.Type = PropertyDataType.PageReference;
createdCriteria.Condition = EPiServer.Filters.CompareCondition.NotEqual;
createdCriteria.Value = "0";
createdCriteria.IsNull = false;
}
Unless I'm missing a trick, this doesn't appear to be possible using the EPiServer PropertyCriteriaCollection.
I've had a dig around in reflector and here are my findings. The FPWC method eventually calls EPiServer.DataAccess.PropertySearchDB.FastFindPagesWithCriteria().
Within this method is the following:
foreach (PropertyCriteria criteria in criterias)
{
if (criteria.IsNull)
{
criteria.Value = null;
}
else if (string.IsNullOrEmpty(criteria.Value))
{
throw new EPiServerException("The crieria value cannot be null or empty. Set the IsNull property to search for null.");
}
...
}
So its not possible to search for an empty string value, without setting IsNull to true. This is then fed down to the EPiServer.DataAccess.PropertySearchDB.ExecuteCriteria method, which constructs and formats the DB command. Because IsNull is true, the netPropertySearchNull stored proc is used. Searching for a string needs to use the netPropertySearchString stored proc.
if (criteria.IsNull && !PageDB.IsMetaData(criteria.Name))
{
cmd.CommandText = "netPropertySearchNull";
}
My suggestion would be to load the full list of pages and filter using linq. Alternatively you could look into bypassing the API and implementing a direct DB query, or use some of the low level EPiServer data access methods (not recommended)
Apologies for my first answer - I really should test code before posting :)
I've seen something where the page has a a hidden bool property "Property X contains a value" that is set in the Saving event.
Then that bool property is used as a PropertyCriteria instead of the one you are REALLY interested in.
To find empty values you need to specify the IsNull property on the PropertyCriteria and use the Equal compare condition.
E.g
var criterias = newPropertyCriteriaCollection
{
new PropertyCriteria()
{
Condition = CompareCondition.NotEqual,
Name = "MyProperty",
IsNull = true,
Type = PropertyDataType.String
}
};
I cant get this to work. The State field is empty on certain occassions, I am trying to get the result to return "--" if it is empty, or doesn't exist.
var CusipFields = from c in xml.Descendants("LISTARRAY")
orderby c.Element("ASKYIELD").Value descending
select new BondData()
{
CUSIP = c.Element("CUSIP").Value,
Description = (string)c.Element("ISSUER").Value,
Maturity= c.Element("MATURITYDT").Value,
AskYield = float.Parse(c.Element("ASKYIELD").Value),
State = (string)c.Element("STATE").Value ?? "--"
}
;
This just doesn't want to work. The error I am getting is:
NullReferenceException was unhandled. {"Object reference not set to an instance of an object."}
I KNOW that it does not exist. I thought that putting ?? "--" will return "--" if c.Element("STATE").Value is null.
I can resort to modifying the statement to:
var CusipFields = from c in xml.Descendants("LISTARRAY")
orderby c.Element("ASKYIELD").Value descending
select c;
foreach(var t in CusipFields)
{
switch(t.name)
{
}
}
But I think that it is slower. And its not what I want.
Use this:
State = (string)c.Element("STATE") ?? "--"
instead of
State = (string)c.Element("STATE").Value ?? "--"
My answer assumes, that your problem is, that the STATE element is missing, not empty. Please tell me, whether or not that fixed your problem.
I think it's because c.Element("STATE") is null, not it's Value property.
try:
(string)c.Element("STATE") != null? (string)c.Element("STATE").Value : "--";
You're getting this error not because the Value property is null, but because c.Element(...) is null. You'll need to check for nulls in all of your Element() calls and take appropriate action in order to avoid this error.
I'm using C# to write a simple program to read Active Directory and display the value held in a AD field on a Windows form program.
If a property doesn't exist then the program crashes, below is my code, how can I catch this and move on to the next field without doing a try/catch for each and every attribute?
DirectoryEntry usr = new DirectoryEntry("LDAP://" + domain, username, password);
DirectorySearcher searcher = new DirectorySearcher(usr);
searcher.Filter = "(sAMAccountName=" + GlobalClass.strUserName + ")";
searcher.CacheResults = false;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("telephoneNumber");
//program crashes here if telephoneNumber attribute doesn't exist.
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();
Just checking usr.Properties["telephoneNumber"] will not work. You must check the actual value. The reason the error is occuring is because you're calling ToString() on Value which is null.
user.Properties will always return a PropertyValueCollection, regardless of the property name entered into the collections indexer.
I.e.
var pony = usr.Properties["OMG_PONIES"]; // Will return a PropertyValueCollection
var value = pony.Value; // Will return null and not error
You need to check the value itself, the best way through the null coalescing operator:
textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value
?? "Not found").ToString();
Store the contents of usr.Properties["telephoneNumber"]; in a variable and check for null:
PropertyValueCollection tel = usr.Properties["telephoneNumber"];
textBoxFirstName.Text = (tel != null && tel.Value != null)
? tel.Value.ToString()
: "";
Use the null-coalescing operator (??) operator.
textBoxFirstName.Text = (usr.Properties["telephoneNumber"].Value
?? String.Empty).ToString();
This way the value is replaced with an empty string if null. You could also just return null instead of String.Empty, the reason your code is crashing is because you're trying to call ToString() on a null value.
Something like this should work. If telephoneNumber is not null, it will convert the value to a string, otherwise it will use an empty string.
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value != null
? usr.Properties["telephoneNumber"].Value.ToString()
: "";
A couple of things will help this be more graceful:
Test usr.Properties["telephoneNumber"] for null before calling child properties like Value. I haven't worked with AD myself, but most string-keyed indexers are designed to gracefully handle non-existent keys. the CLR, on the other hand, will happily throw a NullReferenceException any time you try to reference a member of anything that evaluates to null.
On the off chance that AD DOES blow up on a nonexistent column, enclose the assignment in a Try-Catch block that will show an error on the screen and gracefully continue processing (or not).
Use this code
SearchResult.Properties.Contains("property")
To check if the object actually has the prop loaded from the search result
if (usr.Properties["telephoneNumber"] != null)
textBoxFirstName.Text = usr.Properties["telephoneNumber"].Value.ToString();