Condividi tramite


Novità di ASP.NET MVC 2

Questo documento descrive nuove funzionalità e miglioramenti introdotti in ASP.NET MVC 2.

Introduzione
Aggiornamento di un progetto ASP.NET MVC 1.0 a ASP.NET MVC 2
Nuove funzionalità
Helper modelli
Aree
Supporto per controller asincroni
Supporto per DefaultValueAttribute nei parametri Action-Method
Supporto per l'associazione di dati binari con i binding di modelli
Classi ModelMetadata e ModelMetadataProvider
Supporto per gli attributi dataAnnotations
Provider model-validator
Convalida lato client
Nuovi frammenti di codice per Visual Studio 2010
Nuovo filtro azione RequireHttpsAttribute
Override del verbo del metodo HTTP
Nuova classe HiddenInputAttribute per gli helper modelli
Il metodo helper Html.ValidationSummary può visualizzare Model-Level errori
Modelli T4 in Visual Studio Genera codice specifico per la versione di destinazione dei miglioramenti dell'API .NET Framework
Modifiche di rilievo
Dichiarazione di non responsabilità

Introduzione

ASP.NET MVC 2 si basa su ASP.NET MVC 1.0 e introduce un ampio set di miglioramenti e funzionalità incentrate sull'aumento della produttività. Questa versione è compatibile con ASP.NET MVC 1.0, quindi tutte le conoscenze, le competenze, il codice e le estensioni per ASP.NET MVC 1.0 continuano a essere applicate.

Per altre informazioni su ASP.NET MVC, visitare le risorse seguenti:

Aggiornamento di un progetto ASP.NET MVC 1.0 a ASP.NET MVC 2

ASP.NET MVC 2 può essere installato side-by-side con ASP.NET MVC 1.0 nello stesso server, che consente agli sviluppatori di applicazioni di scegliere quando aggiornare un'applicazione ASP.NET MVC 1.0 a ASP.NET MVC 2. Per informazioni su come aggiornare, vedere il documento Aggiornamento di un'applicazione MVC 1.0 ASP.NET a ASP.NET MVC 2.

Nuove funzioni e caratteristiche

Questa sezione descrive le funzionalità introdotte nella versione MVC 2.

Helper modelli

Gli helper modelli consentono di associare automaticamente gli elementi HTML per la modifica e la visualizzazione ai tipi di dati. Ad esempio, quando i dati di tipo System.DateTime vengono visualizzati in una visualizzazione, è possibile eseguire automaticamente il rendering di un elemento dell'interfaccia utente di selezione date. È simile a come funzionano i modelli di campo in ASP.NET Dati dinamici. Per altre informazioni, vedere Uso di helper modelli per visualizzare i dati nel sito Web MSDN.

Aree

Le aree consentono di organizzare un progetto di grandi dimensioni in più sezioni più piccole per gestire la complessità di un'applicazione Web di grandi dimensioni. Ogni sezione ("area") rappresenta in genere una sezione separata di un sito Web di grandi dimensioni e viene usata per raggruppare set correlati di controller e viste. Per altre informazioni, vedere Procedura dettagliata: Organizzazione di un'applicazione MVC di ASP.NET per aree nel sito Web MSDN.

Per creare una nuova area, in Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto, scegliere Aggiungi e quindi fare clic su Area. Viene visualizzata una finestra di dialogo che richiede il nome dell'area. Dopo aver immesso il nome dell'area, Visual Studio aggiunge una nuova area al progetto.

La figura seguente mostra un layout di esempio per un progetto con due aree, Amministrazione e Blog.

Screenshot che mostra un layout di esempio per un progetto nella casella a discesa Esplora soluzioni con due aree, Amministrazione e blog.

Quando si crea un'area, Visual Studio aggiunge una classe che deriva da AreaRegistration a ogni area. Questa classe è necessaria per registrare l'area e le relative route, come illustrato nell'esempio seguente:

namespace MyApplication.Areas.Blog {
    public class BlogAreaRegistration : AreaRegistration {
        public override string AreaName {
            get { return "blog"; }
        }

