Beispiel #1
0
        private static RosterItem GetRosterItem(int NextId)
        {
            RosterItem returnValue = new RosterItem();

            //were only collecting 3 of the properties
            string FirstName = "";
            string LastName  = "";
            string Gender    = "";

            //create a validator with our new fluent validator class
            //take alook at the comments in the RosterItemValidator class
            RosterItemValidator validator = new RosterItemValidator();

            //start with the object as invalid
            bool IsValid = false;

            //this condition should always be triggered the first time through
            //then only triggered if a property is invalid
            while (!IsValid)
            {
                //this prevents a user having to re-enter valid values
                //if the field has an error we blank it out
                if (String.IsNullOrEmpty(FirstName))
                {
                    //get the first name
                    Console.WriteLine("Enter a FirstName: ");
                    FirstName = Console.ReadLine();
                }

                if (String.IsNullOrEmpty(LastName))
                {
                    //get the lastname
                    Console.WriteLine("Enter a LastName:");
                    LastName = Console.ReadLine();
                }

                if (String.IsNullOrEmpty(Gender))
                {
                    //get the gender
                    Console.WriteLine("Enter a Gender:");
                    Gender = Console.ReadLine();
                }

                //assign our values to the roster item
                returnValue = new RosterItem
                {
                    ID        = NextId,
                    FirstName = FirstName,
                    LastName  = LastName,
                    Gender    = Gender
                };

                //check to see if the values are valid
                ValidationResult results = validator.Validate(returnValue);

                //set the variable for the loop
                IsValid = results.IsValid;

                //loop through all of the errors and display
                //an error message for each error
                foreach (var failure in results.Errors)
                {
                    //change the foreground color to red
                    Console.ForegroundColor = ConsoleColor.Red;

                    //display the error (blank line in front and behind)
                    Console.WriteLine("");
                    Console.WriteLine($"Property {failure.PropertyName} failed validation. \r\nError was: {failure.ErrorMessage}");
                    Console.WriteLine("");

                    //reset the console color
                    Console.ResetColor();

                    //blank out the bad value so it will be repeated to the user
                    switch (failure.PropertyName)
                    {
                    case "FirstName":
                        FirstName = "";
                        break;

                    case "LastName":
                        LastName = "";
                        break;

                    case "LastName.Length":
                        LastName = "";
                        break;

                    case "Gender":
                        Gender = "";
                        break;
                    }
                }
            }

            return(returnValue);
        }
