C# Service Export - Extended Price does not export in the same position

I created a service with the below model.   The service gets data from a database and exports it to an excel CSV file.  

The issue is with the extended price.  The export will put it in position 14 (where it is at currently) but sometimes it is added at the end.  

Anyone know why that would happen?  

I have a winform app that I'm using to troubleshoot the problem.  Also, I'm running the service on my local computer and it seems to put the extended price in the last column instead of position 14.  Any ideas?
    public class PODataModel
    {
        public string name { get; set; }
        public string en { get; set; }
        public string state { get; set; }
        public string purchaseOrderNumber { get; set; }
        public string dateOrder { get; set; }
        public string currency { get; set; }
        public string requiredDate { get; set; }
        public string promisedDate { get; set; }
        public string shipDateNew { get; set; }
        public string total { get; set; }
        public string Name2 { get; set; }
        public string unitPrice { get; set; }
        public string rate { get; set; }
        public string extendedPrice
        {
            get
            {
                double value = ((Convert.ToDouble(unitPrice) * Convert.ToDouble(total)) - ((Convert.ToDouble(unitPrice) * Convert.ToDouble(total) * (Convert.ToDouble(rate) / 100))));
                return value.ToString("###0.00");
            }
        }
        public string id_customer { get; set; }
        public string Customer_Name { get; set; }
        public string id_product { get; set; }
        public string Product_Name { get; set; }
    }

Open in new window

LVL 2
CipherISAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
What is your method used to serialize and output the class properties to a csv.  Without being able to specify an order, you are left to the implementation of the method used.

-saige-
0
CipherISAuthor Commented:
Below is the code that I am using to export.  I modified it and added below as indicated in CAPS.  

I thought that the export would occur in the order of the model.  It seems to switch though and don't understand why.
    public class ExportExcelCVS<T> : IExportData<T>
    {
        string filename = string.Empty;

        public void ExportData(IList<T> value)
        {
            try
            {
                string currentDate = DateTime.Now.ToString("yyyyMMdd");
                filename = AppSettings.GetExportLocationFileName();
                string filenameexport = AppSettings.GetExportLocation() + filename + AppSettings.GetExportLocationFileNameExt();
                string filenamefrom = AppSettings.GetExportProcessLocation() + filename + AppSettings.GetExportLocationFileNameExt();
                string filenameto = AppSettings.GetExportLocationArchive() + currentDate + filename + AppSettings.GetExportLocationFileNameExt();
                string ext = "*" + AppSettings.GetExportLocationFileNameExt();
                string extPrice = string.Empty;  //ADDED 

                FileService.DeleteFiles(AppSettings.GetExportLocation(), ext);

                using (StreamWriter sw = new StreamWriter(filenamefrom, false))
                {
                    sw.WriteLine(currentDate);

                    Type type = typeof(T);
                    PropertyInfo[] properties = type.GetProperties();

                    foreach (T instance in value)
                    {
                        StringBuilder result = new StringBuilder();

                        foreach (PropertyInfo property in properties)
                        {
                            string parsevalue = property.GetValue(instance, null).ToString();

                            if (parsevalue.Contains('\n'))
                                parsevalue = parsevalue.Replace('\n', ' ').Replace('\n', ' ');

                            if (parsevalue.Contains(';'))
                                parsevalue = parsevalue.Replace('\n', ' ').Replace(';', ':');

                            if (parsevalue.Contains(','))
                                parsevalue = parsevalue.Replace('\n', ' ').Replace(',', ' ');

                            if (property.Name == "extendedPrice")  //ADDED 
                                extPrice = parsevalue;  //ADDED 
                            else  //ADDED 
                                result.Append(parsevalue + AppSettings.GetSeparator());
                        }

                        result.Append(extPrice + AppSettings.GetSeparator());  //ADDED 
                        sw.WriteLine(result.ToString());
                        extPrice = string.Empty;  //ADDED 
                    }
                }
                FileService.CopyFiles(filenamefrom, filenameto);
                FileService.CopyFiles(filenamefrom, filenameexport);
                FileService.DeleteFiles(AppSettings.GetExportProcessLocation(), ext);

                filename = AppSettings.GetExportLocationArchive() + AppSettings.GetExportResultFileName();
                ExportResult.WriteResult(AppSettings.GetItemsRegionResult(), filename);
            }
            catch (Exception ex)
            {
                filename = AppSettings.GetExportLocationArchive() + AppSettings.GetExportErrorFileName();
                ExportResult.WriteError(ex.ToString(), filename);
                //Environment.Exit(1);
            }
        }
    }

Open in new window

0
it_saigeDeveloperCommented:
Using pure reflection the methods (GetProperties and GetFields)
do not return Properties/Fields in any particular order


