# Thursday, March 11, 2010

I love ASP.NET MVC 2 validations for client and server via annotations. Steve Sanderson's xVal is great too, but in this post I want to focus on a custom validation for MVC 2 which is frustratingly missing from the out-of-the-box validations. There is a very nice StringLengthAttribute which allows you to specify a maximum length but does not provide for a minimum length.

At first I attacked this deficiency with a regex like this:

[RegularExpression("[\\S]{6,}", ErrorMessage = "Must be at least 6 characters.")]
public string Password { get; set; }

This approach just seems clunky. Happily, while reading Scott Allen's piece on MVC 2 validation in MSDN magazine, I came across a critical reference to one of Phil Haack's blog posts which I must have overlooked.

Thanks go to Phil's easy to follow instructions on writing a custom validator for MVC 2 that will work on both client and server sides.

So here's my custom MinStringLengthAttribute and supporting code which let's me do something easier and cleaner like this:

[StringLength(128, ErrorMessage = "Must be under 128 characters.")]
[MinStringLength(3, ErrorMessage = "Must be at least 3 characters.")]
public string PasswordAnswer { get; set; }

If you really wanted to get creative, you could produce a combination of the two, but I'll leave that for another day.

Here's the code for the attribute and the required validator:

public class MinStringLengthAttribute : ValidationAttribute
{
  public int MinLength { get; set; }

  public MinStringLengthAttribute(int minLength)
  {
    MinLength = minLength;
  }

  public override bool IsValid(object value)
  {
    if (null == value) return true;     //not a required validator
    var len = value.ToString().Length;
    if (len < MinLength)
      return false;
    else
      return true;
  }
}

public class MinStringLengthValidator : DataAnnotationsModelValidator<MinStringLengthAttribute>
{
  int minLength;
  string message;

  public MinStringLengthValidator(ModelMetadata metadata, ControllerContext context, MinStringLengthAttribute attribute)
    : base(metadata, context, attribute)
  {
    minLength = attribute.MinLength;
    message = attribute.ErrorMessage;
  }

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
  {
    var rule = new ModelClientValidationRule
    {
      ErrorMessage = message,
      ValidationType = "minlen"
    };
    rule.ValidationParameters.Add("min", minLength);
    return new[] { rule };
  }
}

Here's the code in the Global.asax.cs that registers the validator:

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);
  DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MinStringLengthAttribute), typeof(MinStringLengthValidator));
}

Here's the javascript to hook up the client side:

Sys.Mvc.ValidatorRegistry.validators["minlen"] = function(rule) {
  //initialization
  var minLen = rule.ValidationParameters["min"];

  //return validator function
  return function(value, context) {
    if (value.length < minLen) 
      return rule.ErrorMessage;
    else
      return true;  /* success */
  };
};

Now, in your view, add <% Html.EnableClientValidation(); %> and that's all there is to it.

posted on Thursday, March 11, 2010 1:21:29 PM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Friday, February 05, 2010

Documentation neglect is a chronic problem in most enterprise application development efforts. This problem is unrelated to the selected development methodology but there are some who assume that agile methods eliminate documentation despite the agile manifesto's declaration that we value "working software over comprehensive documentation." It does not claim that documentation is not needed.

In my own work, I've found that comprehensive documentation authored by well meaning individuals, or worse a committee, who possess very little technical expertise, is often written in confusing, lengthy narrative style that requires a linguistic anthropologist to decipher. Too often development teams spend days pulling out the real features and requirements and expected behavior from such documents, generally resulting in many unanswered questions, the answers to which just cannot be found in the comprehensive documentation.

Recently we have found greater value in documentation that has relatively strict structures that guide authors to produce specific, detailed and comprehensible documentation. The format is simple and adopted from the increasingly popular behavior driven design (BDD) approach.

The goal of this approach is to define desired behavior and clear acceptance criteria for specific requirements without mashing them all together in a narrative style that requires time consuming decomposition. Here's the format:

+++++++++
P[n]: Process Title
Two line description of a process (akin to epic user story)