Beispiel #2
0
        //this method is declared as static so it can be run in
        //another static method
        //I've changed this method a bit to read directly into a List<>
        //instead of just a string
        private static List <RosterItem> ReadFileToRosterList(string FileName)
        {
            //I always like to start my method by declaring the return
            //value when there is a value to be returned
            List <RosterItem> returnValue = new List <RosterItem>();

            //set up a counter and line variable
            int    counter = 0;
            string line;

            //always be aware of what resources your program is using
            //The C# garbage collector does a pretty good job of maintaining program
            //resources, but you shouldn't count on it whe using librarys that
            //acces external resources sunch as files or databases

            //create a progress bar using a nuget package called ShellProgressBar
            //https://github.com/Mpdreamz/shellprogressbar
            //found this by googling "c# console app progress bar"
            //the max number of items to process
            var maxTicks = File.ReadLines(FileName).Count();

            //create a progress bar
            using (var pbar = new ProgressBar(maxTicks, "Starting", ConsoleColor.DarkGreen))
            {
                //we use a "using" statement to make sure the file resource is released from
                //memory. A try..catch..finally can be used but a "using" statement is easier.
                using (System.IO.StreamReader file = new System.IO.StreamReader(FileName))
                {
                    while ((line = file.ReadLine()) != null)
                    {
                        //update the progress bar
                        pbar.Tick("Currently processing " + counter);

                        //skip the first line
                        if (counter > 0)
                        {
                            //returnValue += line;
                            RosterItem myRosterItem = new RosterItem();

                            string[] myLineArray = line.Split(',');

                            myRosterItem.ID        = Convert.ToInt32(myLineArray[0]);
                            myRosterItem.FirstName = myLineArray[1];
                            myRosterItem.LastName  = myLineArray[2];
                            myRosterItem.Email     = myLineArray[3];
                            myRosterItem.TeamColor = myLineArray[4];
                            myRosterItem.Gender    = myLineArray[5];
                            myRosterItem.Position  = myLineArray[6];

                            //now that we have a completed object
                            //add it to the returnvalue (Remember the special List<> gives us the ad method automatically)
                            returnValue.Add(myRosterItem);

                            //artifically add a little time to the process
                            System.Threading.Thread.Sleep(250);
                        }

                        counter++;
                    }
                }
            }
            return(returnValue);
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            //Remember a backslash is a special escape character
            //If you want a line with a quote in the middle of the line you have to "escape"
            //the special meaning of a quote. Uncomment each line and see which one
            //passes
            //string illegalQuoteString = "Don't "Quote" me on that!";
            string properlyEscapedQuoteString = "Don't \"Quote\" me on that!";

            //The same way the Dollar sign can be used for string interpolation
            //the @ symbol can be used to automatically escape characters between
            //the quotes. So a file path stored in a variable could be assigned like:
            string myExampleFilePath = "C:\\Some\\Path\\To\\A\\File";

            //but it's easier to use the @
            string myBetterExampleFilePath = @"C:\Some\Path\To\A\File";

            //both are correct but I think the second one is easier to read

            Console.WriteLine("*** Creating the list by paring the file ourselves ***");
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();
            //Create a Roster --A list of RosterItems (Yes I renamed them since the meetup)
            //A list is nothing more than more than one of a class
            //This is a generic list List<FillInTheBlankWithYourObject>
            //It automatically gives us methods like Add(), Remove(), Find() and FindAll()
            //The <> angle brackets is a SIGNIFICANT pattern in c# you will find other libraries that
            //use the same pattern. When you see them you usually fill in the blank with a TYPE
            //The next line instantiates the generic list
            List <RosterItem> myRoster = new List <RosterItem>();

            //using System.IO file methods we can open the file and Read each line one at a time
            //Let's read the CSV file straight into our list
            //we don't have to include the entire file path since we set the file to "Copy Always"
            //this places the file in the same debug directory as our EXE
            myRoster = ReadFileToRosterList("Roster.csv");

            //loop through the list and write the first and last name of each roster item
            //along with their position
            foreach (RosterItem item in myRoster)
            {
                //by putting the dollar sign in fromt of the string we're telling
                //c# that we want the variable names inside the string to be translated
                //to their values (String Interpolation)
                Console.WriteLine($"Player: {item.FirstName} {item.LastName}, Position: {item.Position}");

                //lets add some drama by adding a quarter a second wait between lines
                System.Threading.Thread.Sleep(250);
            }

            Console.WriteLine("");
            Console.WriteLine("*** Now let's do it using the file helpers library ***");
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();

            //Convert a CSV file to an object list
            //using FileHelpers (downloaded via nuget)
            var engine = new FileHelperEngine <RosterItem>();

            //we don't want to read the header of the file
            engine.Options.IgnoreFirstLines = 1;

            //Now we do it an easier way
            var result = engine.ReadFile("Roster.csv");

            //we managed to convert the file to our class
            //and only had to use 4 lines of code and add
            //an attribute of [DelimitedRecord(",")] to the class
            //pretty easy
            //lets print the info to screen again
            //this time we'll use a for loop instead of a foreach loop
            //loop through the list and write the first and last name of each roster item
            //along with their position
            for (int i = 0; i < myRoster.Count; i++)
            {
                //assign the item in the array to item
                //I think this makes the code a bit cleaner
                //you can, of course, just use myRoster[i].FirstName
                RosterItem item = myRoster[i];
                Console.WriteLine($"Player: {item.FirstName} {item.LastName}, Position: {item.Position}");

                //lets add some drama by adding a quarter a second wait between lines
                System.Threading.Thread.Sleep(250);
            }
            //so when should we use a for loop insatead of a foreach? when we need to
            //track the item number or when we need a counter for the items we're looping through

            //now that we have the list of items
            //let's "Serialize" them
            //The easy way to think about serialzation is that it's the process of
            //turning an object or object list into text (usually XML or JSON)
            //deserilization is the process of taking serialized text and turning it
            //back inot the object or object list
            //this code requires the XML.Serialzation library

            Console.WriteLine("");
            Console.WriteLine("*** Now let's serialize our list ***");
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();

            // Create a new XmlSerializer instance with the type of the test class
            XmlSerializer SerializerObj = new XmlSerializer(typeof(List <RosterItem>));

            // Create a new filestream so we can write the serialized object to a file
            using (TextWriter WriteFileStream = new StreamWriter("roster.xml"))
            {
                //serialize our list<>
                SerializerObj.Serialize(WriteFileStream, myRoster);
            }

            //open the xml file with notepad
            //how did I figure out how to open a file in notepad?
            //easy I googled "C# Open File Notepad"
            Console.WriteLine("Opening our serialized data in notepad...");
            System.Threading.Thread.Sleep(500);
            Process.Start("notepad.exe", "roster.xml");

            Console.WriteLine("");
            Console.WriteLine("*** Now let's deserialize our list ***");
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();

            //Deserialze the XML file
            // Create a new file stream for reading the XML file
            using (FileStream ReadFileStream = new FileStream("roster.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // Load the object saved above by using the Deserialize function
                //the parenthesses mean we are "casting" the return object to that type
                List <RosterItem> reLoadedRoster = (List <RosterItem>)SerializerObj.Deserialize(ReadFileStream);

                //how many items are in our reloaded list
                Console.WriteLine($"We reloaded {reLoadedRoster.Count} items from our xml file.");
            }


            Console.WriteLine("");
            Console.WriteLine("*** Now let's add a new item to the list ***");
            Console.WriteLine("Press Enter to continue...");
            Console.ReadLine();
            //one of the challanges of adding a new entry is that it must be valid data
            //whenever possible you should prevent the user from entering bad data
            //in a windows or web application this is easier since most data being entered
            //is from a control (dropdown list or textbox), it's much more difficult to validate
            //when the user can only enter text, like in our console app

            //we're going to need to get the highest ID number so the next entry
            //will have a unique ID
            //This is a bit of a cheat since I know the items in the file we read in are numbered sequentially
            //so a simple count of the number of the items in the list + 1 should give us the next ID
            //there are probably a 100 other ways we can do this
            int NextId = myRoster.Count + 1;

            //get a new roster item
            //I broke this into its own method
            RosterItem newRosterItem = GetRosterItem(NextId);

            //Add the new item to the list
            myRoster.Add(newRosterItem);
            Console.WriteLine($"There are now {myRoster.Count} items in our list.");
            Console.WriteLine($"You just added {newRosterItem.FirstName} {newRosterItem.LastName} to the roster.");

            //Console.WriteLine(myString);
            Console.ReadLine();
        }