Dev Blog - Johan Danforth
I'm Johan Danforth and this is my dev blog - a mix of .NET, ASP.NET, Rest, Azure and some other random coding stuff.
-
[PDC'05] Hollywood Boulevard
So, last night we took the metro up to Hollywood Boulevard and took a walk and a big, fat hamburger. Pretty cool to see the hand- and footprints outside the Chineese Theatre and all the stars on the boulevard. Parts of Hollywood Boulevard is actually pretty run down, I was surprised to see that. The metro works pretty well, except that you had to wait pretty long before a train came along.
Tonight we will probably walk up to Broadway and just look around.
-
[PDC'05] Pretty good start
So, the pre-conference session (Building .NET Web Services Today with .NET 2.0 and WSE 3.0) with Aaron Skonnard just ended, and it was pretty good. It didn't contain so much new stuff or wasn't as deep level as I thought it was going to be, but Aaron is a good speaker and I learned a couple of new things about WSE 3.0.
Aaron spent almost 2/3 of the day on basic WS stuff that I think most people in the room might already know about, but these are pre-conf sessions so I guess they have to be a bit basic.
Aaron did lots of coding (yay) and one funny thing was when he was going to create a demo with a web service returning datasets (which he claimed was evil). First he named the web service class 'dataset', then realized that it wasn't a very good name, so he changed it into 'webservice' which isn't that much better :) He just laughed and put a '1' after it and went ahead.
Now we're off to see some parts of Hollywood I think...
-
[PDC'05] Cute little 9 guy
Oh, forgot to mention that there was a soft little 9 guy in the bag too :) Like this one:
Maybe I can put it next to my display and use it as a 'display-brick' when I get mad at something. I usually throw away CDs and DVDs, and they break so easily...
-
[PDC'05] Just arrived at the conference center
Just checked in at the conference center and got my stuff: a bag (not a rucksack this time) which looks pretty good, a pretty simple gray kind of t-shirt with the PDC 'logo' on it and some magazines and stuff. Seems we have to wear these plastic bracelets (nice purple color) for the pre-conference sessions.
The WLAN seems to working OK, just got connected with my PocketPC at once. Right now I'm standing in the big hall where they got thousands of PC hocked up to the Net, waiting for breakfast being served. I'm hungry!!
The trip to LA took something like 18 hour all and all. I got up at 4am in Sweden, switched plane in Frankfurt, Germany (2 hours flight) and landed some 11 hours later in LA. Staying at the LA Sheraton Downtown on the 16th floor. The room is large and pretty good. I managed to stay awake til 7 or 8 in the evening before I passed out. Woke up really early, around, and at 6 my wife called :)
Going to spend the day at the Web Services pre-conference session (Building .NET Web Services Today with .NET 2.0 and WSE 3.0) with Aaron Skonnard. It's be interesting and great fun I hope. Write about that later.
-
Das Keyboard, a precision keyboard that says who you are
Have to have one! :D
Not only is it equipped with 100% blank (!) keys, all keys also have individually weighted keyswitches, ranging from 35 grams to 80 grams.
-
Writing to Oracle CLOB fields using System.Data.OracleClient - shoot me down please
If you're a .NET coder and does database stuff against Oracle, this is your chance to put things right :) Keep reading and add comments please!
In one of our current projects we need to write large chunks of text to an Oracle CLOB field from an ASP.NET 1.1 application. We've been using the standard Microsoft System.Data.OracleClient libraries so far (to write smaller amounts of data) and it has worked out quite well for us. I didn't want to introduce another library pack like the Oracle ODP.NET even though the later versions of that pack may work very well.
In older Java projects I've been writing and reading CLOBS and I know you have to handle those fields a bit different than normal VARCHARs and such. So I sat down and started to search the .NET Dynamic Help and whatever I could find on the Internet, and the funny thing is I found three different ways of doing it; 2 really simple and one not so simple. The weird thing is that I don't think the first two options is supposed to be working - but when I test them they work just fine. I'll publish the 3 ways here, and hopefully someone who knows what he's doing with .NET and Oracle can shoot me down in flames. I just want to do the right thing here.
To test this, I have created a simple table in Oracle, which consists of 2 fields; ID (INT) and TEXT (CLOB). That's it. I'm reading a simple text-file created with Notepad, which is 499 KB in size.
NOTE: This is just test-code, nothing you'd want to have in production. If you decide to use some of this code, please add proper error, exception and transaction handling to it.
So, first way of doing it using an OracleDataAdapter, is (if I understand the Class Library docs) not supposed to be working. But it does:
public void writeDataWithDA()
{
FileInfo fi = new FileInfo("c:/temp/testfile.txt");
StreamReader sr = new StreamReader(fi.FullName);
String clob = sr.ReadToEnd();
sr.Close();
OracleDataAdapter da = new OracleDataAdapter("SELECT ID, TEXT FROM CLOBTEST",ConnectionString);
DataTable dt = new DataTable();
// get the schema
da.FillSchema(dt, SchemaType.Source);
OracleCommandBuilder cb = new OracleCommandBuilder(da);
int id = 2;
// create a row containing the data
DataRow row = dt.NewRow();
row["ID"] = id;
row["TEXT"] = clob;
dt.Rows.Add(row);
// update the table
da.Update(dt);
}
The second way of doing it uses an OracleCommand and is also not supposed to be working (I think), but it does:
public void writeDataWithCommand()
{
FileInfo fi = new FileInfo("c:/temp/testfile.txt");
StreamReader sr = new StreamReader(fi.FullName);
String tempBuff = sr.ReadToEnd();
sr.Close();
using(OracleConnection conn = new OracleConnection(ConnectionString))
{
conn.Open();
Console.WriteLine("Connected...") ;
String strSQL = "INSERT INTO CLOBTEST (ID,TEXT) VALUES (1,:TEXT_DATA) ";
OracleParameter parmData = new OracleParameter();
parmData.Direction = ParameterDirection.Input;
parmData.OracleType = OracleType.Clob;
parmData.ParameterName = "TEXT_DATA";
parmData.Value = tempBuff;
OracleCommand cm = new OracleCommand();
cm.Connection = conn;
cm.Parameters.Add(parmData);
cm.CommandText = strSQL;
cm.ExecuteNonQuery();
conn.Close();
}
Console.WriteLine("Done!") ;
}
Now comes the third way of doing it. This is how the .NET Class Library documentation describes C/BLOB handling, by creating a temporary LOB object in Oracle and then write to that object before inserting in into the table. This also works fine, but it requires a bit more hassle with transactions and stuff:
public void writeWithTempBlob()
{
FileInfo fi = new FileInfo("c:/temp/testfile.txt");
StreamReader sr = new StreamReader(fi.FullName);
String tempBuff = sr.ReadToEnd();
sr.Close();
using(OracleConnection conn = new OracleConnection(ConnectionString))
{
conn.Open();
Console.WriteLine("Connected...") ;
OracleTransaction tx = conn.BeginTransaction();
OracleCommand tempcmd = conn.CreateCommand();
tempcmd.Transaction = tx;
tempcmd.CommandText = "declare xx clob; begin dbms_lob.createtemporary(xx, false, 0); :tempclob := xx; end;";
tempcmd.Parameters.Add(new OracleParameter("tempclob",
OracleType.Clob)).Direction = ParameterDirection.Output;
tempcmd.ExecuteNonQuery();
//get the temp lob object
OracleLob tempLob = (OracleLob)tempcmd.Parameters[0].Value;
//transform into byte array
System.Text.Encoding enc = Encoding.Unicode; //MUST be unicode encoded!
Byte[] b = enc.GetBytes(tempBuff);
tempLob.BeginBatch(OracleLobOpenMode.ReadWrite);
tempLob.Write(b,0,b.Length);
tempLob.EndBatch();
OracleCommand cmd = conn.CreateCommand();
cmd.Transaction = tx;
cmd.CommandText = "INSERT INTO CLOBTEST (ID, TEXT) VALUES (:ID, :TEXT)";
cmd.Parameters.Add("ID", 3);
cmd.Parameters.Add("TEXT", OracleType.Clob).Value = tempLob; //insert the temp lob
cmd.ExecuteNonQuery();
tx.Commit();
}
Console.WriteLine("Done!") ;
}
Note that to write to the temporary CLOB, the text must be unicode or you will just get a mess of characters written :)
So, since all three ways seems to be working just fine for me, what is the right way of doing this? Load your gun and fire away...
-
PDC05 Road Trip - Episode 3
-
PDC05 Road Trip - Episode 2
-
[.NET 2.0] A must-know for ASP.NET 2.0 developers
I spent a couple of hours trying to figure out what was wrong with my Master/Details test form, when I ran upon this one. ASP.NET 2.0 doesn't seem to rebind after a PostBack if there is a ViewState available. Even if cache is turned off on the data source. Fritz wrote about this.
Need to test this a bit more. Amazing how much there is to learn about .NET 2.0. My first thoughts about the new release was "yeah, it'll be cool changes to the IDE, refactoring and all that, then there'll be great additions to the c# language and a cart-load of new controls". But this is a change in ASP.NET programming model, isn't it? A small change, but nevertheless quite important, don't you think?
-
[Java] WSS4J version 1.0
Sorry for all the Java spamming today, but if anyone interested in the Apache Axis and Web Service Security area, the Apache WSS4J people got a version 1.0 ready for download and use now.
You can get to their site here. They got some pretty good documentation available now it seems. I believe you should be able to learn from my wss4j tutorial, based on the earlier version of wss4j. I posted a follow-up to that tutorial here.
I'll download the latest version of wssj4 myself and give it a try now, because we're most probably going to use it in the near future. Jeez, I need to get more time to look at the ASP.NET 2.0 stuff too... Argh...