        public override void RegisterArea(AreaRegistrationContext context) {
            context.MapRoute(
                "blog_default",
                "blog/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );

            context.MapRoute(
                "blog_whatsnew",
                "whats-new",
                new { action = "WhatsNew", id = UrlParameter.Optional  }
            );
        }
    }
}

Il modello di progetto predefinito per ASP.NET MVC 2 include una chiamata al metodo RegisterAllAreas nel codice per il file Global.asax. Questo metodo registra ogni area del progetto cercando tutti i tipi che derivano dalla classe AreaRegistration, creando un'istanza del tipo e chiamando il metodo RegisterArea nell'istanza. Nell'esempio seguente viene illustrato come viene eseguita questa operazione.

public class MyMvcApplication : HttpApplication {

    void App_Start() {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterRoutes(RouteCollection routes) {
        routes.MapRoute("default", "{controller}/{action}/{id}", ...);
    }
}

Se non si specifica lo spazio dei nomi nel metodo RegisterArea chiamando il contesto. Il metodo Namespaces.Add, lo spazio dei nomi della classe di registrazione viene usato per impostazione predefinita.

Supporto per controller asincroni

ASP.NET MVC 2 consente ora ai controller di elaborare le richieste in modo asincrono. Ciò può causare miglioramenti delle prestazioni consentendo ai server di chiamare spesso operazioni di blocco (ad esempio richieste di rete) per chiamare invece controparti non bloccanti. Per altre informazioni, vedere l'argomento Uso di un controller asincrono in ASP.NET MVC in MSDN.

Supporto per DefaultValueAttribute nei parametri Action-Method

La classe System.ComponentModel.DefaultValueAttribute consente di specificare un valore predefinito per il parametro di argomento a un metodo action. Si supponga, ad esempio, che la route predefinita seguente sia definita:

{controller}/{action}/{id}

Si supponga inoltre che il metodo di azione e il controller seguenti siano definiti:

public class ArticleController {
    public ActionResult View(int id, [DefaultValue(1)]int page) {
    }
}

Uno degli URL di richiesta seguenti richiama il metodo Di azione View definito nell'esempio precedente.

