mercoledì 4 gennaio 2017
Come sapete non è possibile, salvo
configurazioni un pò macchinose, accedere a siti ospitati su
IIS Express dall'esterno (altri PC\VM\dispositivi).
Esiste tuttavia un modo molto più semplice, che richiede l’installazione di un proxy via NPM
npm install -g iisexpress-proxy Una volta installato, basta eseguire il comando
iisexpress-proxy 51123 to 3000
Dove
- 51123 è la porta IIS a cui il sito è raggiungibile (che è dinamica)
- 3000 è la porta al quale il sito risponderà all’esterno, usando l’ip della scheda di rete primaria.
Se l’ip del mio PC è 192.168.230.126, Il sito sarà ora raggiungibile dall’esterno all’indirizzo: http://192.168.230.126:3000
Su
GitHub trovate i dettagli del progetto.
giovedì 22 ottobre 2015
Molte volte capita di dover effettuare il parsing di file CSV.
L’implementazione può diventare complessa a piacere (basti pensare all’escape dei caratteri, personalizzazione dei delimitatori, etc) e per questo esistono già librerie che ci permettono di effettuare questa operazione facilmente.
Non tutti sanno (ecco il perchè di questo post) che il framework .NET fornisce già questa funzionalità .
La classe in questione è TextFieldParser, contenuto nell’assembly Microsoft.VisualBasic.
using (TextFieldParser parser = new TextFieldParser(@"C:\temp\sample.csv"))
{
parser.CommentTokens = new[] { "#" };
parser.SetDelimiters(";");
parser.HasFieldsEnclosedInQuotes = true;
// Skip over header line.
//parser.ReadLine();
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
if (fields != null)
{
var specificCulture = System.Globalization.CultureInfo.CreateSpecificCulture("it-IT");
var foo = new
{
Field1 = fields[0],
Field2 = int.Parse(fields[1], specificCulture),
Field3 = double.Parse(fields[1], specificCulture),
Field4 = DateTime.Parse(fields[1], specificCulture),
};
}
}
}
martedì 20 ottobre 2015
Da un pò di tempo, quando devo creare un Windows Service, utilizzo la libreria Topshelf, che permette di sviluppare una normale applicazione console e, una volta impostate le opportune configurazioni mediante sintassi fluent, installarla facilmente come windows service, senza tool esterni quali installutil.
Un’applicazione console, oltre ad essere più facile da debuggare, è anche eseguibile direttamente (a differenza di un windows service).
Vediamo quindi come creare un servizio.
1) Apriamo Visual Studio e selezionamo il progetto di tipo “Applicazione console”
2) Creiamo una nuova classe che esponga 2 metodi che verranno chiamati allo start e allo stop del servizio
internal class MyConsoleService
{
public void Start()
{
System.IO.File.AppendAllText("MyConsoleService.text", string.Format("MyConsoleService start {0}{1}", DateTime.Now, Environment.NewLine));
}
public void Stop()
{
System.IO.File.AppendAllText("MyConsoleService.text", string.Format("MyConsoleService start {0}{1}", DateTime.Now, Environment.NewLine));
}
}
3) Nel metodo Main della classe Program, andiamo a definire i parametri di configurazione del nostro servizio (vi rimando alla documentazione per la spiegazione dettagliata)
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyConsoleService>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyConsoleService());
serviceConfigurator.WhenStarted(service => service.Start());
serviceConfigurator.WhenStopped(service => service.Stop());
});
hostConfigurator.RunAsNetworkService();
hostConfigurator.StartAutomatically(); // Autostart del Servizio
hostConfigurator.SetDisplayName("MyConsoleApp Service"); // Nome visualizzato nell'elenco servizi di services.msc
hostConfigurator.SetDescription("Servizio creato utilizzando Topshelf"); // Descrizione visualizzata nell'elenco servizi di services.msc
hostConfigurator.SetServiceName("MyConsoleAppService"); // Nome del servizio
});
}
}
4) Per installare il servizio lanciamo l’exe con il parametro install (digitare il parametro help per vedere l’elenco completo dei comandi)
5) Apriamo la console dei servizi di WIndows e verifichiamo la corretta installazione del servizio
6) Avviamo il servizio e controlliamo la creazione del file
Come potete vedere Topshelf è molto versatile quanto poco invasivo (solo il passo 3 è relativo alla configurazione dell’infastruttura).
Dategli un’occhiata e dimenticherete presto come si crea un windows service, il relativo installer e il tool installutil.
martedì 16 giugno 2015
Recentemente ho avuto la necessità di intercettare e manipolare le query generate da Entity Framework.
In particolare dovevo assicurarmi che non venissero estratte dal database le entità la cui proprietà Disabled fosse true (cancellazione logica).
Dalla versione 6 è possibile innestarsi nella pipeline di EntityFramework ereditando dalla classe DefaultExpressionVisitor ed eseguento l'override del metodo Visit, che si occupa di generare l'expression tree che poi verrà convertito in SQL.
Sostanzialmente, se il tipo di entità ha una proprietà Disabled, imposto un filtro verificando che non sia uguale a true.
Per iniettare questo comportamento nella pipeline, basta implementare l'interfaccia IDbCommandTreeInterceptor e aggiungerla mediante il metodo DbInterception.Add(new SoftDeleteInterceptor()).
Ora ogni query di EntityFramework non estrarrà le entità disabilitate.
La cosa è molto utile anche in caso di estrazioni di alberi di oggetti, in quanto se un'entità disabilitata, non si otterrano neanche le entità children, in quanto viene a mancare la condizione di join.
giovedì 5 febbraio 2015
A volte potrebbe tornare utile avere la rappresentazione visuale del modello CodeFirst che stiamo utilizzando, ovvero datto il DbContext CodeFirst, ottenere il file EDMX corrispondente:

Il tutto è facilmente ottenibile con poche righe di codice:
mercoledì 28 agosto 2013
Oggi mi sono trovato a risolvere un'attività relativamente semplice, ma che in realtà merita un post al riguardo in quanto nasconde alcuni problemi alquanto "subdoli".
Sostanzialmente dovevo costruire, via Javascript, un URL con parametri in QueryString da dare "in pasto" ad una window.open() (
).
Ebbene, i "problemil" sono sostanzialmente:
- encoding dei valori dei parametri\ (possono contenere &, spazi, etc)
- le funzioni native per gestire la (de)codifica delle stringhe sono inutili (vedi qui)
- ogni browser interpreta il tutto a modo suo (anche con comportamenti differenti da versione a versione dello stesso)
Come fare quindi? La soluzione è sempre la stessa..quando si parla di sviluppo web mai dimenticare JQuery!
Esiste infatti una bellissima funzione $.param() che permette di serializzare correttamente un oggetto, in modo da essere compatibile con il formato atteso dalla QueryString!
ES:

mercoledì 17 aprile 2013
Ultimamente mi sto dilettando su un progetto che utilizza ASP.NET MVC in accoppiata con KnockoutJs.
Si tratta di un'applicazione Single-Page che, tramite AJAX, va a costruire dinamicamente il ViewModel Knockout e che quindi, a seconda della navigazione compiuta dall'utente tramite richieste multiple e asincrone, può diventare "grande" a piacere e difficilmente debuggabile.
Mi è quindi tornato utile questo snippet, che permette di visualizzare lo stato attuale del ViewModel, mostrando tutte le proprietà presenti e i relativi valori, in formato json:
<div style="border: 2px dashed red">
<h1>KnockoutJS ViewModel Viewer:</h1>
<div data-bind="text: ko.toJSON($root)"></div>
</div>
Questo un esempio di quanto verrà stampato a video:

martedì 6 novembre 2012
Il code coverage è un'indice importante per avere un'idea della percentuale di codice coperto da unit-test.
Se utilizzate il framework di unit-test Microsoft (MSTest), Visual Studio è in grado di calcolare tale indice automaticamente (maggiori dettagli qui).
Tempo fa avevo instrumentato questo tool su un mio progetto ed oggi, dopo aver fatto refactoring ed aggiunto alcune funzionalità, volevo visualizzare i dati di code coverage.
Lanciando il tool, ottenevo tuttavia questo messaggio:
"Cannot find any coverage data (.coverage or .coveragexml) files. Check test run details for possible errors."
Dopo un pò di verifiche ho scoperto l'inghippo: per qualche motivo il file di impostazioni dei test corrente era "Trace and Test Impact" e non "Local".

giovedì 23 agosto 2012
Dalla versione 4.5 del .NET framework è finalmente supportata out-of-the-box la manipolazione di file zip senza l'utilizzo di librerie di terze parti.
Sono ora disponibili infatti 2 assembly System.IO.Compression e System.IO.Compression.FileSystem che permettono, ad esempio, di enumerare i file presenti in uno zip, estrarli, creare nuovi file zip, etc.
Ad esempio, ecco come si ottiene l'elenco dei file contenuti in uno zip:
const string zipFilePath = @"C:\temp\files.zip";
using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)){
using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) {
foreach (var zipArchiveEntry in archive.Entries) {
Console.WriteLine("File name: {0}", zipArchiveEntry.FullName);}
}}
E come si estraggono in una directory:
const string zipFilePath = @"C:\temp\files.zip";
const string dirToExtract = @"C:\temp\";
using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) {
using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
archive.ExtractToDirectory(dirToExtract);}}
Vi lascio quindi i riferimenti di MSDN:
ZipArchive Class
System.IO.Compression
mercoledì 22 agosto 2012
Una delle cose che più mi piacciono di JQuery è la facilità con la quale è possibile estendere le sue funzionalità.
Ecco infatti come è possibile implementare le funzioni per attivare e disattivare gli elementi del DOM:
// Set an element as enabled, if supported
$.fn.enable= function () {
return this.each(function () {
if (typeof this.disabled != "undefined") {
this.disabled = false;
}
});
};
// Set an element as disabled, if supported
$.fn.disable = function () {
return this.each(function () {
if (typeof this.disabled != "undefined") {
this.disabled = true;
}
});
};
In questo modo è possibile (dis)abilitare qualsiasi elemento con i soliti selettori JQuery:
$("*").enable();
$(".editor").disable();