locked
Specified Cast is not Valid RRS feed

  • Question

  • I am checking the size of a directory and then getting the total value of the column in the database for that directory


    public static long GetCurrentSize(bool onlyUser, int companyId)
            {
                long ret = 0;
                SqlDataSource ds = Database.GetDataSource();
                if (onlyUser)
                {
                    ds.SelectCommand = "_CheckUserBoxSize";
                    ds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure;
                    ds.SelectParameters.Add("CompanyID", DbType.Int32, companyId.ToString());
                }
                else
                {
                    ds.SelectCommand = "_CheckSharedBoxSize";
                    ds.SelectCommandType = SqlDataSourceCommandType.StoredProcedure;
                    ds.SelectParameters.Add("CompanyID", DbType.Int32, companyId.ToString());
                }
                IEnumerator i = ds.Select(System.Web.UI.DataSourceSelectArguments.Empty).GetEnumerator();
    
                while (i.MoveNext())
                {
                    DataRowView d = (DataRowView)i.Current;
                    ret += Database.GetRowViewValue<long>(d, "Total");
                }
                return ret;
            }
    IT fails on this. saying Specifed Cast is not valid i need help asap on this THanks


    public static T GetRowViewValue<T>(DataRowView d, string ColName)
            {
                if (d != null || d[ColName] != System.DBNull.Value)
                    return (T)d[ColName];
                else
                    return default(T);
            }



    Monday, March 5, 2012 3:27 PM

Answers

  • Run the code with a debugger to see what the actual type is.  It could be an int, a string, a decimal, double, etc.
    • Proposed as answer by MarcD Monday, March 5, 2012 8:00 PM
    • Marked as answer by Snake3ite Monday, March 5, 2012 8:03 PM
    Monday, March 5, 2012 3:50 PM

All replies

  • Hi,

    what is the value type of "Total" column?


    Bilhan silva

    Monday, March 5, 2012 3:37 PM
  • The value is going to the be the total size of every file in the directory
    Monday, March 5, 2012 3:46 PM
  • Run the code with a debugger to see what the actual type is.  It could be an int, a string, a decimal, double, etc.
    • Proposed as answer by MarcD Monday, March 5, 2012 8:00 PM
    • Marked as answer by Snake3ite Monday, March 5, 2012 8:03 PM
    Monday, March 5, 2012 3:50 PM
  • Its a long on the

    return (T)d[colname];

    Monday, March 5, 2012 3:57 PM
  • Are you sure it's not a DBNull? Your condition is using an OR instead of an AND:
    if (d != null && d[ColName] != System.DBNull.Value)

    • Proposed as answer by servy42 Monday, March 5, 2012 5:14 PM
    Monday, March 5, 2012 5:05 PM
  • Quite often it is a Decimal that is trying to be converted tosomething else (e.g. double, single/float, etc).

    servery42's suggestion of using a debugger is probably best bet for this.

    Monday, March 5, 2012 5:17 PM
  • Quite often it is a Decimal that is trying to be converted tosomething else (e.g. double, single/float, etc).

    servery42's suggestion of using a debugger is probably best bet for this.

    I thought the same thing ;)

    The prompt reply however confirms that the value really is a long, thus Louis' answer is more likely to be correct.

    Monday, March 5, 2012 6:45 PM
  • if ((d!=null) && ((d[ColName]!=System.DBNull.Value) && (d[ColName]!=null))
       { return (T) d[ColName]; }

    A Cell can have DbNull.Value OR null and this may be the reason for the typecast error.

    After making the above change to the code and you still have the problem, then verify what type d[ColName] is AND what type T is when it's throwing the exception.



    • Proposed as answer by MarcD Monday, March 5, 2012 8:00 PM
    • Edited by MarcD Tuesday, March 6, 2012 5:36 PM
    Monday, March 5, 2012 6:50 PM
  • I think i may have figured it out the columns it is pulling as the total are ints and im trying to get them as a long so i changed that and it seems to work.
    Monday, March 5, 2012 6:52 PM
  • You're making the same mistake as the OP. The condition

    d[ColName] != DBNull.Value || d[ColName] != null

    is always true.

    I wonder in which case d[ColName] can contain null.

    Tuesday, March 6, 2012 4:46 PM
  • Me too...

    If d is null is all else too, dont you think Snake?


    Mitja

    Tuesday, March 6, 2012 4:48 PM
  • Ahh , thanks for pointing that out. Fixed. I normally check and return null first so that's what my brain was thinking when I wrote it.

    DataRow cells can contain null depending upon who filled them and how they were filled.

    From my extensive experience I've seen Datarow have null instead of DbNull enough times to know to ALWAYS check for both because sooner or later it ends up biting you in the butt.

    I just honestly recommend it to everybody as good practice.


    • Edited by MarcD Tuesday, March 6, 2012 5:40 PM
    Tuesday, March 6, 2012 5:38 PM
  • DataRow cells can contain null depending upon who filled them and how they were filled.

    If the type of a column is a value-type, you cannot put null in it. If it's a reference-type, no need add a check, returning null from the row, or returning null by using default(T) doesn't make a difference.

    Wednesday, March 7, 2012 10:06 AM
  • DataRow cells can contain null depending upon who filled them and how they were filled.

    If the type of a column is a value-type, you cannot put null in it. If it's a reference-type, no need add a check, returning null from the row, or returning null by using default(T) doesn't make a difference.

    Your statement makes no sense. DataRow returns data from Databases or anything else from around the world. None of which adhere to or are aware of C#.NET rules.

    DataRow ["Column"] returns an Object.

    Therefore it is completley possible to be EXPECTING an Int32 BUT Instead get a DbNull.Value or a Null, depending upon who or how the DataRow was filled.

    Which is why I said, "as good practice" I recommend everybody always checks for both all the time because its easier to check all the time then remember the scenarios that you do or don't have to and hope to god that that a scenario where you decided "you didn't have to" gets used in a situation where suddenly it becomes a "has to"

    E.g. If you always query against MS SQL and the code that youwrote now queries against a custom data provider that are filled by non-db many of which DO not have to conform to using DbnNull.

    In the general interests of writing good code that breaks less often, my advice stands, you should always check for both because it is 100% practical that you can get a Null.

    if ((Value==DBNull.Value) || (Value==null))

    Case In point: This code pulled from an ORM that I use. Visual Studio tells me that ALL code paths have been taken (aka it is highlighted light blue).
    Value comes DIRECTLY from a DataRow. If all values had been DbNull.Value or NOT DbNul.Value (but not null ) it would be highlighted a sick peach yellow.

    This means that while querying against MS SQL the DataRow has returned cells that have contained non-null values, DbNull.values and NULL values.

    • Edited by MarcD Wednesday, March 7, 2012 3:39 PM
    Wednesday, March 7, 2012 3:35 PM
  • Since the indexer of DataRow is not virtual, it's not possible to change its behavior. ItemArray isn't virtual either. That's why I thought that it's not possible to put a null in a column with a DataType defined as a value-type.

    I'd like to investigate how exactly that "anything else" does what you describe. Do you have a concrete example?

    Wednesday, March 7, 2012 5:28 PM
  • DataColumn does not ensure that DbNull is always returned. It is the responsibility of an internal class called DataStorage.

    DataStorage contains 3 constructors 2 of which allow somebody who has access to instantiating DataStorage to specify what value represents "null" value.

    So it still remains best practice to always check for both if there is possibility of it being null and there is.

    Life has always taught me it's better to be safe than sorry. What you choose to do is your own choice.

    Wednesday, March 7, 2012 6:07 PM