  • /Article/View/123
  • /Article/View/123?page=1 (Effettivamente uguale alla richiesta precedente)
  • /Article/View/123?page=2

Senza l'attributo DefaultValueAttribute, il primo URL dell'elenco precedente non funziona, perché l'argomento della pagina è un tipo di valore non nullable il cui valore non è stato specificato.

Se il codice è scritto in Visual Basic 2010 o Visual C# 2010, è possibile usare parametri facoltativi anziché l'attributo DefaultValueAttribute, come illustrato nell'esempio seguente:

Function View(ByVal id As Integer, Optional ByVal page As Integer = 1) _
        As ActionResult
    ' ...
End Function

public ActionResult MyAction(int id, int page = 1) {
    // ...
}

Supporto per l'associazione di dati binari con i binding di modelli

Esistono due nuovi overload del helper Html.Hidden che codificano i valori binari come stringhe con codifica base-64:

public static string Hidden(this HtmlHelper htmlHelper, string name, Binary value);

public static string Hidden(this HtmlHelper htmlHelper, string name, byte[] value);

Un uso tipico consiste nell'incorporare un timestamp per un oggetto nella visualizzazione. Ad esempio, l'applicazione potrebbe includere l'oggetto Product seguente:

public class Product {
    //... other properties ...	
    public byte[] TimeStamp {
        get;
        set;
    }
}

Un modulo di modifica può eseguire il rendering della proprietà TimeStamp nel modulo, come illustrato nell'esempio seguente:

<%@ Page Inherits="ViewPage<Product>" %>
<%= Html.Hidden("TimeStamp", Model.TimeStamp) %>

Questo markup esegue il rendering di un elemento di input nascosto con il valore timestamp come stringa con codifica base-64 simile all'esempio seguente:

<input type="hidden" name="TimeStamp" value="QVNQLk5FVCBNVkMgaXMgZnVuIQ==" />

Questo modulo può essere pubblicato in un metodo di azione con un argomento di tipo Product, come illustrato nell'esempio seguente:

public ActionResult Edit(Product p) {
    // p.TimeStamp is populated from the form
}

Nel metodo action la proprietà TimeStamp viene popolata correttamente perché la stringa con codifica base-64 viene convertita in una matrice di byte.

Classi ModelMetadata e ModelMetadataProvider

La classe ModelMetadataProvider fornisce un'astrazione per ottenere metadati per il modello all'interno di una vista. MVC 2 include un provider predefinito che rende disponibili i metadati esposti dagli attributi nello spazio dei nomi System.ComponentModel.DataAnnotations. È possibile creare provider di metadati che forniscono metadati da altri archivi dati, ad esempio database o file XML.

La classe ViewDataDictionary espone un oggetto ModelMetadata contenente i metadati estratti dal modello dalla classe ModelMetadataProvider. In questo modo, gli helper modelli possono usare questi metadati e modificare di conseguenza l'output.

Per altre informazioni, vedere la documentazione per le classi ModelMetadata e ModelMetadataProvider.

Supporto per gli attributi dataAnnotations

ASP.NET MVC 2 supporta l'uso degli attributi di convalida RangeAttribute, RequiredAttribute, StringLengthAttribute e RegexAttribute (definiti nello spazio dei nomi System.ComponentModel.DataAnnotations) quando si esegue il binding a un modello per fornire la convalida dell'input.

Per altre informazioni, vedere Procedura: Convalidare i dati del modello usando attributi dataAnnotations nel sito Web MSDN. Un progetto di esempio che illustra l'uso di questi attributi è disponibile per il download in https://go.microsoft.com/fwlink/?LinkId=157753.

Provider di Model-Validator

La classe provider di convalida del modello rappresenta un'astrazione che fornisce la logica di convalida per il modello. ASP.NET MVC include un provider predefinito basato sugli attributi di convalida inclusi nello spazio dei nomi System.ComponentModel.DataAnnotations. È anche possibile creare provider di convalida personalizzati che definiscono regole di convalida personalizzate e mapping personalizzati delle regole di convalida al modello. Per altre informazioni, vedere la documentazione per la classe ModelValidatorProvider .

convalida Client-Side

La classe provider model-validator espone i metadati di convalida al browser sotto forma di dati serializzati JSON che possono essere usati da una libreria di convalida lato client. ASP.NET MVC 2 include una libreria di convalida client e una scheda che supporta gli attributi di convalida dello spazio dei nomi DataAnnotations annotati in precedenza. La classe provider consente inoltre di usare altre librerie di convalida client scrivendo un adapter che elabora i dati JSON e chiama nella libreria alternativa.

Nuovi frammenti di codice per Visual Studio 2010

Un set di frammenti di codice HTML per ASP.NET MVC 2 viene installato con Visual Studio 2010. Per visualizzare un elenco di questi frammenti di codice, nel menu Strumenti selezionare Gestione frammenti di codice. Per la lingua selezionare HTML e per località selezionare ASP.NET MVC 2. Per altre informazioni su come usare frammenti di codice, vedere la documentazione di Visual Studio.

Nuovo filtro azione RequireHttpsAttribute

ASP.NET MVC 2 include una nuova classe RequireHttpsAttribute che può essere applicata ai metodi e ai controller di azione. Per impostazione predefinita, il filtro reindirizza una richiesta non SSL (HTTP) all'equivalente HTTPS (SSL abilitato).

Override del verbo del metodo HTTP

Quando si compila un sito Web usando lo stile di architettura REST, i verbi HTTP vengono usati per determinare quale azione eseguire per una risorsa. REST richiede che le applicazioni supportino l'intera gamma di verbi HTTP comuni, tra cui GET, PUT, POST e DELETE.

ASP.NET MVC 2 include nuovi attributi che è possibile applicare ai metodi di azione e a tale sintassi compatta. Questi attributi consentono ASP.NET MVC di selezionare un metodo di azione basato sul verbo HTTP. Nell'esempio seguente, una richiesta POST chiamerà il primo metodo di azione e una richiesta PUT chiamerà il secondo metodo di azione.

[HttpPost]
public ActionResult Edit(int id)

[HttpPut]
public ActionResult Edit(int id, Tag tag)

Nelle versioni precedenti di ASP.NET MVC, questi metodi di azione richiedono una sintassi più dettagliata, come illustrato nell'esempio seguente:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id) 

[AcceptVerbs(HttpVerbs.Put)] 
public ActionResult Edit(int id, Tag tag)

Poiché i browser supportano solo i verbi HTTP GET e POST, non è possibile pubblicare in un'azione che richiede un verbo diverso. Non è quindi possibile supportare in modo nativo tutte le richieste RESTful.

Tuttavia, per supportare le richieste RESTful durante le operazioni POST, ASP.NET MVC 2 introduce un nuovo metodo helper HTML HttpMethodOverride. Questo metodo esegue il rendering di un elemento di input nascosto che causa l'emulazione efficace di qualsiasi metodo HTTP. Ad esempio, usando il metodo helper HTML HttpMethodOverride, è possibile che venga visualizzato un invio di modulo come richiesta PUT o DELETE. Il comportamento di HttpMethodOverride influisce sugli attributi seguenti:

