Error : Sequence contains no elements - c#

I got a error when i get lat and long using locationService.GetLatLongFromAddress
The error is :
Sequence contains no elements
I have tried this code
var locationService = new GoogleLocationService();
var points = locationService.GetLatLongFromAddress("Ram Theatre Bus Stop, Arcot Road, Vadapalani, Chennai, Tamil Nadu");
mapDetail.Latitude = points.Latitude;
mapDetail.Longitude = points.Longitude;
mapDetail.CollegeAddressId = addressDetail[i].CollegeAddressId;
What is the problem? How can i solve this?

You would typically get that if code uses .First() or .Single() on a sequence (IEnumerable<T>) that has (as the message suggests): no elements. Meaning: an empty sequence (not to be confused with a null sequence). You don't show code that does that, so I can only assume this happens inside .GetLatLongFromAddress(). So it sounds like there is a bug, probably relating to the "not found" case, but in code that we can't see. Personally, I would expect the "not found" case to return a null, or to throw some explicit "not found" exception. If this bug is inside a library: tell the library authors about it. Or better: fix it, and submit a pull request (if you can).
Edit: here we go:
XDocument doc = XDocument.Load(string.Format(APIUrlLatLongFromAddress,
Uri.EscapeDataString(address)));
var els = doc.Descendants("result").Descendants("geometry")
.Descendants("location").First();
if (null != els) {...}
IMO, that should be:
XDocument doc = XDocument.Load(string.Format(APIUrlLatLongFromAddress,
Uri.EscapeDataString(address)));
var els = doc.Descendants("result").Descendants("geometry")
.Descendants("location").FirstOrDefault();
if (null != els) {...}
One line code fix to send them...

I've merged in Mark Gravell's pull request for the GoogleLocationService and have pushed an updated Nuget package.
https://www.nuget.org/packages/GoogleMaps.LocationServices/

Related

How to select nested attribute in scan in DynamoDB?

I realize this is answered in the documentation (basically, "use the dot syntax"), but I'm still missing something. I'm using the .NET SDK and need to be able to select just a few attributes from a scan, one of which is a boolean inside a Map attribute. Note that I'm not trying to filter the results. I want all of the items, but I only want some of the attributes returned to me.
var config = new ScanOperationConfig
{
AttributesToGet = new List<string> { "foo.bar" },
Select = SelectValues.SpecificAttributes
};
var search = Table.Scan(config);
var documents = await search.GetRemainingAsync();
This code gets me the items I expect, but it's missing the "foo.bar" attribute. I know I can select the entire foo object, but I'm trying to minimize the amount of data handed back. I don't want the other attributes inside the foo object.
The relevant attribute of the item has the following JSON format:
{
"foo": {
"bar": true
}
}
I checked spelling, case sensitivity, etc. to no avail. Any idea what's wrong?
Instead of using Table.Scan, use the AmazonDynamoDBClient and you get more options.
The Client's ScanAsync method takes a ScanRequest which has a ProjectionExpression string. This is not present on the ScanOperationConfig class and that was the source of confusion.
Use the ProjectionExpression like so:
var scanRequest = new ScanRequest(Table.TableName)
{
ProjectionExpression = "foo.bar"
};
According to the documentation on ProjectionExpression:
ProjectionExpression replaces the legacy AttributesToGet parameter.
I didn't realize AttributesToGet was legacy until finally looking at the client for a totally unrelated problem and happened to find my answer to this problem.

Linq to XML: Queries for If blocks C#

