0

I'm getting data from a remote Database, so I don't actually know the column types I'm dealing with. So I was using dataReader.GetString(X) as a default. I can save those values into variables, but when actually trying to send the variables into an object constructor it fails (before getting inside the constructor) with an error : System.FormatException: Input string was not in a correct format. If I can save them to string type variables why does it give an error when trying to use those variables to create an object and not before?

        //VARIABLES
        DateTime PreparationDate;
        string ClientId;
        string ClientName;
        string BL;
        string QTD_TOT;
        string QTD_PREP;
        string X_QTD;
        string TAXA;

            string query = GetPreparationsMACPAC;
            SqlConnection con = new SqlConnection(_connectionString);
            if (con.State == ConnectionState.Closed) con.Open();
            SqlCommand cmd = new SqlCommand(query, con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader dr = cmd.ExecuteReader();

            List<PreparationViewModel> shippingsList = new List<PreparationViewModel>();

            PreparationViewModel prep = new PreparationViewModel(new DateTime(), "1", "2", "3", "4", "5", "6", "7");

            if (dr.HasRows)
            {
                while (dr.Read())
                {                    
                    PreparationDate = dr.GetDateTime(0);
                    ClientId = dr.GetString(1);
                    ClientName = dr.GetString(2);
                    BL = dr.GetString(3);
                    QTD_TOT = dr.GetString(4);
                    QTD_PREP = dr.GetString(5);
                    X_QTD = dr.GetString(6);
                    TAXA = dr.GetString(7);

                    //THE FOLLOWING OUTPUT IS CORRET (see below)
                    Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7}", PreparationDate, ClientId, ClientName, BL, QTD_TOT, QTD_PREP, X_QTD, TAXA);

                    //FAILS HERE
                    try
                    {
                        prep = new PreparationViewModel(PreparationDate, ClientId, ClientName, BL, QTD_TOT, QTD_PREP, X_QTD, TAXA);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }

                    shippingsList.Add(prep);
                }
            }

OUTPUT(1Datetime + 7Strings Seperated by ",")

09/04/2021 00:00:00,92843160002,RENAULT MONTAJE VALLADOLID,506653,120,120,0.000,1.0000000

CLASS MODEL

    public class PreparationViewModel
    {
        public PreparationViewModel()
        {

        }

        public PreparationViewModel(DateTime preparationDate, string clientId, string clientName, string transportDocumentId,
            string totalQuantity, string preparedQuantity, string xQuantity, string complianceRate)
        {
            //BREAKPOINT IS SET, NOT REACHED FROM THE TRY/CATCH CODE
            PreparationDate = preparationDate;
            ClientId = clientId;
            ClientName = clientName;
            TransportDocumentId = transportDocumentId;
            TotalQuantity = Int16.Parse(totalQuantity);
            PreparedQuantity = Int16.Parse(preparedQuantity);
            XQuantity = float.Parse(xQuantity);
            ComplianceRate = float.Parse(complianceRate);
        }

        public DateTime PreparationDate {get;set;}
        public string ClientId { get; set; }
        public string ClientName { get; set; }
        public string TransportDocumentId { get; set; }
        public int TotalQuantity { get; set; }
        public int PreparedQuantity { get; set; }
        public float XQuantity { get; set; }
        public float ComplianceRate { get; set; }
}

10
  • If it fails before getting into the constructor - it means it fails inside PreparationViewModel's static constructor or during initialisation of one of its static members Commented Apr 8, 2021 at 12:21
  • @torvin, How so? I'm able, for example, to create a PreparationsViewModel(new DateTime(),"0","0","0","0","0","0","0") with no troubles; so I'm not quite sure of what do you mean. Commented Apr 8, 2021 at 12:25
  • If you are able to do that then this statement is false: "it fails (before getting inside the constructor)". Try setting a breakpoint inside the constructor. Also a full stack trace would be helpful Commented Apr 8, 2021 at 12:28
  • 1
    It sounds like PreparationViewModel has some code in the constructor that is parsing values from strings; we can't see that code, so we can't really comment - but: my first guess would be "locale". The first thing to say is that you shouldn't really store values in a database as strings if they could be primitives - if you can store it as an int/float/decimal/whatever: do that instead, and don't touch strings. But if you somehow have to use strings, you need to ensure that the parse code uses the right locale, otherwise: bad things. Is "100.000" one hundred, or one hundred thousand? Commented Apr 8, 2021 at 12:29
  • 1
    @Steve Commenting those lines solved it. I thought the error couldn't be on the constructor because the breakpoint didn't get "hit" (it still doesn't, and I don't understand why, from other calls said breakpoint is "hit"). Thank you. Now I know exactly the source of the error and can work on it. Commented Apr 8, 2021 at 13:18

1 Answer 1

1

I'm getting data from a remote database so I don´t know exactly the column types

In that scenario, your best bet is probably something like:

short prepQty = Convert.ToInt16(reader.GetValue(5), CultureInfo.InvariantCulture);

(or if you don't want the invariant culture: replace with whatever culture you do want; if the values are strings and you don't know the culture: you've already lost the battle)

This will handle more data types and have better defined semantics when handling strings. It would be advisable to keep the read/parse code in the code that handles the reader, and have the PreparationViewModel just take the parsed value (the short).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.