F[n]: Function Title (a feature or step in the workflow)
As a role
I want action/process description
so that benefit/value of feature.

AC[n]: Acceptance Criteria or Scenario Title (p1)
Given some initial context (the givens),
when an event occurs,
then ensure some outcomes.

+++++++++

It's really not different than BDD. There is only one subtle difference which I've found can make all the difference in the world. the terms used (process, function and acceptance criteria) are far less scary to the business than terms like epic, user story and scenario.

Of course, this won't work for every situation, but where you can break documentation down into logical units that focus on one feature, one thing at a time, you can eliminate the time consuming deconstruction of comprehensive documentation that can only be processed by the most advanced computer in the world: the human brain.

posted on Friday, February 05, 2010 3:33:35 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Wednesday, January 06, 2010

This log helper class seems to get used over and over again in projects I've worked on. Generally I use it as a fallback, calling it from an exception block in a application logging code. Let me know if you find it helpful.

public static class LogHelper
{
  public static bool WriteEventLogEntry(string source, EventLogEntryType entryType, int eventId, string message)
  {
    bool passFail = true;
    try
    {
      if (!EventLog.SourceExists(source))
      {
        EventLog.CreateEventSource(source, "Application");
      }
      EventLog elog = new System.Diagnostics.EventLog();
      elog.Source = source;
      elog.WriteEntry(message, entryType, eventId);
    }
    catch
    {
      passFail = false; //this method is usually called as a last resort, so there can be no real exception handling
    }
    return passFail;
  }
}
posted on Wednesday, January 06, 2010 3:01:07 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Saturday, December 12, 2009

This is an oddity with Visual Studio 2010 Beta 2 installed on the a virtual machine that I’ve run into that perhaps one in a hundred other VMWare Workstation users might run into. I’m running VMWare Workstation 6.5.3 on a Windows 7 x64 box with 8GB of RAM. In turn, I’m spinning up a Windows 7 x64 virtual machine with 3GB of RAM and two cores (a primary reason for buying the VMWare license over Virtual PC). And of course, I had 3D graphics acceleration turned on, because who wouldn’t want some acceleration, right?

But here’s what the New Project dialog and other “add” dialogs looked like (note: I’ve reduced the size of these as the nitty gritty details are not as important as the visualization of the controls, here you don’t see them and later you will):

vmvs1

Note the black (or rather dark blue) abyss at the bottom of the dialog. As near as I can tell, the normally light blue section was gone and inaccessible visually. I’m not certain, but I surmised that it was still there as I was able to tab into the darkness and then out of it again.

After trying various Windows 7 video personalization settings, I then tried increasing video memory in the VMX file, but that was a non-starter. Then an odd hunch led me to try this:

vmvs2

Once I saved that 3D graphics setting unchecked and spun up the virtual machine, I noticed two things. First, the virtual machine seemed more responsive. Second, and more importantly, controls were back in sight. This pleasing view is now what I see (minus my crudely drawn red circle of course):

vmvs3

There was a moment when I thought to blame Visual Studio 2010 Beta 2 for this anomaly but of course some brief thought and sparing a brain cell or two for reasoning and cognitive function resulted in the conclusion that something with video driver and perhaps Windows 7 or Windows in general or just my machine did not like some video setting. Happily, the 3D graphics checkbox was the first thing I tried to disable on the VMWare settings and shazam, it worked.

If you run VMWare Workstation and have problems with Visual Studio 2010 Beta 2 in your virtual machine with missing or invisible controls in certain dialogs and other UI elements, try disabling the 3D graphics option. I still highly recommend VMWare Workstation over Virtual PC, though I must admit that I have not tried Windows Virtual PC in its latest incarnation for Windows 7. The last time I tried it was in the VPC 2007 edition. If you believe the latest version has come up to par with VMWare, I’d love to hear from you.

posted on Saturday, December 12, 2009 10:50:27 AM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Friday, December 04, 2009

