More Log4Net Goodies

Well I can now say, I have done more with log4net in 3 days than what I have ever done with it in the past 3 years.

There was one final hiccup I encountered that was more of an aesthetic/dry-code issue versus just a problem.  For database logging I didn’t want to have to key my connection string twice.

Found this article that gave me exactly what I wanted.  Until then, waiting for 1.2.11

Log4net and Database Logging

Important lesson here -> when you’re having issues AND you have the source code, use it.  I’ve been beating myself up on this one for the better part of an hour.  After discovering a well-formed xml configuration that had invalid nodes, it turns out the Xml datatype in log4net can cause issues.  Turns out that any variable length datatype (ie, strings) will cause SqlCommand fits if the size is not defined from the beginning.  Remember that when you are using a variable length data type to explicitly set the size in your log4net properties otherwise you’ll be lost and wondering as to why your logs never made it to the database.

Log4Net Debugging

I’m working  on a project that requires multiple layers of logging.  Logging to the file is the most obvious as well as the console.  Then there was logging to SMTP. This was alright, but the request was to beautify the email.  This was accomplished via a custom Logger.  More on that another day.

Then it was access to log to the Database.  In case you can’t tell, they really want to know how their code is functioning.  Should be easy, right?

Easy enough when you use the right datatypes.  Turns out uniqueidentifier is not a readily available term in log4net’s enumerations ( afterwards I remembered you’re after .Net datatypes, not Sql Server).  So how did I find this out? By debugging log4net.  Basically log4net can show you it’s build up and configuration by adding the following to your .net config file.  Have fun!

<appSettings>
    <add key="log4net.Internal.Debug" value="true" />
  </appSettings>
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add
         name="textWriterTraceListener"
         type="System.Diagnostics.TextWriterTraceListener"
         initializeData="c:\\log4net.txt" />
      </listeners>
    </trace>
  </system.diagnostics>

			

Knockout JS

For a while now, I’ve been reviewing different UI technologies within available web frameworks.

I’ve looked at Sprout Core, JQuery, good ol’ ASP.net MVC and really just didn’t find exactly what I was looking for in a slick and easy to ramp up Web UI that didn’t involve Silverlight or Flash.  Granted all of the above have their specific features, and strengths and to JQuery and MVC, I’m not ditching it any time soon.

I was toying around with Backbone.js but to be honest, I found the documentation kind of lacking in the community.  This may have been me, but typically I’m pretty good at finding the information I need to execute.

