0

I have searched for the answer to this question, and just can't seem to find it for my situation, or I just haven't grasped it yet. I am working on a business rule for my company's business software and am receiving the "Specified cast is not valid" error. I know it has to do with the char variable and/or a null, I just can't figure out how to fix it or why I'm getting the error (it's probably simple).

Below is the code for the rule. It is supposed to compare the unit_price to price1, both fields in a table, and replace unit_price with price1 if price1 is higher, and it is to do this for every row in the table.

I had the code working until I tried to add Class4. Class4 specifies items with locked prices. This was to be used to prevent changing prices of items with locked prices. Class4 is a char[8] field in the table, and has two values, LOCKED and null. This is where my issues began.

I have removed references to the program for legal purposes.

Forgive me if my code is messy or completely inefficient or incorrect. I'm fairly new to c# and have been guessing for the most part.

    public class PriceCheck : program.Extensions.BusinessRule.Rule
    {
        decimal Unit = 0m;
        decimal Price1 = 0m;
        String Class4;
        DataTable datatable1;
        Boolean bDebugMode = true;
        int TriggerRow;

        public override RuleResult Execute()
        {
            RuleResult result = new RuleResult();
            result.Success = true;

            if (bDebugMode) MessageBox.Show("Starting PriceCheck"); //MessageBox for debugging purposes, shows that PriceCheck has begun

            try
            {
                if (this.Session.MultiRow)
                {
                    datatable1 = this.Data.Set.Tables["Table"]; //Set table information will be pulled from and sent to
                    TriggerRow = this.Data.TriggerRow;

                    foreach (DataRow row in (InternalDataCollectionBase)datatable1.Rows) //Begin loop for all rows in datatable1
                    {
                        Unit = DataRowExtensions.Field<Decimal>(row, "unit_price"); //Retrieve Unit Price from current row
                        Price1 = DataRowExtensions.Field<Decimal>(row, "inv_mast_price1"); //Retrieve Price1 from current row
                        Class4 = Convert.ToString(DataRowExtensions.Field<Char?>(row, "class_id4")); //Retrives Class4 from current row
                        if (bDebugMode) MessageBox.Show("Unit Price " + Unit + "\n" + "Price 1 " + Price1 + "\n" + "Class 4" + Class4, "Debug", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); //MessageBox for debugging, shows values in Unit, List, and Class4

                        if (Class4 == "LOCKED")
                        {
                            if (bDebugMode) MessageBox.Show("Class 4 Locked" + "\n" + "Unit Price will remain the same!" + "\n" + "Unit Price " + Unit, "Class 4 Locked", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        }
                        else
                        {
                            if (Unit > 0) //if unit is null(0), the rule will fail, this is here to prevent that...might change to item Id, depending on if any items have 0 Unit Price and Price 1
                            {
                                if (bDebugMode) MessageBox.Show("Unit > 0", "Unit Check", MessageBoxButtons.OK, MessageBoxIcon.Information); //MessageBox for debugging, shows that this if statement has been reached

                                if (Unit < Price1) //beginning of calculations
                                {
                                    if (bDebugMode) MessageBox.Show("Price 1 " + Price1, "Debug", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); //Shows Price1 before putting it into the unit_price field
                                    DataRowExtensions.SetField<Decimal>(row, "unit_price", Price1); //assigns Price1 to the unit_price field
                                }
                                else
                                {
                                    if (bDebugMode) MessageBox.Show("Unit Price" + Unit, "Debug", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); //Shows Unit Price before assigning it to the unit_price field
                                    DataRowExtensions.SetField<string>(row, "unit_price", Convert.ToString(Unit)); //assigns Unit to the unit_price field
                                }
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Message = ex.Message;
            }
            if (bDebugMode) MessageBox.Show("Ending Price Check"); //MessageBox for debugging, shows the end of the calculations before result is returned
            return result;
        }
        public override string GetDescription()
        {
            return "Checks prices to keep Unit Price above minimum.";
        }
        public override string GetName()
        {
            return "Price Check";
        }
    }
 }
auth private
  • 1,318
  • 1
  • 9
  • 22
  • If you look at `datatable1.Columns["class_id4"].DataType` in debug, what is it? I would guess it's been mapped to a `string`, in which case you should use that for casting instead of `Char?`. A `char` type can only represent a single character. – steve16351 Jul 21 '15 at 21:26
  • I'm not sure if this is what you meant, but I changed the `Class4 = Convert.ToString(DataRowExtensions.Field(row, "class_id4"));` to `Class4 = (DataRowExtensions.Field(row, "class_id4"));` and now receive the error _Cannot cast DBNull.Value to type 'System.Decimal. Please use a nullable type._ – GuitarGrady Jul 21 '15 at 21:42

0 Answers0