I’ve not used this blog for politics in the past, but I’m going to start making some exceptions where I think there is a technology tie-in. George Will’s piece on the Copenhagen summit was very interesting. I recommend that you read it. I am not a climatologist but I am a skeptic of all science based on computer models, especially models that cannot accurately predict the present observable state of a system.

The recently hacked emails of the Climate Research Unit (CRU) in Britain reveal a pattern of behavior that would be more consistent with the corrupt leaders of a cult whose proclaimed tomes of divinely inspired scripture cannot withstand scrutiny should certain facts be revealed. In the minds of the true believing disciples or the corrupt leadership of the cult, the ends justify the means. And truth is not a consideration.  

The software models and data upon which all climate change disciples rely are written by flawed human beings. Whether a software engineer expertly writes the software to implement his best understanding of the requirements of the scientist or the real scientist writes the software with a less than perfect knowledge of software engineering and design, the outcome is the same. (Hey, not even a PhD can know everything.) All software is flawed. It is the nature of our art.

Can computer models be a good thing? Sure. Especially when they work. Can they be a bad thing? Well, consider that a climate model must model the entire earth and its atmosphere. That’s a few million data points (colossal understatement). These models must have historical data. And there’s the rub. It’s not there. Not really. So we extrapolate the data using tree cores and ice cores and, wait for it, more computer models.

Any software engineer knows that such a model will be inherently complex and that complex systems are inherently flawed and that very complex systems are inherently very flawed. No software engineer will declare her (or his) faith in such a model or its output, but more importantly, they would never bet a week’s salary on it’s accuracy without full testing and confirmation against known observable data and repeatable tests. Yet, we are preparing to bet trillions of tax payer dollars on these flawed models. “Hey, Sam, keep your hands out of my pocket!”

The problem we have is that scientists have put their faith in software models and data produced by software models as the magical source of all truth and knowledge. They are either the corrupt leaders of a cult (see the CRU emails) or its blind disciples insisting on the truth of their models even when observable facts contradict and invalidate those assertions.

The climate change models and extrapolated data have become scripture. The scientists who preach daily from the pages of that holy writ are held in prophetic awe and reverence by the ignorant masses of well intentioned politicians and citizens of the earth. Except for software engineers and the “deniers” of course.

So back to the question. Can computer models be a bad thing? Yes, when the ignorant or the corrupt use them as an unquestionable, magical affirmation of their own political agenda or emotional response to the idea that man is killing the planet and that unless we do something about it, we will all die. Well nobody wants that.

Oddly, we ridicule and persecute religious nuts who do the same thing. I guess they just weren’t smart enough to get a PhD and call themselves scientists rather than prophets. Stupid nuts.

posted on Friday, December 04, 2009 10:25:26 PM (Mountain Standard Time, UTC-07:00)  #    Comments [1]
# Sunday, November 29, 2009

It turns out that using table storage in Windows Azure 1.0 is quite easily done with a minimal amount of configuration. In the new Azure cloud service Visual Studio project template, configuration is significantly simpler than what I ended up with in a previous blog post where I was able to get the new WCF RIA Services working with the new Windows Azure 1.0 November 2009 release and the AspProvider code from the updated demo.

And while the project runs as expected on my own machine, I can’t seem to get it to run in the cloud for some reason. I have not solved that problem. Since I can’t seem to get much of a real reason for the failure via the Azure control panel, I’ve decided to start at the beginning, taking each step to the cloud rather than building entirely on the local simulation environment before taking it to the cloud for test.

I started with a clean solution. No changes except to the web role’s Default.aspx page with some static text. Publish to the cloud and twenty to thirty minutes later (too long in my opinion) the page will come up, deployment is complete and the equivalent of a “hello world” app is running in the Azure cloud.

The next step I want to experiment with is the simplest use possible of Azure table storage. In the previous project, there was a lot of configuration. In this new project, there was very little. I wondered how much of the configuration from the previous project, largely an import from the updated AspProviders demo project, was a partially unnecessary legacy of CTP bits. It turns out, nearly all of it.

Here’s the only configuration you need for accessing Azure storage:

