Question

I have sinned on so many levels. I'm hoping someone can tell me a better way to re-write this c#.

I was given a task to modify a section of the web.config at runtime to remove a piece of the subject for an elmah error email and inset the box name.

the reason is we can't trust our cm folks to get these right consistantly and so we waste time debugging errors on the wrong box.

so with that uglyness ahead of me i started writing...

here is the section in the web.config I'm trying to modify

 <elmah>
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/ELMAH"  />
    <errorMail from="..." to="..."
      subject="Application: EditStaff_MVC,  Environment:Dev, ServerBoxName: AUST-DDEVMX90FF"
      async="true" />
  </elmah>

here is the code.

private void UpdateElmahErrorEmailSubject( string appPath )
{
    string machineName = System.Environment.MachineName;

    //System.Collections.IDictionary config = ( System.Collections.IDictionary ) ConfigurationManager.GetSection( "elmah" ); ;
    //System.Configuration.Configuration config2 = ( System.Configuration.Configuration ) ConfigurationManager.GetSection( "elmah/errorMail" );

    System.Configuration.Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration( appPath );
    if ( config == null )
    {
        return;
    }

    ConfigurationSectionGroup sectionGroup  = config.GetSectionGroup( "elmah" );
    ConfigurationSection section            = config.GetSection( "elmah/errorMail" );

    // i was not able to get directly to the subject, so I had to write it as xml
    string s = section.SectionInformation.GetRawXml();

    string search = "ServerBoxName:";

    //here is where i started to feel dirty, direct string parsing.
    int startIndex      = s.IndexOf( search );
    int endIndex        = s.IndexOf( "\"", startIndex );
    string toReplace    = s.Substring( startIndex, ( endIndex - startIndex ) );
    s                   = s.Replace( toReplace, search + " " + machineName );

    section.SectionInformation.SetRawXml( s );

    config.Save();
}

can anyone get around the string parsing. I tried getting to it as xml, but still wound up string parsing the subject. Is there a better way?

Thanks,

Eric-

Was it helpful?

Solution

Use a Factory method to dynamically create an HttpHandler at runtime. Create a custom variant of the HTTPHandler that you need as ELMAH from what I know last time I used is a set of HTTP Handlers.

Look at this example:

http://www.informit.com/articles/article.aspx?p=25339&seqNum=5

OTHER TIPS

Modifying the configuration XML at run-time sounds like a bit of an overkill for what you would like. Instead I would use hooks already built into ELMAH. For example, ELMAH fires events when sending error mails. I would recommend reading the Customizing ELMAH’s Error Emails blog entry by Scott Mitchell for some background. You could write a handler for the Mailing event in your Global.asax to manipulate the subject line when the mail has been prepared but before ELMAH sends it out. I would also patch the relevant part of the subject using Regex as demonstrated in the following example (it's more robust than searching the string, indexing and replacing a portion yourself):

void ErrorMail_Mailing(object sender, Elmah.ErrorMailEventArgs args)
{
    args.Mail.Subject = 
        Regex.Replace(args.Mail.Subject, 
                      @"(?<=\bServerBoxName *: *)([_a-zA-Z0-9-]+)", 
                      Environment.MachineName);
}

Load it as XML and pull subject, then parse the subject with String.Split twice, the first by ",", then each resulting string by ":". You'll get a list of arrays like:

First split: Array 0 Application:EditStaff_MVC 1 Environment:Dev 2 ServerBoxName:AUST-DDEVMX90FF

Second (inner) split: Array 0 Application 1 EditStaff_MVC

On the second split, if the first value is ServerBoxName then rewrite the second value with your machineName. Rebuild the string as you go.

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