- Source
In order to control the order of your properties or fields, you will want to use an Attribute; e.g. -
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

namespace EE_Q29099706
{
    class Program
    {
        static void Main(string[] args)
        {
            var people = (from i in Enumerable.Range(0, 5)
                          select new Person
                          {
                              ID = i,
                              FirstName = $"First{i}",
                              MiddleName = $"Middle{i}",
                              LastName = $"Last{i}",
                              Birthdate = DateTime.Now.AddYears(-(i * 9)),
                              IsWorking = i % 2 == 0
                          });

            foreach (var person in people)
            {
                Console.WriteLine($"Person: {{ {string.Join(", ", (from prop in person.GetOrderedProperties() select $"{prop.Name}: {prop.GetValue(person, null)}"))} }}");
            }
            Console.ReadLine();
        }
    }

    class Person
    {
        [Display(Order = 4)]
        public string LastName { get; set; }
        [Display(Order = 3)]
        public string MiddleName { get; set; }
        [Display(Order = 2)]
        public string FirstName { get; set; }
        [Display(Order = 1)]
        public DateTime Birthdate { get; set; }
        [Display(Order = 0)]
        public int ID { get; set; }
        public bool IsWorking { get; set; }
    }

    static class Extensions
    {
        public static IEnumerable<PropertyInfo> GetOrderedProperties<T>(this T source)
        {
            return (from prop in typeof(T).GetProperties()
                    let attributes = prop.GetCustomAttributes(typeof(DisplayAttribute)).ToArray()
                    where attributes.Count() != 0
                    orderby ((DisplayAttribute)attributes[0]).Order
                    select prop);
        }
    }
}

Open in new window

Which produces the following output -Capture.PNG-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

CipherISAuthor Commented:
Thanks
0
CipherISAuthor Commented:
Saige,

I'm using VS2012.  How do I implement below in my code?

Console.WriteLine("{{ {string.Join(", ", (from prop in person.GetOrderedProperties() select "{property.Name}: {prop.GetValue(person, null)}"))} }}");

Also, is it possible not to use "person" as in your example?

Thanks
    public class ExportExcelCVS<T> : IExportData<T>
    {
        string filename = string.Empty;

        public void ExportData(IList<T> value)
        {
            try
            {
                filename = DateTime.Now.ToString("yyyyMMdd") + AppSettings.GetExportLocationFileName();
                string filenameexport = AppSettings.GetExportLocation() + filename + AppSettings.GetExportLocationFileNameExt();
                string filenamefrom = AppSettings.GetExportProcessLocation() + filename + AppSettings.GetExportLocationFileNameExt();
                string filenameto = AppSettings.GetExportLocationArchive() + filename + AppSettings.GetExportLocationFileNameExt();
                string ext = "*" + AppSettings.GetExportLocationFileNameExt();
                string extPrice = string.Empty;

                FileService.DeleteFiles(AppSettings.GetExportLocation(), ext);

                using (StreamWriter sw = new StreamWriter(filenamefrom, false))
                {
                    Type type = typeof(T);
                    PropertyInfo[] properties = type.GetProperties();

                    foreach (PropertyInfo property in properties)
                    {
                        Console.WriteLine("{{ {string.Join(", ", (from prop in person.GetOrderedProperties() select "{property.Name}: {prop.GetValue(person, null)}"))} }}");
                    }

                    //sw.WriteLine(result.ToString());
                }
                FileService.CopyFiles(filenamefrom, filenameto);
                FileService.CopyFiles(filenamefrom, filenameexport);
                FileService.DeleteFiles(AppSettings.GetExportProcessLocation(), ext);

                filename = AppSettings.GetExportLocationArchive() + AppSettings.GetExportResultFileName();
                ExportResult.WriteResult(AppSettings.GetItemsRegionResult(), filename);
            }
            catch (Exception ex)
            {
                filename = AppSettings.GetExportLocationArchive() + AppSettings.GetExportErrorFileName();
                ExportResult.WriteError(ex.ToString(), filename);
                Environment.Exit(1);
            }
        }
    }

Open in new window

0
CipherISAuthor Commented:
I have it down to this.  Not getting all the fields in the model.
                using (StreamWriter sw = new StreamWriter(filenamefrom, false))
                {
                    Type type = typeof(T);
                    PropertyInfo[] properties = type.GetProperties();

                    Console.WriteLine("CRV");

                    foreach (PropertyInfo property in type.GetProperties())
                    {
                        Console.WriteLine( string.Join("|", (from prop in property.GetOrderedProperties() select property.GetValue(prop, null))) );
                        //Console.WriteLine("{{ {string.Join(", ", (from prop in person.GetOrderedProperties() select "{property.Name}: {prop.GetValue(person, null)}"))} }}");
                    }

                }

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.