简体   繁体   中英

Input string was not in a correct format (using SqlDataReader)

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 (1 Datetime + 7 Strings 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; }
}

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 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM