A Quick Guida for C# (CSharp) Programmers
In questa piccolissima guida vedremo utili consigli per programmatori C#: uso dei log con Log4NET, uso di JSON, qualche utile funzione per chi ha a che fare con i file, qualche utile conversione, conversione di una stringa in valore booleano.
LOGGING
Ipotesi: abbiamo un programma C# e vogliamo loggare determinate informazioni.
Quale libreria conviene usare? In questo ambiente la più usata è Log4NET (priprio come in Java abbiamo la Log4J).
Vediamo qualche piccolo trucco/consiglio per usare al meglio le funzionalità di logging di Log4NET.
Come inserire il log nella nostra classe? Il miglior metodo è:
private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Così facendo si dichiara nella nostra classe la variabile statica da usare per loggare.
Notare come con il codice System.Reflection.MethodBase.GetCurrentMethod().DeclaringType si prende il nome della classe in automatico (utilissima info da inserire nel file di log). Questo ha l'indubbio vantaggio di riutilizzare il codice al volo senza dover cambiare nulla.
Come fare il log nei nostri metodi?
Io uso queste due istruzioni all'inizio e alla fine dei metodi più importanti:
Logger.Info(MethodBase.GetCurrentMethod().DeclaringType.ToString() + " - " + MethodBase.GetCurrentMethod().Name + " - Method Begin");
...
Logger.Info(MethodBase.GetCurrentMethod().DeclaringType.ToString() + " - " + MethodBase.GetCurrentMethod().Name + " - Method End");
Anche qui, la motivazione di questo codice è quella di prendere in automatico il nome della classe con il suo namespace ed il nome del metodo.
Vediamo come loggare una eccezione:
try{
...
}
catch(Exception ex)
{
string errorMsg = ex.Message;
if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message))
{
errorMsg += ex.InnerException.Message;
}
Logger.Error(MethodBase.GetCurrentMethod().DeclaringType, errorMsg, ex);
throw;
}
I Livelli da usare nella configurazione dei log sono i seguenti:
All (Log everything)
Debug
Info
Warn
Error
Fatal
Off (Don’t log anything)
Cosa fare se log4net non riesce la loggare?
Questa libreria se incontra qualche problema non blocca il programma ma semplicemente non logga nulla.
Basta agire nel file web.config ed inserire le seguenti configurazioni:
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
La prima configurazione abilita la libreria log4net all'internal logging. Il tag system diagnostic abilita la scrittura del trace, altrimenti il log interno della libreria log4net non si vedrebbe.
Il file log4net.txt verrà scritto allo stesso livello del file web.config della nostra applicazione.
JSON
Ipotesi: abbiamo un programma C# e vogliamo gestire i msg JSON.
La libreria più usata è quella della Newtonsoft che può tranquillamente essere installata nella nostra solution tramite NuGet.
Come creare un msg JSON? Ecco i semplici passi
//Stringa che conterrà il nostro msg JSON
string jsonMsg = string.Empty;
JObject msgJson = JObject.FromObject(new { mioTag = "mioValore" });
//La seguente istruzione ci dà un msg JSON sotto forma di stringa e senza formattazione
jsonMsg = JsonConvert.SerializeObject(msgJson, Newtonsoft.Json.Formatting.None);
StringContent jsonContent = new StringContent(jsonMsg, Encoding.UTF8, "application/json");
Vediamo ora come convertire una stringa XML in msg JSON:
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null;
doc.LoadXml(myStringXML);
string jsonMsg = JsonConvert.SerializeXmlNode(doc);
Sempre per l'esempio appena visto possiamo anche fare:
string xmljson = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.None, true);
Ovvero gli diciamo di non usare alcuna formattazione e di non inserire la root del nostro XML.
Come ciclare su un JArray (JSON Array)?
JArray jarr = (JArray)response.Response["fields"];
foreach (JObject contentTmp in jarr.Children<JObject>())
{
foreach (JProperty prop in contentTmp.Properties())
{
string tempValue = prop.Value.ToString();
//here more code in order to save in a database
}
}
Scrivere in una colonna del database una string formattata come JSON
E' molto utile avere in una colonna NVARCHAR(max) del nostro database un contenuto in formato JSON. Vediamo come fare:
var objJson = new JObject();
objJson["miaChiave"] = System.Guid.NewGuid();
string testJson = JsonConvert.SerializeObject(objJson, Formatting.None);
Si crea prima un oggetto JObject fornito dalla libreria JSon. Su questo oggetto si possono inserire tutte le coppia "chiave,valore" che si vogliono e poi lo si formatta/serializza in maniera da renderlo compatibile con una stringa.
La stringa risultante testJson la si mette nel campo del database.
Da stringa JSon ad oggetto
Vediamo come avere un oggetto a partire dalla sua rappresentazione in JSon:
MiaClasse miaClasseObj = JsonConvert.DeserializeObject<MiaClasse>(stringaJson);
Da oggetto a string JSON
Vediamo come convertire un oggetto nella sua rappresentazione JSon:
string jsonVersion = JsonConvert.SerializeObject(MyObject, Formatting.None);
Selezionare un Token in una string JSon
string myValue = JsonConvert.DeserializeObject<JObject>(valueJson).SelectToken("MyToken").ToString();
FILE
Da immagine a ByteArray e poi in string a base64
Vediamo come avere una stringa Base64 a partire da una immagine:
byte[] imageArray = System.IO.File.ReadAllBytes(@"path della immagine");
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
Da stringa a File
Vediamo come scrivere una stringa in un file:
using (StreamWriter outputFile = new StreamWriter(@"path del file txt"))
{
outputFile.WriteLine(base64ImageRepresentation);
}
Da stringa base64 a byte[]
byte[] image = Convert.FromBase64String(base64ImageRepresentation);
Da byte[] a file con sovrascrittura
Vediamo come a partire da un array di byte possiamo scrivere il file su file system tenendo conto che il file possa esserci già e quindi va sovrascritto (in questo caso se c'è prima lo cancelliamo):
byte[] myByte = ...;
if (File.Exists(@"C:\myPath\myFile.png")) {
File.Delete(@"C:\myPath\myFile.png");
}
System.IO.FileStream fileStream = new System.IO.FileStream(@"C:\myPath\myFile.png", System.IO.FileMode.Create, System.IO.FileAccess.Write);
fileStream.Write(myByte, 0, myByte.Length);
fileStream.Close();
CONVERSIONI
Da string a Double
Il nostro scopo è convertire una string in un double tenendo conto che il numero reale possa avere il punto o la virgola come separtore:
double y;
try
{
y = double.Parse(myStringWithDouble, CultureInfo.InvariantCulture);
} catch (Exception) {
y = 0.0;
}
Se qualcosa va storto si mette come valore di default 0.0.
Boolean.TryParse()
Vediamo come gestire al meglio la conversione di una stringa in booleano.
Il miglior codice da usare è il seguente:
bool mioValoreBool = false;
string valoreStrDaconvertire = .....;
if (!Boolean.TryParse(valoreStrDaconvertire, out mioValoreBool))
{
log.Info("Conversione in bool non riuscita.");
mioValoreBool = false;
}
La variabile mioValoreBool conterrà la conversione in booleano del valore in stringa valoreStrDaconvertire.
Se la conversione non riesce la funzione ritorna False e questo valore deve essere gestito esplicitamente altrimenti in fase di analisi statica del codice si ottiene il warning seguente:
CA1806 Do not ignore method results
Numeri Random
Vediamo come generare in C# dei numeri random:
Random rnd = new Random();
rnd.Next(1,10);
Questa istruzione genera numeri random nel range 1,9.
Quindi il limite superiore è incluso mentre quello superiore è escluso.
Una versione più corretta sarebbe la seguente:
Random rnd = new Random(DateTime.Now.Millisecond);
rnd.Next(1,10)
In questo caso passando gli attuali millisecondi si usa un seme variabile e quindi la generazione dei numeri random è acora più casuale.
Enum
From String to Enum
Vediamo come convertire una stringa in un Enum:
public MyEnum GetStringToEnumValue()
{
string myStringToEnum = "some value that represent an enum";
if(Enum.TryParse(myStringToEnum, out MyEnum myStatus))
{
return myStatus;
}
throw new Exception("...");
}
Buon lavoro!