2009-07-30 7 views
1

J'ai péché sur tant de niveaux. J'espère que quelqu'un peut me dire une meilleure façon de réécrire ce C#.J'ai péché .. Web.config réécrire à l'exécution ... pour elmah

On m'a demandé de modifier une section de web.config lors de l'exécution pour supprimer une partie du sujet pour un message d'erreur elmah et insérer le nom de la boîte. La raison en est que nous ne pouvons pas faire confiance à nos gens pour les obtenir correctement et donc nous perdons des erreurs de débogage de temps sur la mauvaise case.

donc avec ce devant moi laideur je commence à écrire ...

est la section ici dans le web.config que je suis en train de modifier

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

est le code ici.

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(); 
} 

peut-on contourner l'analyse des chaînes. J'ai essayé d'y arriver en tant que xml, mais j'ai quand même fini par analyser le sujet. Y a-t-il un meilleur moyen?

Merci,

Eric-

+1

Pouvez-vous stocker les valeurs qui sont spécifique au serveur dans le fichier machine.config du serveur? Vous devrez toujours faire confiance à vos amis pour bien faire les choses, mais une fois que c'est correct, il devrait rester juste. – BStruthers

+0

hélas, tout le point d'éviter les problèmes de Cm, donc cela les réduit mais ne les supprime pas. –

+1

Je dois vous upvote juste pour la belle mise en forme du code. Très agréable. Alignés égaux est la seule vraie façon ... –

Répondre

3

Utilisez une méthode Factory pour créer dynamiquement une HttpHandler lors de l'exécution. Créez une variante personnalisée du HTTPHandler dont vous avez besoin en tant que ELMAH d'après ce que je sais la dernière fois que j'ai utilisé est un ensemble de gestionnaires HTTP.

Regardez cet exemple:

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

1

charge comme XML et tirer sujet, puis analyser le sujet avec String.Split deux fois, la première par « », chaque chaîne résultante par « : ". Vous obtiendrez une liste de tableaux comme:

fendu Première: Tableau 0 Application: EditStaff_MVC 1 Environnement: Dev 2 ServerBoxName: AUST-DDEVMX90FF

deuxième (intérieure) divisée: Tableau 0 Application 1 EditStaff_MVC

Sur la deuxième division, si la première valeur est ServerBoxName, réécrivez la deuxième valeur avec votre nom machine. Reconstruisez la chaîne au fur et à mesure.

3

La modification de la configuration XML lors de l'exécution semble être un peu excessive pour ce que vous souhaitez. Au lieu de cela, j'utiliserais des crochets déjà intégrés dans ELMAH. Par exemple, ELMAH déclenche des événements lors de l'envoi de messages d'erreur. Je vous recommande de lire l'article de blog Customizing ELMAH’s Error Emails par Scott Mitchell pour quelque arrière-plan. Vous pouvez écrire un gestionnaire pour l'événement Mailing dans votre Global.asax pour manipuler la ligne d'objet lorsque le courrier a été préparé mais avant que ELMAH ne l'envoie.Je voudrais aussi Patch la partie pertinente du sujet en utilisant Regex comme le montre l'exemple suivant (il est plus robuste que la recherche de la chaîne, l'indexation et le remplacement d'une partie vous-même):

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