  • HttpPostAttribute
  • HttpPutAttribute
  • HttpGetAttribute
  • HttpDeleteAttribute
  • AcceptVerbsAttribute

L'elemento di input nascosto ha il nome X-HTTP-Method-Override e il relativo valore impostato sul verbo HTTP da emulare. Il valore di override può essere specificato anche in un'intestazione HTTP o in un valore stringa di query come coppia nome/valore.

L'override può essere usato solo quando la richiesta reale è una richiesta POST. Il valore di override verrà ignorato per le richieste che usano qualsiasi altro verbo HTTP.

Nuova classe HiddenInputAttribute per helper templated

È possibile applicare il nuovo attributo HiddenInputAttribute a una proprietà del modello per indicare se deve essere eseguito il rendering di un elemento di input nascosto durante la visualizzazione del modello in un modello di editor. L'attributo imposta un valore UIHint implicito di HiddenInput. La proprietà DisplayValue dell'attributo consente di specificare se il valore viene visualizzato nell'editor e nelle modalità di visualizzazione. Quando DisplayValue è impostato su false, non viene visualizzato nulla, nemmeno il markup HTML che normalmente circonda un campo. Il valore predefinito per DisplayValue è true.

È possibile usare l'attributo HiddenInputAttribute negli scenari seguenti:

