FoxPro character fields in .Net showing as blank strings.

Not sure if this should be in the FoxPro forum, or the C# forum.

I have a dBase database, with a table (table1).
table1 contains a field (myField) which is a fixed length, 4-character field.

With each record this field contains 4 ASCII characters (which were created by converting decimal values into ASCII).
Now ... I think that the first 2 or 3 characters are ASCII value 0 (null).

Also, some of them contain Extended ASCII codes.

My problem

the object variable, thisField in my code returns contains an empty text string.

I have tried casting it to different types, and have interrogated the field output in every way. Visual Studio is telling me that the field contains a blank string ("")

Now, I have loaded the table in FoxPro 9 .. and the data IS there.
(e.g. 4 characters... null null null "#")

But I can't get to it.

Any suggestions please

My code is below:


// Initialize database connection.
OleDbConnection _connection = new OleDbConnection( @"Provider=VFPOLEDB.1;Data Source=C:\DataFolder\;");

// SQL select statement
string strSelect = "SELECT * FROM table1";

// Create data adapter, command builder and dataset
OleDbDataAdapter _dataAdapter = new OleDbDataAdapter(strSelect, _connection);
OleDbCommandBuilder _commandBuilder = new OleDbCommandBuilder(_dataAdapter);

DataSet _dataset = new DataSet();

// Fill the dataset with the data
_dataAdapter.FillSchema(_dataset, SchemaType.Source);
_dataAdapter.Fill(_dataset);


foreach(DataRow dr in _dataset.Tables[0].Rows)
{
object thisField = dr["myField"];
}


Martiankeeper



Answer this question

FoxPro character fields in .Net showing as blank strings.

  • OmegaZero

    Does

    strSelect = "select ctobin(myField,'4S') as converted,* from Table1"

    help


  • MBurks

    Alright, I'm starting to get somewhere.

    I'm wondering if I could use CAST() or RIGHT() to get something out


  • OilierThanThou

    By the way in .Net framework a string is a series of unicode characters. It's not true that ASCII = 0 shows the end of a string. That's something known as ASCIIZ string. Most of the .Net strings already have many ASCII=0 in them. ie:

    string myStr = "Hello World";

    has 11 ASCII 0s when you look at it as a unicode char array.


  • Adams

    Ok.

    Here is what I'm doing:

    (bearing in mind the field is a 4-character, fixed width FoxPro table column. and the first 3 values are almost always ASCII null)

    SELECT right(myField, 1) as converted from table1 ...
    .. returns me a string containing a single character of the values I need.

    SELECT cast( right(myField, 1) as char) as converted from table1 ...
    ... returns me a character variable of one of the values I need ...

    SELECT CTOBIN( myField, '4S' ) as converted from table1 ..
    .. returns me a decimal value of 0 for all fields.

    ...

    so ... any way of casting to an array type or perhaps simplifying this Right / Left system .. so that I don't have to extract all 4 characters individually (this table actually has about 30 identically structured fields .. so to do that would be one really big SQL statement )

    thanks so far!

    Martin


  • patrick_pasha

    Ok, I've done some research into this.

    In the dotNetFramework (and VB6, and C/C++) .. a string is:

    "an array of unicode characters, terminated by a null unicode character (ASCII = 0)"

    Hence my predicament ...

    The dotNetFramework recieves the character array from FoxPro ...
    it interrogates it, and finds the first character is unicode null.
    Therefore it treats it as a string variable .. and sends back a blank string.

    This has me rather up a creek without a paddle.

    Any suggestions anyone


  • Chris Dodd

    I remember another thread someth ng like encrypted data and I think this one is related.

    An 32 bit integer is four bytes and in memory it's stored in right to left format (check little endian,big endian). In VFP you can store any combination of ASCII chars to a string (from ASCII 0 to 255). For integers there are some conversion functions which convert from BinaryToCharacter ( BinToC ) and from CharacterToBinary ( CToBin ). Also with those functions you might choose to store/restore in righttoleft format or lefttoright format.

    What you say (null null null #) is 00 00 00 23. If you get that value as Big Endian then it's 35 else 587202560 (x86 uses little Endian however in VFP you might choose as you see fit). Also in VFP there is one another storage again using BinToc.

    CToBin( myField, '4S') or CToBin( myField, '4RS') or CtoBin( myField ) should give you the correct values (table designer woud know which one - you might discover checking against known good values).

    Normally such fields should be marked with NoCpTrans ( no codepage translation ) but as I understand they are not::( If you can do that first alter table structure so those fields are "character binary" not just "character". Assuming you did that part .Net would see them as byte arrays w/o anything to do on your part, and you could directly read. ie: Reading first 3 columns would look like:

    using System;
    using System.Data;
    using System.Data.OleDb;

    class myClass
    {
    static void Main()
    {
    string strCon = @"Provider=VFPOLEDB;Data Source=c:\myPath\myDatabase.dbc";
    string strSelect = "select * from myTable";

    using (OleDbConnection cn = new OleDbConnection(strCon))
    {
    OleDbCommand command = new OleDbCommand(strSelect,cn);
    cn.Open();

    OleDbDataReader rdr = command.ExecuteReader();
    while (rdr.Read())
    {
    Console.WriteLine("{0}\t{1}\t{2}",
    BitConverter.ToInt32((byte[])rdr[0],0),
    BitConverter.ToInt32((byte[])rdr[1],0),
    BitConverter.ToInt32((byte[])rdr[2],0));
    }
    rdr.Close();
    }
    }


  • Rishi Khetan

    If you can do that first alter table structure so those fields are "character binary" not just "character"


    Ok ... awesome.

    I have made that change .. and I can now see the binary values in .Net. Which is fantastic.
    My only problem is .. these values are stored in a database in use by another application.
    I don't know if I can modify the data structure without their permission (and as it was written, and is supported, by another developer ... I doubt that I can).

    So ... this I guess is the crux of my question:

    Can I convert from Character to Character-Binary, in Code .. either through C# or the SQL code

    Thanks a million .. this has been really helpful.


  • Jay_

    IMHO you should notify te original developer that they should really make the change. It wouldn't harm their application but better provide portability. Probably they're not aware yet it's prone to breaking when codepage of an installation changes. All character binary does is to prevent code page translations, it doesn't alter the data itself. If those fields are used as char representations of integer values one would naturally wouldn't want them to be altered by code page translations. IOW I think he would be more than pleased to give the permission and make the change. I simply can't think of a reason not to mark a field as 'binary' when my intention is to store 'binary' there:)


  • Davey400

    Yes .. I'm now starting to get integer values returned.

    But they don't make a lot of sense (compared to the previous ASCII values)

    What is the ctobin function actually doing and what data type should be returned




  • FoxPro character fields in .Net showing as blank strings.