Enter in Knockout JS.  I’ve been following Steve Sanderson’s blog for the better part of a year for some tips and tricks (ex.  getting HTML Unit to run in .Net for headless browser automation).  I’ve been curious about Knockout and wasn’t sure.  Now he has a website devoted to the library (http://www.knockoutjs.com).  It seems pretty powerful, easy to pair with your exsiting infrastructure, and gathering a rather decent following.  I will be exploring it this week and hopefully will have some good news to share. Until then, I leave you with the following video –

Steve Sanderson on Knockout JS in 20 minutes.

 

ListBox.Items.Clear() – What it really does

I was working on a program that was using the ListBox item to do a scrolling list of items.  Essentially it was to mimic my log statements to the user.  This program was going to work as background process for a custom piece of software.  I wanted to remove the list of items with each run (set on a timer every few minutes).  I used the listbox.items.clear() method.  Turns out visually it does clear the listbox, but I was noticed I was never getting back memory as I thought I should.  After examining and searching forums and stepping through Microsoft Code, it turns out all Clear does is remove the elements from the listbox’s gui.  It still retains those items in memory.  What it does is it will essentially reuse those objects in memory for it’s next run.

So if you had 1000 items in memory the first run, and only 30 the next, you would have 1000 items still in memory until the Garbage Collector thought it was time to remove the items.  Using Ants Profiler from RedGate, it didn’t appear the Garbage collection was going to fire any time soon on that object.

If you really want the items out of memory, you must use the RemoveAt(position) method which only removes one element at a time.

FTPS Bug with .Net

This post is here to hopefully save you a couple of hours of grief.

Yes, it is completely possible to use FTPS with .Net.

Is it easy to implement when the Server you’re FTP’ing to is behind a NAT and the DNS cannot resolve the IP to the server name you are hitting?  No.  .Net is not real receptive to the notion of the fact that the IP Address you are sending the file to may not be the final destination that will send back the FTP success response.  Keep this in mind when using FTPS with .Net.  From research it appears this behavior is still a “security feature” in .Net 4.0.

Oracle Parameter Binding with Spring.Net

This is just a quick hit on a little quirk I found using Spring.Net delegates and Oracle Parameter binding.

Using the traditional method of assigning parameters using Spring’s AdoTemplate, Oracle behaves differently than SQL Server.  I should have remembered this from programming Oracle with Java.  Oracle’s default binding involves adding parameters in order of there indexes in the query.  Indexes you may ask?  Under normal configuration Oracle binds more like a String Builder where you substitute parameter values in a string for the numeric place holders.  I had hope that with Spring, I could use named parameters much like SQL Server.  It’s close. The quirk without manipulating the configuration: you can use Named parameters for readability provided you still add them in the order they appear in the query.  There is some configuration you can do to get this working out of order, but it’s not worth the hassle.

Recently, though, this named pairing failed me, when using Spring’s AdoTemplate to execute a one off query with a delegate.  I think this is in part that once in the delegate, it is leveraging System.Data.Common instead of firing off with Oracle.DataAccess.  I found that the following syntax works well.  Once again, add the parameters in the order in which they appear in the query.

Deciaml testDecimalResult = MyAdoTemplate.Execute<Decimal>(delegate(DbCommand command)
{
command.CommandText = MY_SQL_STATEMENT_TO_EXECUTE;

OracleParameter myParam = new OracleParameter(“TheParameterName”, OracleDbType.Varchar2);
myParam.Value =valueToBePassed;
command.Parameters.Add(myParam);
return (Decimal)command.ExecuteScalar();
});

Lean Oracle with Visual Studio and C#

So we’ve been doing some development at work with Spring.Net and Sql Server.  This has gone very well.  Probably due to the fact that all of our development has been within Visual Studio, and SQL Server support is nearly inseparable from the IDE.  Enter the task of Oracle integration.  Under normal circumstances, this task would not sound so daunting.  Install the full client and all of it’s 800+MB glory, reference the DLL from the GAC, and move on with life.

Now imagine a world where the typical end user doesn’t know the difference between Oracle, SQL Server, MySQL, a can of pinto beans…..  Now try telling this user they have to install this client in a particular directory, be careful not to upgrade it, or delete this random directory on their machine that doesn’t sit with their program.  Okay, I know I’ve detailed the extreme here but I think I’m making my point here. why do I need to install so many binaries on someone’s pc just to get my end client to work?

After searching several forums, I learned there is a lean way to deploy the Oracle solution.  The problem I had with a lot of these forum posts was they were not giving all of the details to solve my particular problem.

So let’s get started.

First of all, take note of whether or not you will be using the 32 binaries or the 64 bit.  This plays a big part in how your project will be able to be deployed using Visual Studio.  If you know for a fact you’re going to be going the 64 bit route, go ahead and bite the bullet now and set your visual studio project to 64 bit.  If you’re going the 32 bit route, set your targets to x86.  This is going to save you some grief down the road of relying on Visual Studio’s Any CPU option.

The trick from here now is to grab a certain subset of DLLs.  Probably the easiest way to grab these DLLs is to download the Oracle Instant Client ODP.Net installation.  Once you have installed this binary set, rename the oracle directory.  I know this sounds crazy, but this will help to guarantee you are not accidentally referencing this dll set instead of those you will be placing in your project.  (Thank you cryptic WOW64 undocumented registry key for giving me false hope so many times).

Locate the following dlls (where XX is your version number, latest release is 11 and will be about 80MB):

  • oci.dll
  • ociw32.dll
  • Oracle.DataAccess.dll
  • orannzsbbXX.dll
  • oraocciXX.dll
  • oraociicusXX.dll
  • OraOpsXXw.dll

Now place a copy of these files in a folder in your project for your own reference.  In your project, reference Oracle.DataAccess.dll.  This will be the only dll you can reference within your project.  You will probably notice that if you build the project, the first item you have accessing Oracle will fail.  The next key component is to make sure the rest of the Oracle dlls are getting dumped into the bin folder at build time.  Go to the Build Events tab on your Project’s properties page.  I place a command line value in there of copy “C:\projectname\OracleLib\*.*” “$(TargetDir)” /y where projectname\oraclelib is where the dlls are stored.  Upon a successful build this will move in the files to your bin folder appropriately.  This should prove to be successful for most of your thick client solutions.  There is still one more pitfall – using this solution in an ASP.Net application.  You may find yourself getting a Bad Image error message or Incompatible Oracle Version error.  If you are using the 64 bit Oracle dlls, you cannot debug using Visual Studio’s native Cassini web server.  This web server is only capable of loading x86 compatible binaries.  You will need to develop against a local 64 bit IIS in order to get the appropriate results.

And there you have it, a working much leaner implementation of Oracle with .Net. Enjoy!