Question

I am looking to integrate ELMAH into an existing ASP.NET application to further support error investigations and could use some help with the connection strings. We use a single web.config file for all or our environments the application is deployed in, and at runtime, the app decides which environment it is in, typically based on URL.

This is what a standard block would like like for us...

  <connectionStrings>
    <add name="TESTAppDB" connectionString="Data Source=SQL-T-APPNAME.COMPANY.COM;Initial Catalog=APPNAME;User ID=USER;Password=THEPASS" providerName="System.Data.SqlClient"/>
    <add name="CERTAppDB" connectionString="Data Source=SQL-C-APPNAME.COMPANY.COM;Initial Catalog=APPNAME;User ID=USER;Password=THEPASS" providerName="System.Data.SqlClient"/>
    <add name="PRODAppDB" connectionString="Data Source=SQL-P-APPNAME.COMPANY.COM;Initial Catalog=APPNAME;User ID=USER;Password=THEPASS" providerName="System.Data.SqlClient"/>
  </connectionStrings>

With Elmah, it appears that you just need to specify the name of the connection string, but how can I do this dynamically at runtime? For example, if I'm test, then I want this:

<elmah>
     <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="TESTAppDB"/>
</elmah>

but if I'm in PROD:

<elmah>
     <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="PRODAppDB"/>
</elmah>

EDIT
The deployment practices for web applications are well out of scope for what I am trying to do. I need a code solution that allows me to change the datasource for the ELMAH Sql Error Log...

I cannot change the way we deploy web apps today. That means, whatever is in TEST, moves to CERT. What is in CERT moves to PROD. The web app must be able to determine which environment it is in and run as such...

Was it helpful?

Solution

Since Elmah is open-source it would be easy to add your own :-)

All you would need to do was to add a new static property to the SqlErrorLog class that would contain the connection string you wanted to use and then you would update the SqlErrorLog.ConnectionString property to return your custom connection string if it had a value.

Try to add something like this to the class (warning - untested code):

public static string CustomConnectionString { get; set; }

public virtual string ConnectionString
{
  get 
  { 
    if (string.IsNullOrEmpty(CustomConnectionString)) 
    {
      return _connectionString;
    }
    else
    {
      return CustomConnectionString; 
    }
  }
}

This should be enough. Now all you must do is to find the location where you select your connection string and update it to also set the SqlErrorLog.CustomConnectionString property.

OTHER TIPS

I use a Web Deployment Project for this. You can specify a file with the connection string in it for each Configuration (Debug and Release by default). This way all your config files for all deployments have the same files and your web.config is updated appropriately for each deployment.

Scott Gu has good info here: http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx

It is for a previous release but the information still applies.

I would use one connection string name "AppDB", but actually host the connection string in an external (outside of web.config file) config file, that is different in each environment.

In your web.config:

<connectionStrings configSource="config\connectionStrings.config"/>

Then, in the connectionStrings.config file:

<connectionStrings>    
    <add name="AppDB" connectionString="Data Source=SQL-T-APPNAME.COMPANY.COM;Initial Catalog=APPNAME;User ID=USER;Password=THEPASS" providerName="System.Data.SqlClient"/>
</connectionStrings>

Then, depending on what environment the connectionStrings.config file is in, modify the connectionString. In the code, just refer to "AppDB".

To build on Rune Grimstad's answer, in addition to his changes, add:

if (connectionString.Length == 0)
    connectionString = CustomConnectionString;

after:

string connectionString = ConnectionStringHelper.GetConnectionString(config);

in the SqlErrorLog(IDictionary config) constructor.

Then I did what RSolberg did, but in application_start as opposed to session:

Elmah.SqlErrorLog.CustomConnectionString = "Your CS";

Can we use in this case Database Context?

I have a webapp in MVC 3 and I connect to database with database context (according to above example):

using (var ctx = new TESTAppDB())
{
    var res = (from p in ctx.Customer select p).FirstOrDefault();
}

Where TESTAppDB:

public class TESTAppDB: DbContext
{
    public DbSet<Customer> Customer{ get; set; }
}

If I want to connect to another database, so I write:

using (var ctx = new CERTAppDB())
{
    var res = (from p in ctx.Order select p).FirstOrDefault();
}

It seems to be correct...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top