I've got XML set up like this
<customers>
<customer id="1">
<name title="Mr" first="John" last="Smith" />
<contact number="07123123123" email="john.smith#johnsmith.com" />
<address postcode="E1 1EW">1 Paper Street, London, England, GB</address>
</customer>
(...)
</customers>
I'm trying to query it with Linq to XML for learning purposes. So far I can XDocument.Load the file fine and add/remove etc. But I can't seem to figure out a way to query my XML documents for use in an if block. for example something like (Pseudo code):
XDocument document = XDocument.Load("People.xml");
if(
exists(
document.customers.customer.name.first.value("john")
&& document.customers.customer.name.last.value("smith")
)
)
{
bool exists = true;
}
Whatever I try something the compiler will either laugh at me or spit out something about how it cannot implicitly convert an Ienumerable bool to a bool.
I've been trying many combinations of things from many different google searches for a while now and I think guessing is starting to do more harm than good, can anybody provide a C# snippet that would work in an if block for my xml setup? Just to see if first and last name exist together in the same node. Usually once I see something actually work I can take it from there. Most of the questions I find on the net are only searching to see if the entire node exists or are only searching for one attribute and I just can't seem to tailor it.
(Before anybody bursts into flames over my XML structure, this is not for production purposes, I just want to get a grasp of using this in case I need to in an upcoming project.)
Bonus love for anybody that can link any documentation that's not MSDN (I already have about 10 tabs open on it) and involves some good low level/beginner tutorials on Linq to XML.
To check for John Smith exists as a customer in your XML you ll use
XDocument doc = XDocument.Load(Path);
var customers = doc.Descendants("customer");
//To Check for John Smith
if (customers.Elements("name")
.Any(E => E.Attribute("first").Value == "John"
&& E.Attribute("last").Value == "Smith"))
{
//Do your thing
}
Created a boolean called check to hold the result.
do a count on how many elements called name have attributes First=john and last=smith
Then set the result to check variable.
BTW your XML was missing a " in front of John. That will cause you problems :)
bool check;
var res = XDocument.Load(#"c:\temp\test.xml");
var results = res.Descendants("name")
.Where(x => x.Attribute("first").Value == "john" && x.Attribute("last").Value == "smith")
.Select(x => x.Elements()).Count();
check = results != 0;
XPath is your friend
using System.Xml.XPath;
...
void foo(){
XDocument document = XDocument.Load("People.xml");
var firstCustomerNode = document.XPathSelectElement(
"/customers/customer[0]/name"
);
var hasfirstNameAndLastName = firstCustomerNode.Attribute("firstname") != null && firstCustomerNode.Attribute("lastname") != null;
if(hasfirstNameAndLastName)
{
}
}
Please note that you may also use a schema to validate your Xml, but it's more complex to write.
If you don't want to use XPath, you may also write:
var firstCustomerNode = document.Root.Element("Customers").Elements("customer").First().Element("name");
But honestly, the XPath query is far more readable, and will simplify the error check. This code suppose all the elements up to the target node exists. If not, your code will fail with a poor NullReferenceException.
You need to start by querying the Document.Root.Descendants. Then a method such as IfExists
var nodes = document.Root.Descendants("customer");
bool IfExists(string FirstName, string LastName) {
return nodes.Elements("name").Any(node =>
node.Attribute("first").Value.Equals(FirstName) &&
node.Attribute("last").Value.Equals(LastName));
}
You may want to add exception handling in case an attribute is missing or contains an empty value.

Extension method for Null handling not working on linq for xml

I have an nullexception issue when trying to get the value of an xml tag, which is under a subtree that may not be there.
The extension handler works great when it can't find a tag on an existing subtree, but seems to not be able to handle when looking for a tag in a subtree that doesn't exist.
In this case, the subtree is summaryData, which may or not be there, and trying to get addressLine1 is where it doesn't handle the null, and I get the error
System.NullReferenceException occurred, Message=Object reference not
set to an instance of an object.
Here is the xml, cut down for clarity, but structure is correct:
<record>
<accounts>
<account >
</account >
</accounts>
<summaryData>
<Date>2013-02-04</Date>
<address >
<city>Little Rock</city>
<postalCode>00000</postalCode>
<state>AR</state>
<addressLine1>Frank St</addressLine1>
</serviceAddress>
</summaryData>
</record>
My C# code is:
xmlDoc.Descendants("account")
//select (string)c.Element("account") ;
select new
{
//this works fine
Stuffinxml = c.Element("stuffinxml").Value,
//this field may not be there, but the handler handlers the exception correctly here when it as the correct root (account)
otherstuff = CustXmlHelp.GetElementValue(mR.Element("otherstuff")),
//this is the problem, where the summaryData root does not exist (or moved somewhere else)
street_address = GetElementValue(c.Element("summaryData").Element("serviceAddress").Element("addressLine1"))
};
My extension method to handle a null is:
public static string GetElementValue(this XElement element)
{
if (element != null)
{
return element.Value;
}
else
{
return string.Empty;
}
}
Any help would be appreciated, as I can't see why it fails when the subtree does not exist.
The summary data may or may not be there
That's why. As you're nesting calls, you'll have to null check them all.
Any one of these could be null:
c.Element("summaryData").Element("serviceAddress").Element("addressLine1")
Without a complex conditional, there's not a nice way around it:
street_address = c.Element("summaryData") != null
? c.Element("summaryData").Element("serviceAddress") != null
? GetElementValue(c.Element("summaryData").Element("serviceAddress").Element("addressLine1"))
: string.Empty
: string.Empty;
If the summaryDate element does not exist then
c.Element("summaryData").Element("serviceAddress").Element("addressLine1")
will throw a NullReferenceException because you're trying to call Element() on a null reference (c.Element("summaryData"))
As had been stated, your exception is due to the fact that you are passing multiple nested queries
c.Element("summaryData").Element("serviceAddress").Element("addressLine1")
is the equivalant of writing:
var x1 = c.Element("summaryData");
var x2 = x1.Element("serviceAddress")
var x3 = x2.Element("addressLine1")
So if any of c, x1, or x2 are null, you are going to get a NullReferenceException.
One possible alternative to a pure LINQ solution using multiple null checks, is to use XPath to build the expression.
With XPath, rather than doing a null check at every level, you can instead write your expression:
street_address = GetElementValue(c.XPathSelectElement("/summaryData/serviceAddress/addressLine1"))
This will evaluate the entire expression and if it does not exist in its entirety, it will return null, but will not thrown an exception like your pure LINQ query.

Reading from an attribute that might be missing in a xelement.add method in C#

I am trying to create a XElement that reads from another XElement built from a file. Below is a sample of the code. My question is how do I code around a source attribute that might not be there? docHeader and invoice are XElements. When running this where one attribute is missing, I get a "Object reference not set to an instance of an object" error.
I guess I am asking is there a 'safe' way to read elements and attributes in case they are not there?
invoice.Add(
new XAttribute("InvoiceNumber", docHeader.Attribute("InvoiceNumber").Value),
new XAttribute("InvoiceSource", docHeader.Attribute("InvoiceSource").Value));
You are getting the exception because if the attribute InvoiceSource is not present, docHeader.Attribute("InvoiceSource") returns null. Simple check like
if (docHeader.Attribute("InvoiceSource") != null)
{
// here you can be sure that the attribute is present
}
will be sufficient.
Try breaking up the code so that it's more flexible and readable.
var src = docHeader.Attribute("InvoiceSource");
var num = docHeader.Attribute("InvoiceNumber");
if(src != null && num != null)
{
invoice.Add(
new XAttribute("InvoiceNumber", num.value),
new XAttribute("InvoiceSource", src.value));
}

Need help with a LINQ ArgumentOutOfRangeException in C#

Hoping this is a nice softball of a question for a friday but I have the following line of code:
//System.ArgumentOutOfRangeException generated if there is no matching data
currentAnswers = new CurrentAnswersCollection()
.Where("PARTICIPANT_ID", 10000).Load()[0];
CurrentAnswersCollection is a strongly-typed collection populated by a view going back to my database.
The problem of course is that if there is not a corresponding PARTICIPANT_ID = 10000 I get the error message.
Is there a better way to write this so that I wouldn't get the error message at all?
I just dont know enough about LINQ syntax to know if I can test for the existance first?
thanks.
Use this:
currentAnswers = new CurrentAnswersCollection()
.Where("PARTICIPANT_ID", 10000).Load()
.FirstOrDefault();
It'll return null if there is no first element.
But you may need to fix your code (replicated here) first - the .Where syntax looks dodgy.
The ArgumentOutOfRangeException is occurring when you try to use the indexer to get the first item from the (empty) list. Using the FirstOrDefault() extension method is a convenient way to return the first element of a collection, if there is one, otherwise to return null.
currentAnswers = new CurrentAnswersCollection().Where("PARTICIPANT_ID", 10000)
.Load()
.FirstOrDefault();
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault.aspx
Try:
var answers = new CurrenAnswersCollection().Where("PARTICIPANT_ID", 10000);
if(answers.Count() >= 1) currentAnswers = answers.Load()[0];
or something similar.
You need a lambda expression in .Where.
currentAnswers = new CurrentAnswersCollection()
.Where(c => c.PARTICIPANT_ID == 10000).Load().FirstOrDefault();

Categories

Resources