Question

I Have the following scenario, and would like some help guidance on the topic:

I Have an XML file composed of user credentials (Not for commercial use, so security is really not of any significance in this scenario) for a simple chat application. If a user subscribes to the service, his credentials should match that recorded in the XML file.


Code snippet of the XML file:

<Users>
 <User>
  <Username>Johan</Username>
  <Password>Johan123</Password>
 </User>
 <User>
  <Username>Carel</Username>
  <Password>Carel123</Password>
 </User>
  ...
  ...
</Users>

Then I have the following class:

public class Credentials
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }

The Credentials class is merely going to be used to retrieve the List of users recorded in the XML file, as well as retrieving specific users.

I have the following code that can retrieve elements out of the XML file:

public List<Credentials> RetrieveUsers()
        {
            Root = XElement.Load(path + "Users.xml");
            List<Credentials> credentials = new List<Credentials>();

            var xmlResults = from element in Root.Elements().Elements()
                     select new 
                     {
                           Username = element.Element("Username").Value,
                           Password = element.Element("Password").Value
                     };

            foreach(var xmlResult in xmlResults)
            {
                Credentials temp = new Credentials();

                temp.Username = xmlResult.Username;
                temp.Password = xmlResult.Password;

                credentials.Add(temp);
            }

            return credentials;
        }

However, this feels redundant. I want to achieve something in the line of the following (This does not work):

public List<Credentials> RetrieveUsers()
        {
            Root = XElement.Load(path + "Users.xml");
            List<Credentials> credentials = new List<Credentials>();

            List<Credentials> xmlResults = from element in Root.Elements().Elements()
                select new 
                {
                       Username = element.Element("Username").Value,
                       Password = element.Element("Password").Value
                };
            return xmlResults;
        }

It gives me the following error:

"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)"

which makes perfect sense, as I imagine it uses IEnumerable to enumerate through the collection made by the select LINQ statement.

Any help on the matter would be appreciated, and please tell me if I'm looking at this from the wrong angle, if I can use another approach instead. Thanks in advance

Was it helpful?

Solution

You just need to call the ToList extension method to create a list. Also, you need to create Credentials objects rather than instances of an anonymous type. For example:

var xmlResults = from element in Root.Elements().Elements()
                 select new Credentials
                 {
                     Username = element.Element("Username").Value,
                     Password = element.Element("Password").Value
                 };
return xmlResults.ToList();

Personally I don't tend to use query expressions for simple from/select queries - I'd have written:

return Root.Elements().Elements() // TODO: Consider specifying the element name
           .Select(element => new Credentials
                   {
                     Username = element.Element("Username").Value,
                     Password = element.Element("Password").Value
                   })
           .ToList();

The advantage of using "dot notation" like this is that calling ToList doesn't leave you with a query expression in brackets, which always looks a bit ugly.

OTHER TIPS

Did you try this:

        List<Credentials> xmlResults = Root.Elements().Elements()
            .Select(element => new Credential() {
                   Username = element.Element("Username").Value,
                   Password = element.Element("Password").Value
            })
            .ToList();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top