<?xml version="1.0"?>
<ServiceConfiguration serviceName="MyFilesCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="MyFiles">
    <Instances count="1" />
    <ConfigurationSettings>
      <!-- Add your storage account information and uncomment this to target Windows Azure storage. 
      <Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" />
      <Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myacct;AccountKey=heygetyourownkey" />
      -->

      <!-- local settings -->
      <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

The thumbnails sample does provide one important piece of code that does not come with the standard Visual Studio template. It goes in the WebRole.cs file and makes the use of the CloudStorageAccount class’s static FromConfigurationSetting method which returns the needed CloudStorageAccount instance. To use that method, the SetConfigurationSettingPublisher method must have already been called. Hence this code placed in the WebRole class like this:

public class WebRole : RoleEntryPoint
{
  public override bool OnStart()
  {
    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    #region Setup CloudStorageAccount Configuration Setting Publisher

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
    {
      // Provide the configSetter with the initial value
      configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

      RoleEnvironment.Changed += (sender, arg) =>
      {
        if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
           .Any((change) => (change.ConfigurationSettingName == configName)))
        {
          // The corresponding configuration setting has changed, propagate the value
          if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
          {
            // In this case, the change to the storage account credentials in the
            // service configuration is significant enough that the role needs to be
            // recycled in order to use the latest settings. (for example, the 
            // endpoint has changed)
            RoleEnvironment.RequestRecycle();
          }
        }
      };
    });
    #endregion

    return base.OnStart();
  }

  private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
  {
    // If a configuration setting is changing
    if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
    {
      // Set e.Cancel to true to restart this role instance
      e.Cancel = true;
    }
  }
}

Once you have the set the configuration setting publisher, you can use the FromConfigurationSetting method in the creation of your CloudTableClient and then check for the existence of a table, creating it if it does not already exist in your repository code. Here’s a minimal example that I used and published successfully to my Azure account.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using System.Data.Services.Client;

namespace MyDemo
{
  public class AdventureRow : TableServiceEntity
  {
    public string IpAddress { get; set; }
    public DateTime When { get; set; }
  }

  public class AdventureRepository
  {
    private const string _tableName = "Adventures";
    private CloudStorageAccount _account;
    private CloudTableClient _client;

    public AdventureRepository()
    {
      _account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
      _client = new CloudTableClient(_account.TableEndpoint.ToString(), _account.Credentials);
      _client.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
      _client.CreateTableIfNotExist(_tableName);
    }

    public AdventureRow InsertAdventure(AdventureRow row)
    {
      row.PartitionKey = "AdventurePartitionKey";
      row.RowKey = Guid.NewGuid().ToString();
      var svc = _client.GetDataServiceContext();
      svc.AddObject(_tableName, row);
      svc.SaveChanges();
      return row;
    }

    public List<AdventureRow> GetAdventureList()
    {
      var svc = _client.GetDataServiceContext();
      DataServiceQuery<AdventureRow> queryService = svc.CreateQuery<AdventureRow>(_tableName);
      var query = (from adv in queryService select adv).AsTableServiceQuery();
      IEnumerable<AdventureRow> rows = query.Execute();
      List<AdventureRow> list = new List<AdventureRow>(rows);
      return list;
    }
  }
}

Just as the StorageClient has moved from “sample” to first class library in the Azure SDK, I suspect that the AspProviders sample may already be on that same path to glory. In it’s current form, it represents something new and something old, the old having not been entirely cleaned up, lacking the elegance it deserves and will likely get either by Microsoft or some other enterprising Azure dev team.

As for me, I will continue trying to learn, one step at a time, why the Adventure code I blogged about previously will run locally but not on the cloud as expected. Who knows, it could be as simple as a single configuration gotcha, but figuring it out one step at a time will be a great learning opportunity and as I get the time, I’ll share what I learn here.

posted on Sunday, November 29, 2009 7:13:26 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Monday, November 23, 2009

