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?
 
it_saigeConnect With a Mentor DeveloperCommented:
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
 
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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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
All Courses

From novice to tech pro — start learning today.