  • Quando una visualizzazione consente agli utenti di modificare l'ID di un oggetto ed è necessario visualizzare il valore e fornire un elemento di input nascosto che contiene l'ID precedente in modo che possa essere passato al controller.
  • Quando una visualizzazione consente agli utenti di modificare una proprietà binaria che non deve mai essere visualizzata, ad esempio una proprietà timestamp. In tal caso, il valore e il markup HTML circostante (ad esempio l'etichetta e il valore) non vengono visualizzati.

Nell'esempio seguente viene illustrato come usare la classe HiddenInputAttribute.

public class ProductViewModel {
    [HiddenInput] // equivalent to [HiddenInput(DisplayValue=true)]
    public int Id { get; set; }

    public string Name { get; set; }

    [HiddenInput(DisplayValue=false)]
    public byte[] TimeStamp { get; set; }
}

Quando l'attributo è impostato su true (o non viene specificato alcun parametro), si verifica quanto segue:

  • Nei modelli di visualizzazione viene eseguito il rendering di un'etichetta e il valore viene visualizzato all'utente.
  • Nei modelli dell'editor viene eseguito il rendering di un'etichetta e viene eseguito il rendering del valore in un elemento di input nascosto.

Quando l'attributo è impostato su false, si verifica quanto segue:

  • Nei modelli di visualizzazione non viene eseguito alcun rendering per tale campo.
  • Nei modelli dell'editor non viene eseguito il rendering di alcuna etichetta e il rendering del valore viene eseguito in un elemento di input nascosto.

Il metodo helper Html.ValidationSummary può visualizzare errori Model-Level

Anziché visualizzare sempre tutti gli errori di convalida, il metodo helper Html.ValidationSummary ha una nuova opzione per visualizzare solo gli errori a livello di modello. In questo modo gli errori a livello di modello devono essere visualizzati nel riepilogo della convalida e negli errori specifici del campo accanto a ogni campo.

Modelli T4 in Visual Studio Genera codice specifico per la versione di destinazione di .NET Framework

Una nuova proprietà è disponibile per i file T4 dall'host MVC T4 ASP.NET che specifica la versione di .NET Framework usata dall'applicazione. Ciò consente ai modelli T4 di generare codice e markup specifici di una versione di .NET Framework. In Visual Studio 2008 il valore è sempre .NET 3.5. In Visual Studio 2010 il valore è .NET 3.5 o .NET 4.

Miglioramenti all'API

In questa sezione vengono descritte le modifiche apportate ai tipi e ai membri MVC ASP.NET esistenti.

  • È stato aggiunto un metodo CreateActionInvoker virtuale protetto nella classe Controller. Questo metodo viene richiamato dalla proprietà ActionInvoker di Controller e consente la creazione di istanze lazy del invoker se non è già impostato alcun invoker.
  • È stato aggiunto un metodo HandleUnauthorizedRequest virtuale protetto nella classe AuthorizeAttribute. Ciò consente ai filtri che derivano da AuthorizeAttribute di controllare il comportamento quando l'autorizzazione ha esito negativo.
  • Aggiunta di un metodo Add(string key, object value) nella classe ValueProviderDictionary. In questo modo è possibile usare la sintassi dell'inizializzatore del dizionario per ValueProviderDictionary, come nell'esempio seguente:
Controller c = new MyController();
c.ValueProvider = new ValueProviderDictionary(null) {
    { "example1", "example1Value" },
    { "example2", "example2Value" },
    { "example3", new int[] { 1, 2, 3 } }
};
  • Aggiunta di un metodo get_object nella classe Sys.Mvc.AjaxContext. Si tratta di un metodo JavaScript simile al metodo get_data, ma se il tipo di contenuto della risposta è application/json, get_object restituisce l'oggetto JSON.
  • Aggiunta di una proprietà ActionDescriptor nella classe AuthorizationContext.
  • Aggiunta di un token UrlParameter.Optional che può essere usato per risolvere i problemi durante l'associazione a un modello che contiene una proprietà ID quando la proprietà è assente in un post di modulo. Per altri dettagli, vedere la voce ASP.NET parametri URL facoltativi di MVC 2 nel blog di Phil Haack.

Modifiche di rilievo

Le modifiche seguenti potrebbero causare errori nelle applicazioni ASP.NET MVC 1.0 esistenti.

Modifica del comportamento di convalida delle proprietà per le classi che implementano IDataErrorInfo

Per gli oggetti modello che usano IDataErrorInfo per eseguire la convalida, ogni proprietà viene convalidata, indipendentemente dal fatto che sia stato impostato un nuovo valore. In ASP.NET MVC 1.0 sono state convalidate solo le proprietà con nuovi valori impostati. In ASP.NET MVC 2, la proprietà Error di IDataErrorInfo viene chiamata solo se tutti i validator di proprietà hanno avuto esito positivo.

Lo script di mapping di script IIS non è più disponibile nel programma di installazione

Lo script di mapping di script IIS è uno script della riga di comando usato per configurare le mappe di script per IIS 6 e per IIS 7 in modalità classica. Lo script di mapping di script non è necessario se si usa Visual Studio Development Server o se si usa IIS 7 in modalità integrata. Gli script sono disponibili come download separato non supportato nel ASP.NET WebStack.

Il metodo helper Html.Substitute in MVC Futures non è più disponibile

A causa delle modifiche apportate al comportamento di rendering dei motori di visualizzazione MVC, il metodo helper Html.Substitute non funziona ed è stato rimosso.

L'interfaccia IValueProvider sostituisce tutti gli usi di IDictionary

Ogni argomento di proprietà o metodo che ha accettato IDictionary in MVC 1.0 ora accetta IValueProvider. Questa modifica influisce solo sulle applicazioni che includono provider di valori personalizzati o strumenti di associazione di modelli personalizzati. Di seguito sono riportati alcuni esempi di proprietà e metodi interessati da questa modifica:

  • Proprietà ValueProvider delle classi ControllerBase e ModelBindingContext.
  • Metodi TryUpdateModel della classe Controller.

Sono state aggiunte nuove classi CSS nel file Site.css

Il file Site.css nei modelli di progetto ASP.NET MVC è stato aggiornato per includere nuovi stili usati dalla funzionalità di convalida e dagli helper con modelli.

Gli helper restituiscono ora un oggetto MvcHtmlString

Per sfruttare i vantaggi della nuova sintassi delle espressioni di codifica HTML in ASP.NET 4, il tipo restituito per gli helper HTML è ora MvcHtmlString anziché una stringa. Se si usa ASP.NET MVC 2 e i nuovi helper in ASP.NET 3.5, non sarà possibile sfruttare la sintassi di codifica HTML; la nuova sintassi è disponibile solo quando si esegue ASP.NET MVC 2 in ASP.NET 4.

JsonResult risponde ora solo alle richieste HTTP POST

Per attenuare gli attacchi di hijack JSON che hanno la possibilità di divulgazione di informazioni, per impostazione predefinita, la classe JsonResult risponde ora solo alle richieste HTTP POST. Le chiamate GET Ajax ai metodi di azione che restituiscono un oggetto JsonResult devono essere modificate in modo da usare POST. Se necessario, è possibile eseguire l'override di questo comportamento impostando la nuova proprietà JsonRequestBehavior di JsonResult. Per altre informazioni sul potenziale exploit, vedere il post di blog Json Hijacking nel blog di Phil Haack.

I setter delle proprietà Model e ModelType in ModelBindingContext sono obsoleti

È stata aggiunta una nuova proprietà ModelMetadata impostabile alla classe ModelBindingContext. La nuova proprietà incapsula sia le proprietà Model che ModelType. Anche se le proprietà Model e ModelType sono obsolete, per la compatibilità con le versioni precedenti i getter della proprietà continuano a funzionare; delegano alla proprietà ModelMetadata per recuperare il valore.

Modifiche apportate alle factory di controller personalizzate di defaultControllerFactory che derivano da esso

La classe DefaultControllerFactory è stata risolta rimuovendo la proprietà RequestContext. Al posto di questa proprietà, l'istanza del contesto della richiesta viene passata ai metodi GetControllerInstance e GetControllerType protetti. Questa modifica influisce sulle factory controller personalizzate che derivano da DefaultControllerFactory.

Le factory di controller personalizzati vengono spesso usate per fornire l'inserimento delle dipendenze per ASP.NET applicazioni MVC. Per aggiornare le factory controller personalizzate per supportare ASP.NET MVC 2, modificare la firma o le firme del metodo in modo che corrispondano alle nuove firme e usare il parametro di contesto della richiesta anziché la proprietà.

"Area" è ora una chiave di route riservata

La stringa "area" nei valori route ora ha un significato speciale in ASP.NET MVC, nello stesso modo in cui "controller" e "action" eseguire. Un'implicazione è che se gli helper HTML vengono forniti con un dizionario di route-value contenente "area", gli helper non aggiungeranno più "area" nella stringa di query.

Se si usa la funzionalità Aree, assicurarsi di non usare {area} come parte dell'URL della route.

Dichiarazione di non responsabilità

Il presente documento è una versione preliminare e può essere modificato in modo sostanziale prima della versione finale commerciale del software qui descritto.

Le informazioni contenute in questo documento rappresentano la posizione attuale di Microsoft Corporation sulle problematiche trattate alla data di pubblicazione. Poiché Microsoft deve rispondere alle mutevoli condizioni del mercato, questo non deve essere interpretato come un impegno da parte di Microsoft, che non garantisce l'accuratezza delle informazioni presentate dopo la data di pubblicazione.

Il presente white paper è fornito solo a scopi informativi. MICROSOFT NON RILASCIA ALCUNA GARANZIA, ESPRESSA, IMPLICITA O LEGALE, IN MERITO ALLE INFORMAZIONI DEL PRESENTE DOCUMENTO.

Il rispetto di tutte le applicabili leggi in materia di copyright è esclusivamente a carico dell'utente. Fermi restando tutti i diritti coperti da copyright, nessuna parte di questa documentazione potrà comunque essere riprodotta o inserita in un sistema di riproduzione o trasmessa in qualsiasi forma e con qualsiasi mezzo (in formato elettronico, meccanico, fotocopia, tramite registrazione o altro) per qualsiasi scopo, senza il permesso scritto di Microsoft Corporation.

Microsoft può essere titolare di brevetti, domande di brevetto, marchi, copyright o altri diritti di proprietà intellettuale relativi all'oggetto della presente documentazione. Salvo quanto espressamente previsto in un contratto scritto di licenza Microsoft, la consegna della presente documentazione non implica la concessione di alcuna licenza su tali brevetti, marchi, copyright o altra proprietà intellettuale.

Se non diversamente indicato, le aziende di esempio, le organizzazioni, i prodotti, i nomi di dominio, gli indirizzi di posta elettronica, i logo, le persone, i luoghi e gli eventi illustrati di seguito sono fittizi e non è prevista alcuna associazione con alcuna società, organizzazione, prodotto, prodotto, nome di dominio, indirizzo di posta elettronica, logo, persona, luogo o evento.

© 2010 Microsoft Corporation. Tutti i diritti sono riservati.

Microsoft e Windows sono marchi registrati o marchi di Microsoft Corporation negli Stati Uniti e/o in altri paesi.

I nomi di società e prodotti reali citati nel presente documento possono essere marchi dei rispettivi proprietari.