Ho peccato .. Web.config riscrivendo in fase di esecuzione ... per elmah
Domanda
Ho peccato su così tanti livelli. Spero che qualcuno possa dirmi un modo migliore per riscrivere questo c #.
Mi è stato assegnato il compito di modificare una sezione di web.config in fase di esecuzione per rimuovere una parte dell'oggetto per un'e-mail di errore elmah e inserire il nome della casella.
il motivo è che non possiamo fidarci della nostra gente di cm per ottenere questi giusti coerentemente e quindi perdiamo tempo a eseguire il debug degli errori nella casella sbagliata.
quindi con quella bruttezza davanti a me ho iniziato a scrivere ...
ecco la sezione nel web.config che sto cercando di modificare
<elmah>
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/ELMAH" />
<errorMail from="..." to="..."
subject="Application: EditStaff_MVC, Environment:Dev, ServerBoxName: AUST-DDEVMX90FF"
async="true" />
</elmah>
ecco il codice.
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();
}
chiunque può aggirare l'analisi della stringa. Ho provato a farlo come xml, ma ho comunque finito la stringa analizzando il soggetto. C'è un modo migliore?
Grazie,
Eric -
Soluzione
Utilizzare un metodo Factory per creare dinamicamente un HttpHandler in fase di esecuzione. Crea una variante personalizzata di HTTPHandler che ti serve come ELMAH da quello che so l'ultima volta che ho usato è un set di gestori HTTP.
Guarda questo esempio:
http://www.informit.com/articles/article aspx p = 25339 & amp;? seqNum = 5
Altri suggerimenti
La modifica dell'XML di configurazione in fase di esecuzione sembra un po 'eccessiva per quello che vorresti. Invece userei ganci già integrati in ELMAH. Ad esempio, ELMAH genera eventi durante l'invio di messaggi di errore. Consiglio di leggere le Personalizzare le email di errore di ELMAH post di blog di Scott Mitchell per alcuni retroscena. Puoi scrivere un gestore per l'evento Mailing
nel tuo Global.asax
per manipolare la riga dell'oggetto quando la posta è stata preparata ma prima che ELMAH la invii. Vorrei anche rattoppare la parte pertinente del soggetto usando Regex
come dimostrato nell'esempio seguente (è più robusto della ricerca della stringa, dell'indicizzazione e della sostituzione di una porzione):
void ErrorMail_Mailing(object sender, Elmah.ErrorMailEventArgs args)
{
args.Mail.Subject =
Regex.Replace(args.Mail.Subject,
@"(?<=\bServerBoxName *: *)([_a-zA-Z0-9-]+)",
Environment.MachineName);
}
Caricalo come XML e estrae l'oggetto, quindi analizza l'oggetto con String.Split due volte, il primo con ", " ;, quindi ogni stringa risultante con ": " ;. Otterrai un elenco di array come:
Prima divisione: schieramento 0 Applicazione: EditStaff_MVC 1 Ambiente: Dev 2 ServerBoxName: AUST-DDEVMX90FF
Seconda divisione (interna): schieramento 0 Applicazione 1 EditStaff_MVC
Nella seconda divisione, se il primo valore è ServerBoxName, riscrivere il secondo valore con machineName. Ricostruisci la stringa mentre procedi.