A month ago I posted the results of some experimentation with the preview bits of what was then called .NET RIA Services, Silverlight 3 and the Windows Azure with AspProvider sample code from the Azure July 2009 CTP. That was then and much has changed.

Windows Azure 1.0 and what is now called WCF RIA Services Beta have since been released. Lot’s of great changes make using these together with the new AspProvider sample in the “Additional C# Samples” download that some friendly readers shared with me. With Visual Studio 2008 SP1 and SQL Server 2008 (Express if you want) and these you’re set up to play.

WARNING: They were not lying about the WCF part when they renamed it. The default Domain Service channel is binary and they’re using Windows Activation Service (WAS). So make sure you’re Windows Features look something like this or you’re in for several hours of maddening error chasing.

advnew3

After some review of the previous effort using the July 2009 CTP and RIA preview bits, I decided starting over was the best course of action. Here’s the steps to nirvana:

  1. Create a new Silverlight Business Application called Adventure which produces Adventure.Web application as well.
  2. Add new CloudService project with WebRole called AdventureCloudService and WebRole1.
  3. Copy WebRole.cs to Adventure.Web and rename namespace.
  4. Add 3 azure refs to Adventure.Web.
  5. In the cloud service project file, replace WebRole1 with Adventure.Web and project guid with that from Adventure.Web. (There is probably a better way to do this.)
  6. The node under Roles in the cloud service project shows an error. Right click it and choose “associate” and pick Adventure.Web.
  7. Copy system.diagnostics section from WebRole1 web.config to that of Adventure.Web.
  8. Remove WebRole1 from solution and set service project as startup.
  9. Copy and new AspProviders project and sections from demo web.config into Adventure.Web, changing DefaultProviderApplicationName and applicationName="Adventure".
  10. Do the same previous steps to create/copy UserProfile class and IUserProfile with FriendlyName property too. Added to the Models directory this time. NOTE: Be sure to get the magic strings right in the UserProfile class or you will get unexpected results.
  11. Add Global.asax and AppInitializer class to it from previous project without the CreateTableFromModel calls which are no longer needed as I understand it.
  12. Drop in the code to create the admin user if it does not already exist.
  13. When I go to modify the LoginStatus.xaml which was previously LoginControl.xaml, but find the needed modification is already there. Skip this step.
  14. Just hit F5 and error is thrown.

After some lengthy research, I discovered a bug in the AspProvider's TableStorageRoleProvider.cs. When the RoleExists method is called and no roles have yet been created an exception is thrown.

AspProvider Fix Found
Replace e.InnerException in line 484 in TableStorageRoleProvider.cs with e.InnerException.InnerException. The first inner exception is another InvalidOperationException. The second inner exception is the DataServiceClientException we're looking for.

Login with admin/admin and we see Administrator displayed in the newly renamed LoginStatus area.

And we’re back to par. Download the code here (566KB).

posted on Monday, November 23, 2009 8:48:05 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Sunday, November 22, 2009

Silverlight WCF RIA Services Beta Released was released recently, replacing the preview bits I’ve been playing with. You can pick up the new beta here. I'm still using VS 2008 SP1, but I am using Windows 7, so I download directly from here.

WARNING! If you’re not on Windows 7 or Server 2008 R2, you’ll need the hotfix mentioned. If you're still on XP or Vista, let this be the final reason to upgrade and do it. You won't regret it.

I learned first about the beta release from Dan Abrams blog post. Some coolness he mentions:

  • DataSources window. Drag and drop "tables" exposed by Domain Service onto the form.
  • Simplified error handling on client and server.
  • Data model inheritence flows through the Domain Service.
  • Presentation model hides DAL model with CRUD support.
  • Optimized binary channel by default.
  • Integrated into Silverlight 4 installer.
  • Handling of compositional hiearchy in data models.
  • GAC and bin deployment, with bin taking precedence.
  • Globalization support, user state and persisted sign in with updated Business Application Template.
  • Go-Live bits for .NET 3.5 SP1 and Silverlight 3.

