Protezione delle stringhe di connessione e di altre informazioni di configurazione (C#)
Un'applicazione ASP.NET archivia in genere le informazioni di configurazione in un file di Web.config. Alcune di queste informazioni sono sensibili e garantiscono la protezione. Per impostazione predefinita, questo file non verrà servito a un visitatore del sito Web, ma un amministratore o un hacker può accedere al file system del server Web e visualizzare il contenuto del file. In questa esercitazione si apprenderà che ASP.NET 2.0 consente di proteggere le informazioni riservate crittografando le sezioni del file di Web.config.
Introduzione
Le informazioni di configurazione per le applicazioni ASP.NET vengono in genere archiviate in un file XML denominato Web.config
. Nel corso di queste esercitazioni abbiamo aggiornato le Web.config
poche volte. Quando si crea il Northwind
dataset tipizzato nella prima esercitazione, ad esempio, stringa di connessione informazioni sono state aggiunte automaticamente nella Web.config
<connectionStrings>
sezione. Successivamente, nell'esercitazione Master Pages and Site Navigation (Pagine master e Navigazione sito ) è stato aggiornato Web.config
manualmente , aggiungendo un <pages>
elemento che indica che tutte le pagine di ASP.NET nel progetto devono usare il DataWebControls
tema.
Poiché Web.config
può contenere dati sensibili, ad esempio stringhe di connessione, è importante che il contenuto di Web.config
sia mantenuto sicuro e nascosto dagli utenti non autorizzati. Per impostazione predefinita, qualsiasi richiesta HTTP a un file con l'estensione .config
viene gestita dal motore di ASP.NET, che restituisce il messaggio Questo tipo di pagina non viene visualizzato nella figura 1. Ciò significa che i visitatori non possono visualizzare il Web.config
contenuto del file immettendo http://www.YourServer.com/Web.config semplicemente nella barra degli indirizzi del browser.
Figura 1: Visita Web.config
tramite un browser Restituisce un tipo di pagina non servito Messaggio (Fare clic per visualizzare l'immagine a dimensioni complete)
Ma cosa succede se un utente malintenzionato riesce a trovare un altro exploit che consente di visualizzare il Web.config
contenuto del file? Cosa può fare un utente malintenzionato con queste informazioni e quali passaggi possono essere eseguiti per proteggere ulteriormente le informazioni riservate all'interno Web.config
di ? Fortunatamente, la maggior parte delle sezioni in Web.config
non contiene informazioni riservate. Quale danno può causare un utente malintenzionato se conosce il nome del tema predefinito usato dalle pagine di ASP.NET?
Alcune Web.config
sezioni, tuttavia, contengono informazioni riservate che possono includere stringhe di connessione, nomi utente, password, nomi del server, chiavi di crittografia e così via. Queste informazioni sono in genere disponibili nelle sezioni seguenti Web.config
:
<appSettings>
<connectionStrings>
<identity>
<sessionState>
In questa esercitazione verranno esaminate le tecniche per la protezione di tali informazioni di configurazione riservate. Come si vedrà, .NET Framework versione 2.0 include un sistema di configurazioni protette che esegue la crittografia e la decrittografia delle sezioni di configurazione selezionate a livello di codice.
Nota
Questa esercitazione termina con un'occhiata alle raccomandazioni di Microsoft per la connessione a un database da un'applicazione ASP.NET. Oltre a crittografare le stringhe di connessione, è possibile proteggere il sistema assicurandosi di connettersi al database in modo sicuro.
Passaggio 1: Esplorazione delle opzioni di configurazione protette di ASP.NET 2.0
ASP.NET 2.0 include un sistema di configurazione protetto per crittografare e decrittografare le informazioni di configurazione. Sono inclusi i metodi in .NET Framework che possono essere usati per crittografare o decrittografare le informazioni di configurazione a livello di codice. Il sistema di configurazione protetto usa il modello provider che consente agli sviluppatori di scegliere l'implementazione crittografica utilizzata.
.NET Framework viene fornito con due provider di configurazione protetti:
RSAProtectedConfigurationProvider
- usa l'algoritmo RSA asimmetrico per la crittografia e la decrittografia.DPAPIProtectedConfigurationProvider
- usa l'API Protezione dati di Windows (DPAPI) per la crittografia e la decrittografia.
Poiché il sistema di configurazione protetto implementa il modello di progettazione del provider, è possibile creare il proprio provider di configurazione protetto e collegarlo all'applicazione. Per altre informazioni su questo processo, vedere Implementazione di un provider di configurazione protetto .
I provider RSA e DPAPI usano chiavi per le routine di crittografia e decrittografia e queste chiavi possono essere archiviate a livello di computer o utente. Le chiavi a livello di computer sono ideali per scenari in cui l'applicazione Web viene eseguita nel proprio server dedicato o se sono presenti più applicazioni in un server che devono condividere informazioni crittografate. Le chiavi a livello di utente sono un'opzione più sicura negli ambienti di hosting condiviso in cui altre applicazioni nello stesso server non devono essere in grado di decrittografare le sezioni di configurazione protette dell'applicazione.
In questa esercitazione gli esempi useranno il provider DPAPI e le chiavi a livello di computer. In particolare, verrà esaminata la crittografia della <connectionStrings>
sezione in Web.config
, anche se il sistema di configurazione protetto può essere usato per crittografare la maggior parte delle Web.config
sezioni. Per informazioni sull'uso delle chiavi a livello di utente o sull'uso del provider RSA, consultare le risorse nella sezione Ulteriori letture alla fine di questa esercitazione.
Nota
I RSAProtectedConfigurationProvider
provider e DPAPIProtectedConfigurationProvider
vengono registrati nel machine.config
file con i nomi RsaProtectedConfigurationProvider
del provider e DataProtectionConfigurationProvider
, rispettivamente. Quando si crittografa o decrittografando le informazioni di configurazione, è necessario specificare il nome del provider appropriato ( o ) anziché il nome effettivo del tipo (RsaProtectedConfigurationProvider
RSAProtectedConfigurationProvider
e DPAPIProtectedConfigurationProvider
).DataProtectionConfigurationProvider
È possibile trovare il machine.config
file nella $WINDOWS$\Microsoft.NET\Framework\version\CONFIG
cartella.
Passaggio 2: Crittografare e decrittografare le sezioni di configurazione a livello di codice
Con alcune righe di codice è possibile crittografare o decrittografare una determinata sezione di configurazione usando un provider specificato. Il codice, come si vedrà brevemente, deve semplicemente fare riferimento a livello di codice alla sezione di configurazione appropriata, chiamare il ProtectSection
metodo o UnprotectSection
e quindi chiamare il Save
metodo per rendere persistenti le modifiche. Inoltre, .NET Framework include un'utilità della riga di comando utile che può crittografare e decrittografare le informazioni di configurazione. Verrà esaminata questa utilità della riga di comando nel passaggio 3.
Per illustrare le informazioni di configurazione a livello di codice, consente di creare una pagina di ASP.NET che include pulsanti per crittografare e decrittografare la <connectionStrings>
sezione in Web.config
.
Iniziare aprendo la EncryptingConfigSections.aspx
pagina nella AdvancedDAL
cartella. Trascinare un controllo TextBox dalla casella degli strumenti nella Designer, impostandone rispettivamente la ID
proprietà su WebConfigContents
, la relativa TextMode
proprietà su MultiLine
e Width
Rows
le relative proprietà e su 95% e 15. Questo controllo TextBox visualizzerà il contenuto che Web.config
consente di verificare rapidamente se il contenuto è crittografato o meno. Naturalmente, in un'applicazione reale non si vuole mai visualizzare il contenuto di Web.config
.
Sotto la Casella di testo aggiungere due controlli Button denominati EncryptConnStrings
e DecryptConnStrings
. Impostare le proprietà di testo su Crittografare stringhe di connessione e decrittografare le stringhe di connessione .
A questo punto la schermata dovrebbe essere simile alla figura 2.
Figura 2: Aggiungere un controllo Web casella di testo e due controlli Web pulsante alla pagina (fare clic per visualizzare l'immagine full-size)
Successivamente, è necessario scrivere codice che carica e visualizza il contenuto di Web.config
in WebConfigContents
TextBox quando la pagina viene caricata per la prima volta. Aggiungere il codice seguente alla classe code-behind della pagina. Questo codice aggiunge un metodo denominato DisplayWebConfig
e lo chiama dal Page_Load
gestore eventi quando Page.IsPostBack
è false
:
protected void Page_Load(object sender, EventArgs e)
{
// On the first page visit, call DisplayWebConfig method
if (!Page.IsPostBack)
DisplayWebConfig();
}
private void DisplayWebConfig()
{
// Reads in the contents of Web.config and displays them in the TextBox
StreamReader webConfigStream =
File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
string configContents = webConfigStream.ReadToEnd();
webConfigStream.Close();
WebConfigContents.Text = configContents;
}
Il DisplayWebConfig
metodo usa la File
classe per aprire il file dell'applicazione Web.config
, la StreamReader
classe per leggere il contenuto in una stringa e la Path
classe per generare il percorso fisico del Web.config
file. Queste tre classi sono tutte disponibili nello System.IO
spazio dei nomi. Di conseguenza, è necessario aggiungere un'istruzione using
System.IO
all'inizio della classe code-behind o, in alternativa, prefissi questi nomi di classe con System.IO.
.
È quindi necessario aggiungere gestori eventi per i due eventi di controlli Click
Button e aggiungere il codice necessario per crittografare e decrittografare la <connectionStrings>
sezione usando una chiave a livello di computer con il provider DPAPI. Dalla Designer fare doppio clic su ognuno dei pulsanti per aggiungere un Click
gestore eventi nella classe code-behind e quindi aggiungere il codice seguente:
protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only encrypt the section if it is not already protected
if (!connectionStrings.SectionInformation.IsProtected)
{
// Encrypt the <connectionStrings> section using the
// DataProtectionConfigurationProvider provider
connectionStrings.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings =
config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only decrypt the section if it is protected
if (connectionStrings.SectionInformation.IsProtected)
{
// Decrypt the <connectionStrings> section
connectionStrings.SectionInformation.UnprotectSection();
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
Il codice usato nei due gestori eventi è quasi identico. Entrambi iniziano recuperando informazioni sul file dell'applicazione Web.config
corrente tramite il WebConfigurationManager
metodo della classe.OpenWebConfiguration
Questo metodo restituisce il file di configurazione Web per il percorso virtuale specificato. Successivamente, la Web.config
sezione del file viene accessibile tramite il Configuration
metodo della GetSection(sectionName)
<connectionStrings>
classe, che restituisce un ConfigurationSection
oggetto.
L'oggetto ConfigurationSection
include una SectionInformation
proprietà che fornisce informazioni e funzionalità aggiuntive relative alla sezione di configurazione. Come illustrato nel codice precedente, è possibile determinare se la sezione di configurazione è crittografata controllando la SectionInformation
proprietà della IsProtected
proprietà. Inoltre, la sezione può essere crittografata o decrittografata tramite i metodi e UnprotectSection
delle SectionInformation
proprietàProtectSection(provider)
.
Il ProtectSection(provider)
metodo accetta come input una stringa che specifica il nome del provider di configurazione protetto da usare durante la crittografia. EncryptConnString
Nel gestore eventi Button viene passato DataProtectionConfigurationProvider al ProtectSection(provider)
metodo in modo che venga usato il provider DPAPI. Il UnprotectSection
metodo può determinare il provider usato per crittografare la sezione di configurazione e pertanto non richiede parametri di input.
Dopo aver chiamato il metodo oUnprotectSection
, è necessario chiamare il metodo dell'oggetto Save
ProtectSection(provider)
Configuration
per rendere persistenti le modifiche. Dopo aver crittografato o decrittografato le informazioni di configurazione e le modifiche salvate, viene chiamato DisplayWebConfig
per caricare il contenuto aggiornato Web.config
nel controllo TextBox.
Dopo aver immesso il codice precedente, testarlo visitando la EncryptingConfigSections.aspx
pagina tramite un browser. Inizialmente verrà visualizzata una pagina che elenca il contenuto di Web.config
con la <connectionStrings>
sezione visualizzata in testo normale (vedere la figura 3).
Figura 3: Aggiungere un controllo Web casella di testo e due controlli Web pulsante alla pagina (fare clic per visualizzare l'immagine full-size)
Fare ora clic sul pulsante Crittografa stringhe di connessione. Se la convalida della richiesta è abilitata, il markup pubblicato di nuovo da WebConfigContents
TextBox produrrà un HttpRequestValidationException
oggetto , che visualizza il messaggio, un valore potenzialmente pericoloso Request.Form
è stato rilevato dal client. La convalida della richiesta, abilitata per impostazione predefinita in ASP.NET 2.0, impedisce postback che includono html non codificati ed è progettata per impedire attacchi di inserimento di script. Questo controllo può essere disabilitato a livello di pagina o applicazione. Per disattivarlo per questa pagina, impostare l'impostazione ValidateRequest
su false
nella @Page
direttiva. La @Page
direttiva viene trovata nella parte superiore del markup dichiarativo della pagina.
<%@ Page ValidateRequest="False" ... %>
Per altre informazioni sulla convalida della richiesta, lo scopo, come disabilitarlo a livello di pagina e applicazione, nonché come codificaRE HTML, vedere Convalida della richiesta - Prevenzione degli attacchi di script.
Dopo aver disabilitato la convalida della richiesta per la pagina, provare a fare clic nuovamente sul pulsante Crittografa stringhe di connessione. Al postback, il file di configurazione verrà accessibile e la relativa <connectionStrings>
sezione crittografata usando il provider DPAPI. TextBox viene quindi aggiornato per visualizzare il nuovo Web.config
contenuto. Come illustrato nella figura 4, le <connectionStrings>
informazioni sono ora crittografate.
Figura 4: Fare clic sul pulsante Encrypt Connection Strings Encrypts the Section (Fare clic per visualizzare l'immagine<connectionString>
full-size)
La sezione crittografata <connectionStrings>
generata nel computer segue, anche se alcuni dei contenuti nell'elemento <CipherData>
sono stati rimossi per brevità:
<connectionStrings
configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/...zChw==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Nota
L'elemento <connectionStrings>
specifica il provider usato per eseguire la crittografia (DataProtectionConfigurationProvider
). Queste informazioni vengono usate dal metodo quando viene fatto clic sul UnprotectSection
pulsante Decrittografa stringhe di connessione.
Quando le informazioni di stringa di connessione vengono accessibili da Web.config
, in base al codice scritto, da un controllo SqlDataSource o dal codice generato automaticamente dai TableAdapters in DataSet tipizzato, viene decrittografato automaticamente. In breve, non è necessario aggiungere codice aggiuntivo o logica per decrittografare la sezione crittografata <connectionString>
. Per illustrare questo problema, visitare una delle esercitazioni precedenti in questo momento, ad esempio l'esercitazione Di visualizzazione semplice dalla sezione Report di base (~/BasicReporting/SimpleDisplay.aspx
). Come illustrato nella figura 5, l'esercitazione funziona esattamente come ci si aspetta, indicando che le informazioni stringa di connessione crittografate vengono decrittografate automaticamente dalla pagina ASP.NET.
Figura 5: Il livello di accesso ai dati decrittografa automaticamente le informazioni sulla stringa di connessione (fare clic per visualizzare l'immagine full-size)
Per ripristinare la <connectionStrings>
sezione nella rappresentazione di testo normale, fare clic sul pulsante Decrittografa stringhe di connessione. Nel postback verranno visualizzate le stringhe di connessione in Web.config
testo normale. A questo punto la schermata dovrebbe essere simile alla prima visita di questa pagina (vedere la figura 3).
Passaggio 3: Crittografia delle sezioni di configurazione tramite aspnet_regiis.exe
.NET Framework include un'ampia gamma di strumenti da riga di comando nella $WINDOWS$\Microsoft.NET\Framework\version\
cartella. Nell'esercitazione Uso delle dipendenze cache SQL, ad esempio, è stato esaminato l'uso aspnet_regsql.exe
dello strumento della riga di comando per aggiungere l'infrastruttura necessaria per le dipendenze della cache SQL. Un altro strumento della riga di comando utile in questa cartella è lo strumento ASP.NET di registrazione IIS (aspnet_regiis.exe
). Come implica il nome, lo strumento di registrazione IIS ASP.NET viene usato principalmente per registrare un'applicazione ASP.NET 2.0 con il server Web di livello professionale Microsoft, IIS. Oltre alle funzionalità correlate a IIS, lo strumento di registrazione IIS ASP.NET può essere usato anche per crittografare o decrittografare le sezioni di configurazione specificate in Web.config
.
L'istruzione seguente mostra la sintassi generale usata per crittografare una sezione di configurazione con lo strumento della aspnet_regiis.exe
riga di comando:
aspnet_regiis.exe -pef section physical_directory -prov provider
sezione è la sezione di configurazione per crittografare (ad esempio connectionStrings ), il physical_directory è il percorso fisico completo della directory radice dell'applicazione Web e il provider è il nome del provider di configurazione protetto da usare (ad esempio DataProtectionConfigurationProvider). In alternativa, se l'applicazione Web è registrata in IIS, è possibile immettere il percorso virtuale anziché il percorso fisico usando la sintassi seguente:
aspnet_regiis.exe -pe section -app virtual_directory -prov provider
L'esempio seguente aspnet_regiis.exe
crittografa la <connectionStrings>
sezione usando il provider DPAPI con una chiave a livello di computer:
aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_CS"
-prov "DataProtectionConfigurationProvider"
Analogamente, lo strumento della aspnet_regiis.exe
riga di comando può essere usato per decrittografare le sezioni di configurazione. Anziché usare l'opzione -pef
, usare -pdf
(o invece di -pe
, usare -pd
). Si noti inoltre che il nome del provider non è necessario durante la decrittografia.
aspnet_regiis.exe -pdf section physical_directory
-- or --
aspnet_regiis.exe -pd section -app virtual_directory
Nota
Poiché si usa il provider DPAPI, che usa chiavi specifiche per il computer, è necessario eseguire aspnet_regiis.exe
dallo stesso computer da cui vengono gestite le pagine Web. Ad esempio, se si esegue questo programma della riga di comando dal computer di sviluppo locale e quindi si carica il file di Web.config crittografato nel server di produzione, il server di produzione non sarà in grado di decrittografare le informazioni di stringa di connessione poiché è stato crittografato usando chiavi specifiche per il computer di sviluppo. Il provider RSA non ha questa limitazione perché è possibile esportare le chiavi RSA in un altro computer.
Informazioni sulle opzioni di autenticazione del database
Prima che qualsiasi applicazione possa emettere SELECT
query , , INSERT
UPDATE
o DELETE
a un database di microsoft SQL Server, il database deve prima identificare il richiedente. Questo processo è noto come autenticazione e SQL Server fornisce due metodi di autenticazione:
- Autenticazione di Windows : processo in cui viene eseguita l'applicazione per comunicare con il database. Quando si esegue un'applicazione ASP.NET tramite Visual Studio 2005 s ASP.NET Development Server, l'applicazione ASP.NET presuppone l'identità dell'utente attualmente connesso. Per ASP.NET applicazioni in Microsoft Internet Information Server (IIS), ASP.NET applicazioni in genere presupponeno l'identità di
domainName``\MachineName
odomainName``\NETWORK SERVICE
, anche se è possibile personalizzare questa operazione. - Autenticazione SQL : i valori id utente e password vengono forniti come credenziali per l'autenticazione. Con l'autenticazione SQL, l'ID utente e la password vengono forniti nella stringa di connessione.
autenticazione di Windows è preferibile tramite l'autenticazione SQL perché è più sicura. Con autenticazione di Windows il stringa di connessione è gratuito da un nome utente e una password e se il server Web e il server di database risiedono in due computer diversi, le credenziali non vengono inviate tramite la rete in testo normale. Con l'autenticazione SQL, tuttavia, le credenziali di autenticazione vengono hardcoded nella stringa di connessione e vengono trasmesse dal server Web al server di database in testo normale.
Queste esercitazioni hanno usato autenticazione di Windows. È possibile indicare quale modalità di autenticazione viene usata controllando la stringa di connessione. Il stringa di connessione in Web.config
per le esercitazioni è stato:
Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True
La sicurezza integrata=True e la mancanza di un nome utente e una password indicano che viene usato autenticazione di Windows. In alcune stringhe di connessione il termine Trusted Connection=Sì o Integrated Security=SSPI viene usato anziché Integrated Security=True, ma tutte e tre indicano l'uso di autenticazione di Windows.
Nell'esempio seguente viene illustrato un stringa di connessione che usa l'autenticazione SQL. $CREDENTIAL_PLACEHOLDER$
è un segnaposto per la coppia chiave-valore della password. Si noti che le credenziali vengono incorporate all'interno del stringa di connessione:
Server=serverName; Database=Northwind; uid=userID; $CREDENTIAL_PLACEHOLDER$
Si supponga che un utente malintenzionato possa visualizzare il file dell'applicazione Web.config
. Se si usa l'autenticazione SQL per connettersi a un database accessibile tramite Internet, l'utente malintenzionato può usare questa stringa di connessione per connettersi al database tramite SQL Management Studio o dalle pagine di ASP.NET nel proprio sito Web. Per attenuare questa minaccia, crittografare le informazioni di stringa di connessione nell'uso Web.config
del sistema di configurazione protetta.
Nota
Per altre informazioni sui diversi tipi di autenticazione disponibili in SQL Server, vedere Compilazione di applicazioni di ASP.NET sicure: autenticazione, autorizzazione e comunicazione sicura. Per ulteriori stringa di connessione esempi che illustrano le differenze tra sintassi di autenticazione Windows e SQL, vedere ConnectionStrings.com.
Riepilogo
Per impostazione predefinita, i file con estensione in un'applicazione .config
ASP.NET non possono essere accessibili tramite un browser. Questi tipi di file non vengono restituiti perché possono contenere informazioni riservate, ad esempio stringhe di connessione al database, nomi utente e password e così via. Il sistema di configurazione protetto in .NET 2.0 consente di proteggere ulteriormente le informazioni riservate consentendo la crittografia delle sezioni di configurazione specificate. Esistono due provider di configurazione protetti predefiniti: uno che usa l'algoritmo RSA e uno che usa l'API Protezione dati di Windows (DPAPI).
In questa esercitazione è stato illustrato come crittografare e decrittografare le impostazioni di configurazione usando il provider DPAPI. Questa operazione può essere eseguita sia a livello di codice, come illustrato nel passaggio 2, sia tramite lo strumento della aspnet_regiis.exe
riga di comando, illustrato nel passaggio 3. Per altre informazioni sull'uso di chiavi a livello di utente o sull'uso del provider RSA, vedere invece le risorse nella sezione Ulteriori letture.
Programmazione felice!
Altre informazioni
Per altre informazioni sugli argomenti illustrati in questa esercitazione, vedere le risorse seguenti:
- Creazione di un'applicazione sicura ASP.NET: autenticazione, autorizzazione e comunicazione sicura
- Crittografia delle informazioni di configurazione nelle applicazioni ASP.NET 2.0
- Crittografia dei
Web.config
valori in ASP.NET 2.0 - Procedura: Crittografare le sezioni di configurazione in ASP.NET 2.0 usando DPAPI
- Procedura: crittografare le sezioni di configurazione in ASP.NET 2.0 utilizzando RSA
- API di configurazione in .NET 2.0
- Protezione dei dati di Windows
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.
Grazie speciali
Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali per questa esercitazione erano Teresa Murphy e Randy Schmidt. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per