Another item of note is the name change with the WCF moniker. RIA Services is now part of the WCF services family along with ADO.NET Data Services. This seems like a convergence of technologies in an enterprise ready set of tools and services that will bring Silverlight into the forefront of enterprise application development and delivery.

I'll be working on pulling these new bits together and getting my "Aventure" blog sample back on track with the new Azure SDK bits and these new WCF RIA Services bits. Given the plethora of changes, I'll likely start over with fresh new project templates and pull what little customized code that might be needed from my previous blog post on the topic.

posted on Sunday, November 22, 2009 1:50:42 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Sunday, November 15, 2009

The 1.0 release of Windows Azure SDK is now available. Download and read about what’s new here. Sadly, the AspProviders sample project was not included. I spent a few hours trying to bandage it up, but it was a hopeless cause. If a new AspProviders sample is not soon forthcoming, it will be easier to write one from scratch using the new SDK and the new project templates.

Update (11/22/09) - AspProviders in Additional C# Examples: One comment and an additional private email from readers have pointed out Azure Code Samples on MSDN where you can download the "Additional C# Samples" which contatin the new AspProviders. I'll be checking out this and other samples with the new Azure SDK. Thanks to both Jason and Gerold for the links.

When I tried to run my old project, after modifying some references to match those of a fresh project created with the new Visual Studio templates, the first thing that popped was a new local storage database script dialog result:

az-nov09-01 

I’ve not explored them in detail but there are several new tables, some stored procedures and a few user defined functions in the new dev storage database.

I clicked okay and before I got my next error, I noticed the new baloon dialog name for the dev fabric, Windows Azure Simulation Environment:

az-nov09-02

I also compared the csCFG and and csDEF config files for the Azure cloud service project. The XML namespace is the same and as near as I can tell there are no changes there.

The next thing I noticed was a new class in the web role of the new project template. Seems we now have a “Windows Service”-like OnStart and RoleEnironmentChanging set of startup and status change event handlers. This will be highly useful for web role applications that may have resource cleanup needs.

public class WebRole : RoleEntryPoint
{
	public override bool OnStart()
	{
		DiagnosticMonitor.Start("DiagnosticsConnectionString");

		// For information on handling configuration changes
		// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
		RoleEnvironment.Changing += RoleEnvironmentChanging;

		return base.OnStart();
	}

	private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
	{
		// If a configuration setting is changing
		if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
		{
			// Set e.Cancel to true to restart this role instance
			e.Cancel = true;
		}
	}
}

Another bit of great news is that the StorageClient goes from “sample” project to part of the release libraries. There were ample changes there which appear to have broken the AspProviders sample project severely. While that explains the missing AspProviders project disappointment, I do hope that it means the changes in the StorageClient namespace will make using Azure storage easier.

Much more to learn and blog about with the new release, but it looks as though I’ll need to start over on my “Aventure” sample. I’m glad that I don’t have loads of code to refactor to the new release. It makes starting over less painful. For those who have written large projects relying on the beta, all I can say is, “beta = subject to change.”

posted on Sunday, November 15, 2009 3:42:06 PM (Mountain Standard Time, UTC-07:00)  #    Comments [1]
# Wednesday, October 21, 2009

A very long time ago, I wrote a little helper class clone of SqlHelper for Oracle which I called OraHelper. I haven’t looked at or touched the code in years, but I regularly get email asking where it’s gone to. It appears that the www.asp.net community gallery still refers to it but their link is broken. Rather than attempt to get them to fix the link, I’m posting it here.

Download OraHelper (12KB) here.

I don’t know how well this code works anymore. I’ve no Oracle database against which I can test it. I recall that one inquirer indicated that he wanted the code because he was limited to the .NET Framework 1.1. I found that rather sad to think about given how comfortable I’ve become with generics and lambdas of late.

For those of you who are doing .NET database access to Oracle, you may be helped even more by looking at Oracle’s .NET Developer Center. I can’t speak for the state of their current support. Perhaps there are readers that could post more informed comments on the subject here.

posted on Wednesday, October 21, 2009 9:05:51 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]