Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este documento proporciona información general sobre muchas de las nuevas características de ASP.NET incluidas en the.NET Framework 4 y en Visual Studio 2010.
Contents
Servicios principales
Refactorización de archivos Web.config
Almacenamiento en caché de salida extensible
Inicio automático de aplicaciones web
Redirigir permanentemente una página
Reducir el estado de sesión
Expandir el intervalo de direcciones URL permitidas
Validación extensible de solicitudes
Extensibilidad del almacenamiento en caché de objetos y almacenamiento en caché de objetos
Codificación extensible de HTML, URL y Encabezado HTTP
Monitor de rendimiento para Aplicaciones individuales en un único proceso de trabajo
Compatibilidad con múltiples versiones
Ajax
jQuery incluido con formularios Web Forms y MVC
Asistencia a Content Delivery Network
Scripts explícitos de ScriptManager
Formularios Web Forms
Establecimiento de meta etiquetas con las propiedades Page.MetaKeywords y Page.MetaDescription
Habilitación del estado de vista para controles individuales
Cambios en las funcionalidades del explorador
Enrutamiento en ASP.NET 4
Establecer identificadores de cliente
Conservar la selección de filas en controles de datos
Chart Control de ASP.NET
Filtrado de datos con el control QueryExtender
Expresiones codificadas con código HTML
Cambios en la plantilla de proyecto
Mejoras de CSS
Ocultar elementos div alrededor de campos ocultos
Representación de una tabla externa para controles basados en modelos
Mejoras de Control ListView
Mejoras de Control CheckBoxList y RadioButtonList
Mejoras de Control Menu
Asistente y CreateUserWizard Controles 56
ASP.NET MVC (Más información sobre ASP.NET MVC)
Soporte técnico para áreas
Soporte técnico para la validación de atributos de anotación de datos
Asistentes con plantilla
Datos dinámicos
Habilitación de datos dinámicos para proyectos existentes
Sintaxis de control DynamicDataManager declarativa
Plantillas de entidad
Nuevas plantillas de campo para direcciones URL y direcciones de correo electrónico
Crear vínculos con el control DynamicHyperLink
Implementar la herencia en el modelo de datos
Compatibilidad con relaciones de varios a varios (solo Entity Framework)
Nuevos atributos para controlar las enumeraciones de visualización y soporte técnico
Compatibilidad mejorada con filtros
Mejoras en el desarrollo web de Visual Studio 2010
Compatibilidad de CSS mejorada
Fragmentos de código HTML y JavaScript
Mejoras de IntelliSense de JavaScript
Implementación de aplicaciones web con Visual Studio 2010
Empaquetado web
Transformación de Web.config
Implementación de base de datos
Publicación con un solo clic para Aplicaciones web
Recursos
Declinación de responsabilidades
Servicios principales
ASP.NET 4 presenta una serie de características que mejoran los servicios principales ASP.NET, como el almacenamiento en caché de salida y el almacenamiento de estado de sesión.
Refactorización de archivos Web.config
El archivo Web.config
que contiene la configuración de una aplicación web ha crecido considerablemente en las últimas versiones de .NET Framework, ya que se han agregado nuevas características, como Asynchronous JavaScript And XML, enrutamiento e integración con IIS 7. Esto ha hecho que sea más difícil configurar o iniciar nuevas aplicaciones web sin herramientas como Visual Studio. Los elementos de configuración principales en .the NET Framework 4 se han movido al archivo machine.config
y las aplicaciones ahora heredan esta configuración. Esto permite que el archivo Web.config
en aplicaciones de ASP.NET 4 esté vacío o contenga solo las siguientes líneas, que especifican para Visual Studio qué versión del marco de trabajo es el destino de la aplicación:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation targetFramework="4.0" />
</system.web>
</configuration>
Almacenamiento en caché de salida extensible
Desde que se publicó ASP.NET 1.0, el almacenamiento en caché de salida ha permitido a los desarrolladores almacenar la salida generada de páginas, controles y respuestas HTTP en memoria. En las solicitudes web posteriores, ASP.NET puede servir contenido más rápidamente recuperando la salida generada de la memoria en lugar de regenerar la salida desde cero. Sin embargo, este enfoque tiene una limitación: el contenido generado debe almacenarse siempre en la memoria; en los servidores que experimentan un tráfico intensivo la memoria consumida por el almacenamiento en caché de salida puede competir con las demandas de memoria de otras partes de una aplicación web.
ASP.NET 4 agrega un punto de extensibilidad al almacenamiento en caché de salida que permite configurar uno o varios proveedores personalizados de caché de salida. Los proveedores de caché de salida pueden usar cualquier mecanismo de almacenamiento para conservar el contenido HTML. Esto permite personalizar proveedores de caché de salida para diversos mecanismos de persistencia que pueden incluir discos locales o remotos, almacenamiento en la nube y motores de caché distribuida.
Se crea un proveedor de caché de salida personalizado como una clase que deriva del nuevo tipo System.Web.Caching.OutputCacheProvider. Puede configurar el proveedor en el archivo Web.config
mediante la subsección nuevos proveedores del elemento outputCache, como se muestra en este ejemplo:
<caching>
<outputCache defaultProvider="AspNetInternalProvider">
<providers>
<add name="DiskCache"
type="Test.OutputCacheEx.DiskOutputCacheProvider, DiskCacheProvider"/>
</providers>
</outputCache>
</caching>
De forma predeterminada, todas las respuestas HTTP, las páginas representadas y los controles en ASP.NET 4 usan la caché de salida en memoria, como en el ejemplo anterior, donde el atributo defaultProvider se establece en AspNetInternalProvider. Puede cambiar el proveedor de caché de salida predeterminado que se usa para una aplicación web especificando un nombre de proveedor diferente para defaultProvider.
Además, puede seleccionar diferentes proveedores de caché de salida para cada control y solicitud. La manera más fácil de elegir un proveedor de caché de salida diferente para distintos controles de usuario web es hacerlo mediante declaración con el nuevo atributo providerName en una directiva de control, como se muestra en este ejemplo:
<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>
Especificar un proveedor de caché de salida diferente para una solicitud HTTP es un poco más trabajoso. En lugar de especificar mediante declaración el proveedor, invalida el nuevo método GetOuputCacheProviderName en el archivo Global.asax
para especificar mediante programación qué proveedor se va a usar para una solicitud específica. El ejemplo siguiente muestra cómo hacerlo.
public override string GetOutputCacheProviderName(HttpContext context)
{
if (context.Request.Path.EndsWith("Advanced.aspx"))
return "DiskCache";
else
return base.GetOutputCacheProviderName(context);
}
Ahora puede seguir estrategias de almacenamiento en caché de salida más absolutas e inteligentes para los sitios web gracias a la extensibilidad del proveedor de caché de salida a ASP.NET 4. Por ejemplo, ahora es posible almacenar en caché las páginas "Top 10" de un sitio en la memoria, mientras se copian en caché páginas que obtienen un menor tráfico en el disco. También puede almacenar en caché cada combinación vary-by para una página representada, pero usar una caché distribuida para que el consumo de memoria se descargue de los servidores web front-end.
Inicio automático de aplicaciones web
Algunas aplicaciones web necesitan cargar grandes cantidades de datos o realizar un procesamiento de inicialización costoso antes de atender la primera solicitud. En versiones anteriores de ASP.NET, en estas situaciones se tenía que diseñar enfoques personalizados para "reactivar" una aplicación ASP.NET y después ejecutar un código de inicialización durante el método Application_Load en el archivo Global.asax
.
Hay disponible una nueva característica de escalabilidad denominada inicio automático que aborda directamente este escenario cuando ASP.NET 4 se ejecuta en IIS 7.5 en Windows Server 2008 R2. La característica de inicio automático proporciona un enfoque controlado para iniciar un grupo de aplicaciones, inicializar una aplicación ASP.NET y después aceptar solicitudes HTTP.
Nota:
Módulo de preparación de aplicación IIS para IIS 7.5
El equipo de IIS ha publicado la primera versión de prueba beta del módulo de preparación de aplicación para IIS 7.5. Esto hace que el calentamiento de sus aplicaciones sea aún más fácil de lo descrito anteriormente. En lugar de escribir un código personalizado, especifique las direcciones URL de los recursos que se van a ejecutar antes de que la aplicación web acepte las solicitudes de la red. Este proceso de preparación se produce durante el inicio del servicio IIS (si configuró el grupo de aplicaciones IIS como AlwaysRunning) y cuando se recicla un proceso de trabajo de IIS. Durante el reciclaje, el anterior proceso de trabajo de IIS continúa ejecutando solicitudes hasta que el proceso de trabajo recién generado está totalmente caliente, de modo que las aplicaciones no experimenten interrupciones ni otros problemas debido a cachés en mal estado. Tenga en cuenta que este módulo funciona con cualquier versión de ASP.NET (a partir de la versión 2.0).
Para más información, consulte Preparación de aplicaciones en el sitio web de IIS.net. Para ver un tutorial sobre cómo usar la característica de preparación, consulte Introducción al módulo de preparación de aplicaciones de IIS 7.5 en el sitio web de IIS.net.
Para usar la característica de inicio automático, un administrador de IIS establece un grupo de aplicaciones en IIS 7.5 para que se inicie automáticamente mediante la siguiente configuración en el archivo applicationHost.config
:
<applicationpools>
<add name="MyApplicationPool" startMode="AlwaysRunning" />
</applicationpools>
Dado que un único grupo de aplicaciones puede contener varias aplicaciones, especifique que las aplicaciones individuales se inicien automáticamente mediante la siguiente configuración en el archivo applicationHost.config
:
<sites>
<site name="MySite" id="1">
<application path="/"
serviceAutoStartEnabled="true"
serviceAutoStartProvider="PrewarmMyCache" >
<!-- Additional content -->
</application>
</site>
</sites>
<!-- Additional content -->
<serviceautostartproviders>
<add name="PrewarmMyCache"
type="MyNamespace.CustomInitialization, MyLibrary" />
</serviceautostartproviders>
Cuando se arranca en frío un servidor IIS 7.5 o cuando se recicla un grupo de aplicaciones individual, IIS 7.5 usa la información del archivo applicationHost.config
para determinar qué aplicaciones web deben iniciarse automáticamente. Para cada aplicación marcada para inicio automático, IIS7.5 envía una solicitud a ASP.NET 4 para iniciar la aplicación en un estado durante el cual la aplicación no acepta temporalmente solicitudes HTTP. Cuando se encuentra en este estado, ASP.NET crea una instancia del tipo definido por el atributo serviceAutoStartProvider (como en el ejemplo anterior)y llama a su punto de entrada público.
Cree un tipo de inicio automático administrado con el punto de entrada necesario mediante la implementación de la interfaz IProcessHostPreloadClient, como se muestra en este ejemplo:
public class CustomInitialization : System.Web.Hosting.IProcessHostPreloadClient
{
public void Preload(string[] parameters)
{
// Perform initialization.
}
}
Una vez que el código de inicialización se ejecuta en el método Preload y el método devuelve, la aplicación ASP.NET está lista para procesar solicitudes.
Con la incorporación del inicio automático a IIS .5 y ASP.NET 4, ahora usted tiene un enfoque bien definido para realizar una inicialización de aplicación costosa antes de procesar la primera solicitud HTTP. Por ejemplo, puede usar la nueva característica de inicio automático para inicializar una aplicación y después indicar un equilibrador de carga que la aplicación se inicializó y listo para aceptar el tráfico HTTP.
Redirigir permanentemente a una página
Es habitual que las aplicaciones web muevan páginas y otro contenido con el tiempo, lo que puede provocar una acumulación de enlaces obsoletos en los motores de búsqueda. En ASP.NET, los desarrolladores han controlado tradicionalmente las solicitudes a direcciones URL antiguas mediante el método Response.Redirect para reenviar una solicitud a la nueva dirección URL. Sin embargo, el método Redirect emite una respuesta HTTP 302 Found (redirección temporal), lo que da como resultado un recorrido HTTP más de ida y vuelta cuando los usuarios intentan acceder a las direcciones URL antiguas.
ASP.NET 4 agrega un nuevo método auxiliar RedirectPermanent que facilita la emisión de respuestas HTTP 301 Movel Permanently, como en este ejemplo:
RedirectPermanent("/newpath/foroldcontent.aspx");
Los motores de búsqueda y otros agentes de usuario que reconocen redirecciones permanentes almacenarán la nueva dirección URL asociada al contenido, lo que elimina el recorrido de ida y vuelta innecesario del explorador para las redirecciones temporales.
Reducir el Estado de sesión
ASP.NET proporciona dos opciones predeterminadas para almacenar el estado de sesión en una granja de servidores web: un proveedor de estado de sesión que invoca un servidor de estado de sesión fuera de proceso y un proveedor de estado de sesión que almacena datos en una base de datos de Microsoft SQL Server. Ya que ambas opciones implican almacenar información de estado fuera del proceso de trabajo de una aplicación web, el estado de sesión debe serializarse antes de enviarlo al almacenamiento remoto. Dependiendo de la cantidad de información que guarde un desarrollador en estado de sesión, el tamaño de los datos serializados puede crecer bastante.
ASP.NET 4 presenta una nueva opción de compresión para ambos tipos de proveedores de estado de sesión fuera del proceso. Si la opción de configuración compressionEnabled que se muestra en el ejemplo siguiente se establece en true, ASP.NET comprimirá (y descomprimirá) el estado de sesión serializado con la clase de .NET Framework System.IO.Compression.GZipStream .
<sessionState
mode="SqlServer"
sqlConnectionString="data source=dbserver;Initial Catalog=aspnetstate"
allowCustomSqlDatabase="true"
compressionEnabled="true"
/>
Con la sencilla incorporación del nuevo atributo al archivo Web.config
, las aplicaciones con ciclos de CPU de reserva en los servidores web pueden lograr reducciones considerables en el tamaño de los datos serializados de estado de sesión.
Expandir el intervalo de direcciones URL permitidas
ASP.NET 4 presenta nuevas opciones para expandir el tamaño de las direcciones URL de la aplicación. Las versiones anteriores de ASP.NET limitaban la longitud de las rutas URL a 260 caracteres, basándose en el límite de rutas de archivo NTFS. En ASP.NET 4 usted tiene la opción de aumentar (o disminuir) este límite según en sus para las aplicaciones, mediante dos nuevos atributos de configuración httpRuntime. En el siguiente ejemplo se muestran esos nuevos atributos.
<httpRuntime maxUrlLength="260" maxQueryStringLength="2048" />
Para permitir rutas de acceso más largas o cortas (la parte de la dirección URL que no incluye el protocolo, el nombre del servidor y la cadena de consulta), modifique el atributo maxUrlLength. Para permitir cadenas de consulta más largas o más cortas, modifique el valor del atributo maxQueryStringLength.
ASP.NET 4 también le permite configurar los caracteres que usa la comprobación de caracteres de URL. Cuando ASP.NET encuentra un caracter no válido en la parte de la ruta de acceso de una URL, rechaza la solicitud y emite un error HTTP 400. En versiones anteriores de ASP.NET las comprobaciones de caracteres de URL estaban limitadas a un conjunto fijo de caracteres. Puede personalizar el conjunto de caracteres válidos en ASP.NET 4 mediante el nuevo atributo requestPathInvalidCharacters del elemento de configuración httpRuntime, como se muestra en el ejemplo siguiente:
<httpRuntime requestPathInvalidCharacters="<,>,*,%,&,:,\,?" />
De forma predeterminada, el atributo requestPathInvalidCharacters define ocho caracteres como no válidos. (En la cadena asignada a requestPathInvalidCharacters de forma predeterminada, el conjunto de caracteres menor que (<), mayor que (>) y (&) se codifican porque el archivo Web.config
es un archivo XML). Puede personalizar el conjunto de caracteres no válidos según sea necesario.
Nota:
Tenga en cuenta que ASP.NET 4 siempre rechaza las rutas de acceso de URL que contienen caracteres en el intervalo ASCII de 0x00 a 0x1F, ya que son caracteres de dirección URL no válidos, tal como se define en RFC 2396 del IETF (http://www.ietf.org/rfc/rfc2396.txt). En las versiones de Windows Server que ejecutan IIS 6 o posteriores, el controlador de dispositivo de protocolo http.sys rechaza automáticamente las URL con estos caracteres.
Validación extensible de solicitudes
La validación de solicitudes de ASP.NET busca datos de solicitud HTTP entrantes para cadenas que se usan habitualmente en ataques de scripting entre sitios (XSS). Si se encuentran cadenas XSS potenciales, la validación de solicitudes marca la cadena sospechosa y devuelve un error. La validación de solicitudes integrada devuelve un error solo cuando encuentra las cadenas más comunes usadas en ataques XSS. Los intentos anteriores de hacer que la validación XSS fuera más absoluta dio lugar a demasiados falsos positivos. Sin embargo, es posible que los clientes quieran solicitar una validación más absoluta o, por el contrario, que quieran relajar intencionadamente las comprobaciones XSS para páginas específicas o para determinados tipos de solicitudes.
La característica de validación de solicitudes en ASP.NET 4se ha hecho extensible para que pueda usar la lógica personalizada de validación de solicitudes. Para ampliar la validación de solicitudes, cree una clase que derive del nuevo tipo System.Web.Util.RequestValidator y configure la aplicación (en la sección httpRuntime del archivo Web.config
) para usar el tipo personalizado. En este ejemplo se muestra cómo configurar una clase de validación de solicitud personalizada:
<httpRuntime requestValidationType="Samples.MyValidator, Samples" />
El nuevo atributo requestValidationType requiere una cadena de identificador de tipo de .NET Framework estándar que especifica la clase que proporciona una validación de solicitudes personalizada. ASP.NET invoca el tipo personalizado en cada solicitud para procesar cada parte de los datos de solicitud HTTP entrantes. La dirección URL entrante, todos los encabezados HTTP (tanto cookies como encabezados personalizados) y el cuerpo de la entidad están disponibles para su inspección mediante una clase de validación de solicitudes personalizada como la siguiente:
public class CustomRequestValidation : RequestValidator
{
protected override bool IsValidRequestString(
HttpContext context, string value,
RequestValidationSource requestValidationSource,
string collectionKey,
out int validationFailureIndex)
{...}
}
En los casos que no desee inspeccionar un fragmento de datos HTTP entrantes, la clase de validación de solicitudes puede dejar que se ejecute la validación de solicitudes predeterminada ASP.NET simplemente llamando a base.IsValidRequestString.
Extensibilidad del almacenamiento en caché de objetos y almacenamiento en caché de objetos
Desde su primera versión, ASP.NET ha incluido una potente caché de objetos en memoria (System.Web.Caching.Cache). La implementación de caché ha sido tan popular que se ha utilizado en aplicaciones que no son web. Sin embargo, resulta incómodo que una aplicación de Windows Forms o WPF incluya una referencia a System.Web.dll
solo para poder usar la caché de objetos de ASP.NET.
Para que el almacenamiento en caché esté disponible en todas las aplicaciones, .NET Framework 4 presenta un nuevo ensamblado, un nuevo espacio de nombres, algunos tipos base y una implementación concreta del almacenamiento en caché. El nuevo ensamblado System.Runtime.Caching.dll
contiene una nueva API de almacenamiento en caché en el espacio de nombres System.Runtime.Caching. El espacio de nombres contiene dos conjuntos principales de clases:
- Tipos abstractos que proporcionan la base para crear cualquier tipo de implementación de caché personalizada.
- Implementación concreta de la caché de objetos en memoria (la clase System.Runtime.Caching.MemoryCache).
La nueva clase MemoryCache se modela estrechamente en la caché de ASP.NET y comparte gran parte de la lógica del motor de caché interna con ASP.NET. Aunque las API de almacenamiento en caché públicas de System.Runtime.Caching se han actualizado para admitir el desarrollo de cachés personalizadas, si ha usado el objeto Caché de ASP.NET, encontrará conceptos conocidos en las nuevas API.
Una explicación detallada de la nueva clase MemoryCache y las API base auxiliares requeriría un documento completo. Sin embargo, en el ejemplo siguiente se proporciona una idea sobre cómo funciona la nueva API de caché. El ejemplo se escribió para una aplicación de Windows Forms, sin depender de System.Web.dll
.
private void btnGet_Click(object sender, EventArgs e)
{
//Obtain a reference to the default MemoryCache instance.
//Note that you can create multiple MemoryCache(s) inside
//of a single application.
ObjectCache cache = MemoryCache.Default;
//In this example the cache is storing the contents of a file string
fileContents = cache["filecontents"] as string;
//If the file contents are not currently in the cache, then
//the contents are read from disk and placed in the cache.
if (fileContents == null)
{
//A CacheItemPolicy object holds all the pieces of cache
//dependency and cache expiration metadata related to a single
//cache entry.
CacheItemPolicy policy = new CacheItemPolicy();
//Build up the information necessary to create a file dependency.
//In this case we just need the file path of the file on disk.
List filePaths = new List();
filePaths.Add("c:\\data.txt");
//In the new cache API, dependencies are called "change monitors".
//For this example we want the cache entry to be automatically expired
//if the contents on disk change. A HostFileChangeMonitor provides
//this functionality.
policy.ChangeMonitors.Add(new HostFileChangeMonitor(filePaths));
//Fetch the file's contents
fileContents = File.ReadAllText("c:\\data.txt");
//And then store the file's contents in the cache
cache.Set("filecontents", fileContents, policy);
}
MessageBox.Show(fileContents);
}
Codificación extensible de HTML, URL y Encabezado HTTP
En ASP.NET 4 puede crear rutinas de codificación personalizadas para las siguientes tareas comunes de codificación de texto:
- Codificación HTML.
- Codificación de direcciones URL.
- Codificación del atributo HTML.
- Codificación de encabezados HTTP salientes.
Puede crear un codificador personalizado derivando del nuevo tipo System.Web.Util.HttpEncoder y después, configurando ASP.NET para usar el tipo personalizado en la sección httpRuntime del archivo Web.config
, como se muestra en este ejemplo:
<httpRuntime encoderType="Samples.MyCustomEncoder, Samples" />
Una vez configurado un codificador personalizado, ASP.NET llama automáticamente a la implementación de codificación personalizada cada vez que se llama a los métodos de codificación pública de las clases System.Web.HttpUtility o System.Web.HttpServerUtility. Esto permite que una parte de un equipo de desarrollo web cree un codificador personalizado que implemente una codificación de caracteres absoluta, mientras que el resto del equipo de desarrollo web sigue usando las API de codificación de ASP.NET públicas. Mediante la configuración centralizada de un codificador personalizado en el elemento httpRuntime, se garantiza que todas las llamadas de codificación de texto desde las API de codificación de ASP.NET públicas se enrutan a través del codificador personalizado.
Monitor de rendimiento para Aplicaciones individuales en un único proceso de trabajo
Para aumentar el número de sitios web que se pueden hospedar en un solo servidor, muchos anfitriones ejecutan varias aplicaciones ASP.NET en un único proceso de trabajo. Sin embargo, si varias aplicaciones usan un único proceso de trabajo compartido, es difícil que los administradores del servidor identifiquen una aplicación individual que esté experimentando problemas.
ASP.NET 4 aprovecha la nueva funcionalidad de supervisión de recursos introducida por CLR. Para habilitar esta funcionalidad, puede agregar el siguiente fragmento de código de configuración XML al archivo de configuraciónaspnet.config
.
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<runtime>
<appDomainResourceMonitoring enabled="true"/>
</runtime>
</configuration>
Nota:
Nota: el archivo aspnet.config
está en el directorio donde está instalado .NET Framework. No es el archivo Web.config
.
Cuando se habilita la característica appDomainResourceMonitoring, hay dos nuevos contadores de rendimiento disponibles en la categoría de rendimiento "Aplicaciones ASP.NET": % de tiempo de procesador administrado y Memoria administrada usada. Ambos contadores de rendimiento usan la nueva característica de administración de recursos de dominio de aplicación CLR para realizar un seguimiento del tiempo estimado de CPU y el uso de memoria administrada de aplicaciones individuales ASP.NET. Como resultado, ahora los administradores con ASP.NET 4 tienen una vista más detallada del consumo de recursos de las aplicaciones individuales que se ejecutan en un único proceso de trabajo.
Compatibilidad con múltiples versiones (multi-targeting)
Puede crear una aplicación que tenga como destino una versión concreta de .NET Framework. En ASP.NET 4, un nuevo atributo del elemento compilación del archivo Web.config
le permite tener como destino a .NET Framework 4 y versiones posteriores. Si tiene como destino explícitamente .NET Framework 4 y si usted incluye elementos opcionales en el archivo Web.config
, como las entradas de system.codedom, estos elementos deben ser correctos para .NET Framework 4. (Si no tiene como destino explícitamente .NET Framework 4, la plataforma de destino se deduce por la falta de una entrada en el archivo Web.config
).
En el siguiente ejemplo se muestra el uso del atributo targetFramework en el elemento de compilación del archivo Web.config
.
<compilation targetFramework="4.0"/>
Tenga en cuenta esto sobre el destino de una versión específica de .NET Framework:
- En un grupo de aplicaciones de .NET Framework 4, el sistema de compilación de ASP.NET asume .NET Framework 4 como destino si el archivo
Web.config
no incluye el atributo targetFramework o si falta el archivoWeb.config
. (Es posible que tenga que realizar cambios de codificación en la aplicación para que se ejecute con .NET Framework 4). - Si incluye el atributo targetFramework y si el elemento system.codeDom se define en el archivo
Web.config
, este archivo debe contener las entradas correctas para .NET Framework 4. - Si usa el comando aspnet_compiler para precompilar la aplicación (por ejemplo, en un entorno de compilación), debe usar la versión correcta del comando aspnet_compiler para la plataforma de destino. Use el compilador incluido con .NET Framework 2.0 (%WINDIR%\Microsoft.NET\Framework\v2.0.50727) para compilar para .NET Framework 3.5 y versiones anteriores. Use el compilador incluido con .NET Framework 4 para compilar aplicaciones creadas con ese marco o con versiones posteriores.
- Durante el tiempo de ejecución, el compilador usa los ensamblados de marco más recientes que se instalan en el equipo (y, por tanto, en la GAC). Si se realiza una actualización más adelante en el marco (por ejemplo, se instala una versión hipotética 4.1), podrá usar características en la versión más reciente del marco aunque el atributo targetFramework tenga como destino una versión inferior (como la 4.0). (Sin embargo,durante el tiempo de diseño en Visual Studio 2010 o cuando se usa el comando aspnet_compiler, el uso de características más recientes del marco provocará errores en el compilador).
Ajax
jQuery incluido con formularios Web Forms y MVC
Las plantillas de Visual Studio para Web Forms y MVC incluyen la biblioteca jQuery de código abierto. Al crear un nuevo sitio web o proyecto, se crea una carpeta Scripts que contiene estos tres archivos:
- jQuery-1.4.1.js: la versión legible y desminificada de la biblioteca de jQuery.
- jQuery-14.1.min.js: la versión desminificada de la biblioteca de jQuery.
- jQuery-1.4.1-vsdoc.js: la documentación de IntelliSense para la biblioteca jQuery.
Incluya la versión desminificada de jQuery al desarrollar una aplicación. Incluya la versión minificada de jQuery para aplicaciones de producción.
Por ejemplo, la siguiente página de formularios Web Forms muestra cómo puede usar jQuery para cambiar el color de fondo de los controles TextBox de ASP.NET a amarillo cuando tienen el foco.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ShowjQuery.aspx.cs" Inherits="ShowjQuery" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Show jQuery</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtFirstName" runat="server" />
<br />
<asp:TextBox ID="txtLastName" runat="server" />
</div>
</form>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script type="text/javascript">
$("input").focus( function() { $(this).css("background-color", "yellow"); });
</script>
</body>
</html>
Asistencia a Content Delivery Network
Microsoft AJAX Content Delivery Network (CDN) le permite agregar fácilmente ASP.NET scripts Asynchronous JavaScript And XML y jQuery a las aplicaciones web. Por ejemplo, puede empezar a usar la biblioteca de jQuery simplemente agregando una etiqueta <script>
a la página que apunta a Ajax.microsoft.com de la siguiente manera:
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.4.2.js" type="text/javascript"></script>
Aprovechando CDN de Microsoft Asynchronous JavaScript And XML, puede mejorar significativamente el rendimiento de las aplicaciones AJAX. El contenido de CDN de Microsoft AJAX se almacena en memoria caché en servidores que se encuentran en todo el mundo. Además, CDN de Microsoft AJAX permite que los exploradores reutilicen los archivos JavaScript copiados en caché para los sitios web que se encuentran en diferentes dominios.
Content Delivery Network de Microsoft AJAX admite SSL (HTTPS) en caso de que necesite servir una página web mediante la Capa de sockets seguros.
Implemente una reserva cuando la red CDN no esté disponible. Pruebe la reserva.
Para más información sobre la red CDN de Microsoft AJAX, visite este sitio web:
https://www.asp.net/ajaxlibrary/CDN.ashx
El ScriptManager de ASP.NET admite la red CDN de Microsoft AJAX. Con solo establecer la propiedad EnableCdn puede recuperar todos los archivos JavaScript del marco de ASP.NET de la red CDN:
<asp:ScriptManager ID="sm1" EnableCdn="true" runat="server" />
Tras establecer la propiedad EnableCdn en el valor true, el marco de ASP.NET recuperará todos los archivos JavaScript del marco ASP.NET de la red CDN, incluidos todos los archivos JavaScript usados para la validación y UpdatePanel. Establecer esta propiedad puede tener un fuerte impacto en el rendimiento de la aplicación web.
Puede establecer la ruta de acceso de la red CDN para sus propios archivos JavaScript mediante el atributo WebResource. La nueva propiedad CdnPath especifica la ruta de acceso a la red CDN usada al establecer la propiedad EnableCdn en el valor true:
[assembly: WebResource("Foo.js", "application/x-javascript", CdnPath = "http://foo.com/foo/bar/foo.js")]
Scripts explícitos de ScriptManager
Si anteriormente usó el ASP.NET ScriptManger, entonces necesitó cargar toda la biblioteca monolítica AJAX ASP.NET. Si aprovecha la nueva propiedad ScriptManager.AjaxFrameworkMode, puede controlar exactamente qué componentes se cargan de la biblioteca de AJAX de ASP.NET y cargan solo los componentes de la biblioteca de ASP.NET AJAX necesarios.
La propiedad ScriptManager.AjaxFrameworkMode se puede establecer con los valores siguientes:
- Habilitado: especifica que el control ScriptManager incluye automáticamente el archivo de script de MicrosoftAjax.js, que es un archivo de script combinado de cada script de marco principal (comportamiento heredado).
- Deshabilitado: especifica que todas las características de script de Microsoft AJAX están deshabilitadas y que el control ScriptManager no hace automáticamente referencia a ningún script.
- Explícito: especifica que incluirá explícitamente referencias de script al archivo de script principal de marco individual que requiere su página y que usted incluirá referencias a las dependencias que requiere cada archivo de script.
Por ejemplo, si establece la propiedad AjaxFrameworkMode en el valor Explicit, puede especificar los scripts de componentes de AJAX concretos ASP.NET que necesita:
<asp:ScriptManager ID="sm1" AjaxFrameworkMode="Explicit" runat="server">
<Scripts>
<asp:ScriptReference Name="MicrosoftAjaxCore.js" />
<asp:ScriptReference Name="MicrosoftAjaxComponentModel.js" />
<asp:ScriptReference Name="MicrosoftAjaxSerialization.js" />
<asp:ScriptReference Name="MicrosoftAjaxNetwork.js" />
</Scripts>
</asp:ScriptManager>
Web Forms
Web Forms ha sido una característica principal de ASP.NET desde la versión de ASP.NET 1.0. Se han realizado muchas mejoras en esta área para ASP.NET 4, incluyendo:
- La capacidad de establecer etiquetas meta.
- Más control sobre el estado de visualización.
- Formas más sencillas de trabajar con las funcionalidades del explorador.
- Compatibilidad con el uso de ASP.NET enrutamiento con formularios Web Forms.
- Más control sobre los identificadores generados.
- La capacidad de conservar las filas seleccionadas en los controles de datos.
- Más control sobre HTML representado en los controles FormView y ListView.
- Compatibilidad del filtrado de controles de origen de datos.
Establecer etiquetas META con las propiedades Page.MetaKeywords y Page.MetaDescription
ASP.NET 4 agrega dos propiedades a la clase Page, MetaKeywords y MetaDescription. Estas dos propiedades representan las etiquetas META correspondientes a su página, como se muestra aquí:
<head id="Head1" runat="server">
<title>Untitled Page</title>
<meta name="keywords" content="These, are, my, keywords" />
<meta name="description" content="This is the description of my page" />
</head>
Estas dos propiedades funcionan de la misma manera que la propiedad Title de la página. Siguen estas reglas:
- Si no hay etiquetas META en el elemento encabezado que coincidan con los nombres de propiedad (es decir, name="keywords" para Page.MetaKeywords y name="description" para Page.MetaDescription, lo que significa que estas propiedades no se han establecido), las etiquetas META se agregarán a la página cuando se represente.
- Si ya hay etiquetas META con estos nombres, estas propiedades actúan como métodos get y set para el contenido de las etiquetas existentes.
Puede establecer estas propiedades durante el tiempo de ejecución, lo que le permite obtener el contenido de una base de datos u otro origen y establecer las etiquetas dinámicamente para describir lo que es una página determinada.
También puede establecer las propiedades Palabras clave y Descripción de la directiva @ Page en la parte superior del marcado de página de Formularios Web Forms, como en este ejemplo:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
Keywords="These, are, my, keywords"
Description="This is a description" %>
Esto invalidará el contenido de la etiqueta META (si existe) ya declarado en la página.
El contenido de la etiqueta META descriptiva se usa para mejorar las vistas previas de la descripción de búsqueda en Google. (Para más información, consulte Mejora de fragmentos de código con una meta description makeover en el blog de Google Webmaster Central). Google y Windows Live Search no usan el contenido de las palabras clave, pero otros motores de búsqueda podrían.
Estas nuevas propiedades son una característica sencilla, pero le ahorran el requisito de agregarlas manualmente o de escribir su propio código para crear las etiquetas META.
Habilitación del estado de vista para controles individuales
El estado de visualización está habilitado para la página de forma predeterminada, así que cada control de la página almacene potencialmente el estado de visualización aunque no sea necesario para la aplicación. Los datos de estado de visualización se incluyen en el marcado que genera una página y aumenta la cantidad de tiempo que se tarda en enviar una página al cliente y volver a publicarlos. Almacenar más estado de visualización de lo necesario puede provocar una degradación significativa del rendimiento. En versiones anteriores de ASP.NET, los desarrolladores podían deshabilitar el estado de visualización de los controles individuales para reducir el tamaño de página, pero tenían que hacerlo explícitamente para controles individuales. En ASP.NET 4, los controles de servidor web incluyen una propiedad ViewStateMode que permite deshabilitar el estado de visualización de forma predeterminada y después habilitarlo solo para los controles que lo requieran en la página.
La propiedad ViewStateMode toma una enumeración que tiene tres valores: Enabled, Disabled y Inherit. Habilitado habilita el estado de vista para ese control y para los controles secundarios que se establecen en Heredar o que no tienen nada establecido. Deshabilitado deshabilita el estado de vista y Heredar especifica que el control usa la configuración ViewStateMode del control primario.
En el ejemplo siguiente se muestra cómo funciona la propiedad ViewStateMode. El marcado y el código de los controles de la página siguiente incluyen valores para la propiedad ViewStateMode:
<form id="form1" runat="server">
<script runat="server">
protected override void OnLoad(EventArgs e) {
if (!IsPostBack) {
label1.Text = label2.Text = "[DynamicValue]";
}
base.OnLoad(e);
}
</script>
<asp:PlaceHolder ID="PlaceHolder1" runat="server" ViewStateMode="Disabled">
Disabled: <asp:Label ID="label1" runat="server" Text="[DeclaredValue]" /><br />
<asp:PlaceHolder ID="PlaceHolder2" runat="server" ViewStateMode="Enabled">
Enabled: <asp:Label ID="label2" runat="server" Text="[DeclaredValue]" />
</asp:PlaceHolder>
</asp:PlaceHolder>
<hr />
<asp:button ID="Button1" runat="server" Text="Postback" />
<%-- Further markup here --%>
Como puede ver, el código deshabilita el estado de visualización del control PlaceHolder1. El control label1 secundario hereda este valor de propiedad (Heredar es el valor predeterminado de ViewStateMode para los controles). Por lo tanto, no guarda ningún estado de vista. En el control PlaceHolder2, ViewStateMode se establece en Habilitado, por lo que label2 hereda esta propiedad y guarda el estado de visualización. Cuando la página se carga por primera vez, la propiedad Text de ambos controles Label se establece en la cadena "[DynamicValue]".
El efecto de esta configuración es que cuando la página se carga por primera vez, se muestra esta salida en el explorador:
: [DynamicValue]
deshabilitado
[DynamicValue]
: habilitado
Sin embargo, después de un postback se muestra esta salida:
: [DeclaredValue]
deshabilitado
[DynamicValue]
: habilitado
El control label1 (cuyo valor ViewStateMode está establecido en Deshabilitado) no ha conservado el valor establecido en el código. Sin embargo, el control label2 (cuyo valor ViewStateMode está establecido en Habilitado) ha conservado su estado.
También puede establecer ViewStateMode en la directiva @ Page, como en el ejemplo siguiente:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="Default.aspx.cs"
Inherits="WebApplication1._Default"
ViewStateMode="Disabled" %>
La clase Page es solo otro control, actúa como control primario para todos los demás controles de la página. El valor predeterminado de ViewStateMode es Habilitado para instancias de Page. Dado que los controles de forma predeterminada Heredar los controles heredarán el valor de la propiedad Habilitado a menos que establezca ViewStateMode en el nivel de página o control.
El valor de la propiedad ViewStateMode determina si el estado de vista se mantiene solo si la propiedad EnableViewState está establecida en true. Si la propiedad EnableViewState está establecida en false, el estado de vista no se mantendrá aunque ViewStateMode esté establecido en Habilitado.
Un buen uso de esta característica es con controles ContentPlaceHolder en páginas maestras, donde puede establecer ViewStateMode en Deshabilitado para la página maestra y después habilitarlo individualmente para los controles ContentPlaceHolder que, a su vez, contienen controles que requieren estado de visualización.
Cambios en las funcionalidades del explorador
ASP.NET determina las funcionalidades del explorador que usa un usuario para examinar el sitio mediante una característica denominada funcionalidades del explorador. Las funcionalidades del explorador se representan mediante el objeto HttpBrowserCapabilities (expuesto por la propiedad Request.Browser). Por ejemplo, puede usar el objeto HttpBrowserCapabilities para determinar si el tipo y la versión del explorador actual admiten una versión determinada de JavaScript. O bien, puede usar el objeto HttpBrowserCapabilities para determinar si la solicitud se originó desde un dispositivo móvil.
El objeto HttpBrowserCapabilities está controlado por un conjunto de archivos de definición de explorador. Estos archivos contienen información sobre las funcionalidades de determinados exploradores. En ASP.NET 4 estos archivos de definición de navegador se han actualizado para contener información sobre navegadores y dispositivos introducidos recientemente, como Google Chrome, Research in Motion BlackBerry smartphones y Apple iPhone.
La siguiente lista muestra nuevos archivos de definición de explorador:
- blackberry.browser
- chrome.browser
- Default.browser
- firefox.browser
- gateway.browser
- generic.browser
- ie.browser
- iemobile.browser
- iphone.browser
- opera.browser
- safari.browser
Uso de proveedores de funcionalidades del explorador
En ASP.NET versión 3.5 Service Pack 1 puede definir las capacidades que tiene un explorador de las siguientes maneras:
En el nivel de equipo, creará o actualizará un archivo XML
.browser
en esta carpeta:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers
Después de definir la funcionalidad del explorador, ejecute el siguiente comando desde el símbolo del sistema de Visual Studio para volver a generar el ensamblado de funcionalidades del explorador y agregarlo a la GAC:
aspnet_regbrowsers.exe -I c
Para una aplicación individual, cree un archivo
.browser
en la carpetaApp_Browsers
de la aplicación.
Estos enfoques requieren que cambie los archivos XML y, para los cambios de nivel de equipo, debe reiniciar la aplicación después de ejecutar el proceso de aspnet_regbrowsers.exe.
ASP.NET 4 incluye una característica denominada proveedores de funcionalidades del explorador. Como sugiere el nombre, esto le permite crear un proveedor que, a su vez, le permite usar su propio código para determinar las funcionalidades del explorador.
En la práctica, los desarrolladores a menudo no definen funcionalidades de explorador personalizadas. Los archivos del explorador son difíciles de actualizar, el proceso para actualizarlos es bastante complicado y la sintaxis XML de los archivos .browser
puede ser compleja de usar y definir. Este proceso sería más fácil si hubiera una sintaxis de definición de explorador común, una base de datos que contuviera definiciones de explorador actualizadas o incluso un servicio web para dicha base de datos. La nueva característica de proveedores de funcionalidades del explorador hace que estos escenarios sean posibles y prácticos para los desarrolladores de terceros.
Hay dos enfoques principales para usar la nueva característica del proveedor de funcionalidades del explorador ASP.NET 4: ampliar la funcionalidad de definición de funcionalidades del explorador ASP.NET o reemplazarla totalmente. En las siguientes secciones se describe primero cómo reemplazar la funcionalidad y luego cómo ampliarla.
Reemplazar la funcionalidad del explorador de ASP.NET
Para reemplazar completamente las capacidades de definición de funciones del explorador ASP.NET, siga estos pasos:
Cree una clase de proveedor que derive de HttpCapabilitiesProvider y que invalide el método GetBrowserCapabilities, como en el ejemplo siguiente:
public class CustomProvider : HttpCapabilitiesProvider { public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request) { HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities(); Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase); values[String.Empty] = request.UserAgent; values["browser"] = "MyCustomBrowser"; browserCaps.Capabilities = values; return browserCaps; } }
El código de este ejemplo crea un nuevo objeto HttpBrowserCapabilities, especificando solo la funcionalidad denominada browser y estableciéndola en MyCustomBrowser.
Registre el proveedor con la aplicación.
Para usar un proveedor con una aplicación, debe agregar el atributo provider a la sección browserCaps de los archivos
Web.config
oMachine.config
. (También puede definir los atributos de proveedor en un elementolocation para directorios específicos de la aplicación, como en una carpeta para un dispositivo móvil específico). En el ejemplo siguiente se muestra cómo establecer el atributo de proveedor en un archivo de configuración:<system.web> <browserCaps provider="ClassLibrary2.CustomProvider, ClassLibrary2, Version=1.0.0.0, Culture=neutral" /> </system.web>
Otra manera de registrar la nueva definición de funcionalidad del explorador es usar código, como se muestra en este ejemplo:
void Application_Start(object sender, EventArgs e) { HttpCapabilitiesBase.BrowserCapabilitiesProvider = new ClassLibrary2.CustomProvider(); // ... }
Este código debe ejecutarse en el evento Application_Start del archivo
Global.asax
. Cualquier cambio en la clase BrowserCapabilitiesProvider debe producirse antes de que se ejecute cualquier código de la aplicación para asegurarse de que la memoria caché permanece en un estado válido para el objeto resuelto HttpCapabilitiesBase.
Almacenamiento en caché del objeto HttpBrowserCapabilities
El ejemplo anterior tiene un problema: el código se ejecutaría cada vez que se invoca el proveedor personalizado para obtener el objeto HttpBrowserCapabilities. Esto puede ocurrir varias veces durante cada solicitud. En el ejemplo, el código del proveedor no hace mucho. Sin embargo, si el código del proveedor personalizado realiza un trabajo significativo para obtener el objeto HttpBrowserCapabilities, esto puede afectar al rendimiento. Para evitar que esto suceda, puede almacenar en caché el objeto HttpBrowserCapabilities. Siga estos pasos:
Cree una clase que derive de HttpCapabilitiesProvider, como la de este ejemplo:
public class CustomProvider : HttpCapabilitiesProvider { public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request) { string cacheKey = BuildCacheKey(); int cacheTime = GetCacheTime(); HttpBrowserCapabilities browserCaps = HttpContext.Current.Cache[cacheKey] as HttpBrowserCapabilities; if (browserCaps == null) { HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities(); Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase); values[String.Empty] = request.UserAgent; values["browser"] = "MyCustomBrowser"; browserCaps.Capabilities = values; HttpContext.Current.Cache.Insert(cacheKey, browserCaps, null, DateTime.MaxValue, TimeSpan.FromSeconds(cacheTime)); } return browserCaps; } }
En el ejemplo, el código genera una clave de caché llamando a un método BuildCacheKey personalizado y obtiene el período de tiempo para almacenar en caché llamando a un método GetCacheTime personalizado. A continuación, el código agrega el objeto resuelto HttpBrowserCapabilities a la memoria caché. El objeto se puede recuperar de la memoria caché y reutilizarse en las solicitudes posteriores que usen el proveedor personalizado.
Registre el proveedor con la aplicación como se describe en el procedimiento anterior.
Extensión de la funcionalidad de la capacidad del explorador ASP.NET
En la sección anterior se describe cómo crear un nuevo objeto HttpBrowserCapabilities en ASP.NET 4. También puede ampliar la funcionalidad del explorador de ASP.NET agregando nuevas definiciones de funcionalidades de explorador a las que ya están en ASP.NET. Puede hacerlo sin usar las definiciones del explorador XML. En el procedimiento siguiente se muestra cómo.
Cree una clase que derive de HttpCapabilitiesEvaluator y que invalide el método GetBrowserCapabilities, como se muestra en este ejemplo:
public class CustomProvider : HttpCapabilitiesEvaluator { public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request) { HttpBrowserCapabilities browserCaps = base.GetHttpBrowserCapabilities(request); if (browserCaps.Browser == "Unknown") { browserCaps = MyBrowserCapabilitiesEvaulator(request); } return browserCaps; } }
En primer lugar, este código usa la funcionalidad de capacidades del explorador ASP.NET para intentar identificar el explorador. Sin embargo, si no se identifica ningún explorador en función de la información definida en la solicitud (es decir, si la propiedad Explorador del objeto HttpBrowserCapabilities es la cadena "Desconocido"), el código llama al proveedor personalizado (MyBrowserCapabilitiesEvaluator) para identificar el explorador.
Registre el proveedor con la aplicación como se describe en el ejemplo anterior.
Extensión de funcionalidades del explorador agregando nuevas funcionalidades a las definiciones de funcionalidades existentes
Además de crear un proveedor de definiciones de explorador personalizado y crear de forma dinámica nuevas definiciones de explorador, puede ampliar las definiciones de explorador existentes con funcionalidades adicionales. Esto le permite usar una definición cercana a lo que desea, pero que solo carezca de algunas funcionalidades. Para hacer esto, siga los pasos siguientes:
Cree una clase que derive de HttpCapabilitiesEvaluator y que invalide el método GetBrowserCapabilities, como se muestra en este ejemplo:
public class CustomProvider : HttpCapabilitiesEvaluator { public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request) { HttpBrowserCapabilities browserCaps = base.GetHttpBrowserCapabilities(request); if (browserCaps.Browser == "Unknown") { browserCaps = MyBrowserCapabilitiesEvaulator(request); } return browserCaps; } }
El código de ejemplo amplía la clase ASP.NET HttpCapabilitiesEvaluator existente y obtiene el objeto HttpBrowserCapabilities que coincide con la definición de solicitud actual mediante el código siguiente:
HttpBrowserCapabilities browserCaps = base.GetHttpBrowserCapabilities(request);
El código puede entonces agregar o modificar una funcionalidad para este explorador. Hay dos maneras de especificar una nueva funcionalidad del explorador:
Agregue un par clave/valor al objeto IDictionary expuesto por la propiedad Capabilities del objeto HttpCapabilitiesBase. En el ejemplo anterior, el código agrega una funcionalidad denominada MultiTouch con un valor true.
Establezca las propiedades existentes del objeto HttpCapabilitiesBase. En el ejemplo anterior, el código establece la propiedad Frames en true. Esta propiedad es simplemente un descriptor de acceso para el objeto IDictionary que expone la propiedad Capabilities.
Nota:
Nota: este modelo se aplica a cualquier propiedad de HttpBrowserCapabilities, incluidos los adaptadores de control.
Registre el proveedor con la aplicación como en el procedimiento anterior.
Enrutamiento en ASP.NET 4
ASP.NET 4 agrega compatibilidad integrada para usar el enrutamiento con formularios web. El enrutamiento le permite configurar una aplicación para aceptar URL de solicitud que no se asignan a archivos físicos. En su lugar, puede usar el enrutamiento para definir URL que sean significativas para los usuarios y que pueden ayudar con la optimización del motor de búsqueda (SEO) para la aplicación. Por ejemplo, la URL de una página que muestra categorías de productos en una aplicación existente podría tener un aspecto similar al del ejemplo siguiente:
http://website/products.aspx?categoryid=12
Mediante el enrutamiento, puede configurar la aplicación para que acepte la siguiente URL para representar la misma información:
http://website/products/software
El enrutamiento es disponible desde ASP.NET 3.5 SP1. (Para obtener un ejemplo de cómo usar el enrutamiento en ASP.NET 3.5 SP1, consulte la entrada Uso del enrutamiento con WebForms en el blog de Phil Haack). Sin embargo, ASP.NET 4 incluye algunas características que facilitan el enrutamiento, incluyendo:
- La clase PageRouteHandler, que es un controlador HTTP simple que se usa al definir rutas. La clase pasa datos a la página a la que se enruta la solicitud.
- Las nuevas propiedades HttpRequest.RequestContext y Page.RouteData (que es un proxy para el objeto HttpRequest.RequestContext.RouteData). Estas propiedades facilitan el acceso a la información que se pasa desde la ruta.
- Los siguientes generadores de expresiones nuevos, que se definen en System.Web.Compilation.RouteUrlExpressionBuilder y System.Web.Compilation.RouteValueExpressionBuilder:
- RouteUrl, que proporciona una manera sencilla de crear una dirección URL que se corresponda con una dirección URL de ruta dentro de un control de servidor ASP.NET.
- RouteValue, que proporciona una manera sencilla de extraer información del objeto RouteContext.
- La clase RouteParameter, que facilita el paso de datos contenidos en un objeto RouteContext a una consulta de un control de origen de datos (similar a FormParameter).
Enrutamiento de páginas de formularios web
En el ejemplo siguiente se muestra cómo definir una ruta de Formularios Web Forms mediante el nuevo método MapPageRoute de la clase Route:
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapPageRoute("SearchRoute",
"search/{searchterm}", "~/search.aspx");
RouteTable.Routes.MapPageRoute("UserRoute",
"users/{username}", "~/users.aspx");
}
}
ASP.NET 4 presenta el método MapPageRoute. El ejemplo siguiente es equivalente a la definición de SearchRoute que se muestra en el ejemplo anterior, pero usa la clase PageRouteHandler.
RouteTable.Routes.Add("SearchRoute", new Route("search/{searchterm}",
new PageRouteHandler("~/search.aspx")));
El código del ejemplo asigna la ruta a una página física (en la primera ruta, a ~/search.aspx
). La primera definición de ruta también especifica que el parámetro denominado searchterm debe extraerse de la URL y pasarse a la página.
El método MapPageRoute admite las siguientes sobrecargas de método:
- MapPageRoute(cadena routeName, cadena routeUrl, string physicalFile, bool checkPhysicalUrlAccess)
- MapPageRoute(cadena routeName, cadena routeUrl, cadena physicalFile, bool checkPhysicalUrlAccess, valores predeterminados RouteValueDictionary)
- MapPageRoute(cadena routeName, cadena routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary valores predeterminados, restricciones RouteValueDictionary)
El parámetro checkPhysicalUrlAccess especifica si la ruta debe comprobar los permisos de seguridad de la página física a la que se enruta (en este caso, search.aspx) y los permisos en la dirección URL entrante (en este caso, search/{searchterm}). Si el valor de checkPhysicalUrlAccess es false, solo se comprobarán los permisos de la URL entrante. Estos permisos se definen en el archivo Web.config
mediante la configuración, como la siguiente:
<configuration>
<location path="search.aspx">
<system.web>
<authorization>
<allow roles="admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="search">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>
En la configuración de ejemplo, se deniega el acceso a la página física search.aspx
para todos los usuarios, excepto aquellos con rol de administrador. Cuando el parámetro checkPhysicalUrlAccess se establece en true (que es su valor predeterminado), solo los usuarios administradores pueden acceder a la dirección URL /search/{searchterm}, ya que la página física search.aspx está restringida a los usuarios de ese rol. Si checkPhysicalUrlAccess está establecido en false y el sitio está configurado como se muestra en el ejemplo anterior, todos los usuarios autenticados pueden acceder a la dirección URL /search/{searchterm}.
Leer información de enrutamiento en una página de Web Forms
En el código de la página física de Web Forms puede acceder a la información que el enrutamiento ha extraído de la dirección URL (u otra información que otro objeto haya agregado al objeto RouteData) mediante dos nuevas propiedades: HttpRequest.RequestContext y Page.RouteData. (Page.RouteData encapsulados HttpRequest.RequestContext.RouteData.) En el siguiente ejemplo se muestra cómo usar Page.RouteData.
protected void Page_Load(object sender, EventArgs e)
{
string searchterm = Page.RouteData.Values["searchterm"] as string;
label1.Text = searchterm;
}
El código extrae el valor que se pasó para el parámetro searchterm, tal como se definió en la ruta de ejemplo anterior. Tenga en cuenta la siguiente URL de solicitud:
http://localhost/search/scott/
Cuando se realiza esta solicitud, la palabra "scott" se representaría en la página search.aspx
.
Acceso a la información de enrutamiento en el marcado
El método descrito en la sección anterior muestra cómo obtener datos de ruta en el código de una página de Web Forms. También puede usar expresiones en marcado que le proporcionen acceso a la misma información. Los generadores de expresiones son una manera eficaz y elegante de trabajar con código declarativo. (Para más información, consulte la entrada Exprésese con Generadores de expresiones personalizadas en el blog de Phil Haack).
ASP.NET 4 incluye dos nuevos generadores de expresiones para el enrutamiento de Web Forms. En el ejemplo siguiente se muestra cómo usarlos.
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="<%$RouteUrl:SearchTerm=scott%>">Search for Scott</asp:HyperLink>
En el ejemplo, la expresión RouteUrl se usa para definir una dirección URL basada en un parámetro de ruta. Esto le ahorra tener que codificar de forma rígida la URL completa en el marcado y le permite cambiar la estructura de direcciones URL más adelante sin necesidad de ningún cambio en este vínculo.
En función de la ruta definida anteriormente, este marcado genera la siguiente URL:
http://localhost/search/scott
ASP.NET elabora automáticamente la ruta correcta (es decir, genera la dirección URL correcta) en función de los parámetros de entrada. También puede incluir un nombre de ruta en la expresión que le permite especificar una ruta a usar.
En el ejemplo siguiente se muestra cómo usar la expresión RouteValue.
<asp:Label ID="Label1" runat="server" Text="<%$RouteValue:SearchTerm%>" />
Cuando se ejecuta la página que contiene este control, el valor "scott" se muestra en la etiqueta.
La expresión RouteValue facilita el uso de datos de ruta en el marcado y evita tener que trabajar con la sintaxis más compleja Page.RouteData["x"] en el marcado.
Uso de datos de ruta para parámetros de control de origen de datos
La clase RouteParameter permite especificar los datos de ruta como un valor de parámetro para las consultas de un control de origen de datos. funciona de forma muy similar a la clase , como se muestra en el ejemplo siguiente:
<asp:sqldatasource id="SqlDataSource1" runat="server"
connectionstring="<%$ ConnectionStrings:MyNorthwind %>"
selectcommand="SELECT CompanyName,ShipperID FROM Shippers where
CompanyName=@companyname"
<selectparameters>
<asp:routeparameter name="companyname" RouteKey="searchterm" />
</selectparameters>
</asp:sqldatasource>
En este caso, el valor del parámetro de rute searchterm se usará para el parámetro @companyname en la instrucción Select.
Establecer identificadores de cliente
La nueva propiedad ClientIDMode aborda un problema de larga duración en ASP.NET, es decir, cómo los controles crean el atributo id para los elementos que representan. Saber el atributo id para los elementos representados es importante si la aplicación incluye script de cliente que hace referencia a estos elementos.
El atributo id en HTML que se representa para los controles de servidor web se genera en función de la propiedad ClientID del control. Hasta ASP.NET 4, el algoritmo para generar el atributo id a partir de la propiedad ClientID ha sido concatenar el contenedor de nomenclatura (si existe) con el identificador y, en el caso de controles repetidos (como en los controles de datos), para agregar un prefijo y un número secuencial. Aunque esto siempre ha garantizado que los identificadores de los controles de la página sean únicos, el algoritmo ha dado lugar a identificadores de control que no eran predecibles y, por lo tanto, eran difíciles de hacer referencia en el script de cliente.
La nueva propiedad ClientIDMode permite especificar con más precisión cómo se genera el identificador de cliente para los controles. Puede establecer la propiedad ClientIDMode para cualquier control, incluyendo la página. Posible configuración:
- AutoID: es equivalente al algoritmo para generar valores de propiedad ClientID que se usaron en versiones anteriores de ASP.NET.
- Estático: especifica que el valor ClientID será el mismo que el identificador sin concatenar los identificadores de los contenedores de nomenclatura primarios. Esto puede ser útil en los controles de usuario web. Dado que un control de usuario web se puede ubicar en diferentes páginas y en distintos controles de contenedor, puede ser difícil escribir el script de cliente para los controles que usan el algoritmo AutoID porque no se puede predecir cuáles serán los valores de identificador.
- Predicción: esta opción se usa principalmente en controles de datos que usan plantillas de repetición. Concatena las propiedades id. de los contenedores de nomenclatura del control, pero los valores clientIDgenerados no contienen cadenas como "ctlxxx". Esta configuración funciona junto con la propiedad ClientIDRowSuffix del control. La propiedad ClientIDRowSuffix se establece en el nombre de un campo de datos y el valor de ese campo se usa como sufijo para el valor ClientID generado. Normalmente, usted usaría la clave principal de un registro de datos como el valor ClientIDRowSuffix.
- Heredar: esta configuración es el comportamiento predeterminado para los controles; especifica que la generación de identificadores de un control es la misma que su elemento primario.
Puede establecer la propiedad ClientIDMode en el nivel de página. Esto define el valor predeterminado ClientIDMode en todos los controles de la página actual.
El valor predeterminado clientIDMode en el nivel de página es AutoIDy el valor predeterminado ClientIDMode en el nivel de control es Heredar. Entonces, si no establece esta propiedad en ningún lugar del código, todos los controles tendrán como valor predeterminado el algoritmo AutoID.
Establezca el valor de nivel de página en la directiva @ Page, como se muestra en el ejemplo siguiente:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
ClientIDMode="Predictable" %>
También puede establecer el valor ClientIDMode en el archivo de configuración, ya sea en el nivel de equipo (máquina) o en el nivel de aplicación. Esto define la configuración ClientIDModepredeterminada para todos los controles de todas las páginas de la aplicación. Si establece el valor en el nivel de equipo, define la configuración predeterminada ClientIDMode para todos los sitios web de ese equipo. En el ejemplo siguiente se muestra la configuración ClientIDMode en el archivo de configuración:
<system.web>
<pages clientIDMode="Predictable"></pages>
</system.web>
Como se indicó anteriormente, el valor de la propiedad ClientID se deriva del contenedor de nomenclatura del elemento primario de un control. En algunos escenarios, como cuando se usan páginas maestras, los controles pueden acabar con identificadores como los del siguiente código HTML representado:
<div id="ctl00_ContentPlaceHolder1_ParentPanel">
<div id="ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1">
<input name="ctl00$ContentPlaceHolder1$ParentPanel$NamingPanel1$TextBox1"
type="text" value="Hello!"
id="ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1_TextBox1" />
</div>
Aunque el elemento de entrada que se muestra en el marcado (desde un control TextBox) es solo dos contenedores de nomenclatura profundos en la página (los controles anidados ContentPlaceholder), debido a la forma en que se procesan las páginas maestras, el resultado final es un identificador de control como este:
ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1_TextBox1
Se garantiza que este id. es único en la página, pero innecesariamente largo para la mayoría de los propósitos. Imagine que desea reducir la longitud del id. representado y tener más control sobre cómo se genera este. (Por ejemplo, quiere eliminar los prefijos "ctlxxx"). La manera más fácil de lograrlo es establecer la propiedad ClientIDMode como se muestra en este ejemplo:
<tc:NamingPanel runat="server" ID="ParentPanel" ClientIDMode="Static">
<tc:NamingPanel runat="server" ID="NamingPanel1" ClientIDMode="Predictable">
<asp:TextBox ID="TextBox1" runat="server" Text="Hello!"></asp:TextBox>
</tc:NamingPanel>
</tc:NamingPanel>
En este ejemplo, la propiedad ClientIDMode se establece en Static para el elemento NamingPanel más externo y se establece en Predecir para el elemento NamingControl interno. Esta configuración da como resultado el siguiente marcado (se supone que el resto de la página y la página maestra son los mismos que en el ejemplo anterior):
<div id="ParentPanel">
<div id="ParentPanel_NamingPanel1">
<input name="ctl00$ContentPlaceHolder1$ParentPanel$NamingPanel1$TextBox1"
type="text" value="Hello!" id="ParentPanel_NamingPanel1_TextBox1" />
</div>
La configuración Estática tiene el efecto de restablecer la jerarquía de nomenclatura de los controles dentro del elemento NamingPanel más externo y de eliminar los identificadores ContentPlaceHolder y MasterPage del id. generado. (El atributo name de los elementos representados no se ve afectado, por lo que la funcionalidad ASP.NET normal se conserva para eventos, estado de visualización, etc.). Un efecto secundario de restablecer la jerarquía de nomenclatura es que incluso si mueve el marcado de los elementos NamingPanel a otro control ContentPlaceholder, los identificadores de cliente representados siguen siendo los mismos.
Nota:
Nota: depende de usted asegurarse de que los identificadores de control representados son únicos. Si no lo son, puede interrumpir cualquier funcionalidad que requiera identificadores únicos para elementos HTML individuales, como la función cliente document.getElementById.
Creación de identificadores de cliente predecibles en controles enlazados a datos
Los valores clientID que se generan para los controles de un control de lista enlazado a datos por el algoritmo heredado pueden ser largos y no son realmente predecibles. La funcionalidad ClientIDMode puede ayudarle a tener más control sobre cómo se generan estos identificadores.
El marcado del ejemplo siguiente incluye un control ListView:
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1"
OnSelectedIndexChanged="ListView1_SelectedIndexChanged"
ClientIDMode="Predictable"
RowClientIDRowSuffix="ProductID">
</asp:ListView>
En el ejemplo anterior, las propiedades ClientIDMode y RowClientIDRowSuffix se establecen en el marcado. La propiedad ClientIDRowSuffix solo se puede usar en controles enlazados a datos y su comportamiento difiere en función del control que use. Estas son las diferencias:
Control GridView: puede especificar el nombre de una o varias columnas en el origen de datos, que se combinan durante el tiempo de ejecución para crear los identificadores de cliente. Por ejemplo, si establece RowClientIDRowSuffix en "ProductName, ProductId", los identificadores de control de los elementos representados tendrán un formato similar al siguiente:
rootPanel_GridView1_ProductNameLabel_Chai_1
Control ListView: puede especificar una sola columna en el origen de datos que se anexa al identificador de cliente. Por ejemplo, si establece ClientIDRowSuffix en "ProductName", los identificadores de control representados tendrán un formato similar a este:
rootPanel_ListView1_ProductNameLabel_1
En este caso, el final 1 se deriva del identificador de producto del elemento de datos actual.
Control Repeater: este control no admite la propiedad ClientIDRowSuffix. En un control Repeater, se usa el índice de la fila actual. Cuando se usa ClientIDMode="Predictable" con un control Repeater, se generan identificadores de cliente que tienen el formato siguiente:
Repeater1_ProductNameLabel_0
El final 0 es el índice de la fila actual.
Los controles FormView y DetailsView no muestran varias filas, por lo que no admiten la propiedad ClientIDRowSuffix.
Conservar la selección de filas en controles de datos
Los controles GridView y ListView pueden permitir a los usuarios seleccionar una fila. La selección se ha basado en el índice de fila de la página en versiones anteriores de ASP.NET. Por ejemplo, si selecciona el tercer elemento de la página 1 y después pasa a la página 2, se selecciona el tercer elemento de esa página.
La selección persistente solo se admitía inicialmente en proyectos de datos dinámicos en .NET Framework 3.5 SP1. Cuando esta característica está habilitada, el elemento seleccionado actual se basa en la clave de datos del elemento. Esto significa que si selecciona la tercera fila de la página 1 y se mueve a la página 2, no se selecciona nada en la página 2. Al volver a la página 1, la tercera fila está seleccionada todavía. La selección persistente ahora se admite para los controles GridView y ListView en todos los proyectos mediante la propiedad EnablePersistedSelection, como se muestra en el ejemplo siguiente:
<asp:GridView id="GridView2" runat="server" EnablePersistedSelection="true">
</asp:GridView>
Chart Control de ASP.NET
El Chart control de ASP.NET expande las ofertas de visualización de datos en .NET Framework. Con el control Gráfico, puede crear ASP.NET páginas que tengan gráficos intuitivos y visualmente atractivos para análisis estadísticos o financieros complejos. El control Gráfico de ASP.NET se introdujo como complemento para la versión 3.5 SP1 de .NET Framework y forma parte de la versión de .NET Framework 4.
El control incluye las siguientes características:
- 35 tipos de gráfico distintos.
- Un número ilimitado de áreas de charts, títulos, leyendas y anotaciones.
- Una amplia variedad de configuraciones de apariencia para todos los elementos del chart.
- Capacidad 3D para la mayoría de los tipos de charts.
- Etiquetas de datos inteligentes que pueden ajustarse automáticamente a los puntos de datos.
- Seccione líneas, saltos de escala y escalado logarítmico.
- Más de 50 fórmulas financieras y estadísticas para la transformación y el análisis de datos.
- Enlace simple y manipulación de datos del chart.
- Compatibilidad con formatos de datos comunes, como fechas, horas y moneda.
- Compatibilidad con la interactividad y la personalización controlada por eventos, incluidos los eventos de clics de cliente mediante Ajax.
- Administración de estados.
- Transmisión de flujo binario.
En las cifras siguientes se muestran ejemplos de gráficos financieros producidos por el Chart Control de ASP.NET.
Figura 2: ejemplos de Chart Control ASP.NET
Para más ejemplos de cómo usar el Chart Control de ASP.NET, descargue el código de ejemplo en la página Samples Environment for Microsoft Chart Controls (Entorno de ejemplos para controles de gráficos de Microsoft) en el sitio web de MSDN. Puede encontrar más ejemplos de contenido de la comunidad en el Foro de controles Chart.
Agregar el Chart Control a una página de ASP.NET
En el ejemplo siguiente se muestra cómo agregar un control Chart a una página de ASP.NET mediante marcado. En el ejemplo, el control Chart genera un gráfico de columnas para puntos de datos estáticos.
<asp:Chart ID="Chart1" runat="server">
<Series>
<asp:Series Name="Series1" ChartType="Column">
<Points>
<asp:DataPoint AxisLabel="Product A" YValues="345"/>
<asp:DataPoint AxisLabel="Product B" YValues="456"/>
<asp:DataPoint AxisLabel="Product C" YValues="125"/>
<asp:DataPoint AxisLabel="Product D" YValues="957"/> &
lt;/Points>
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1">
<AxisY IsLogarithmic="True" />
</asp:ChartArea>
</ChartAreas>
<Legends>
<asp:Legend Name="Legend1" Title="Product Sales" />
</Legends>
</asp:Chart>
Uso de charts 3D
El control Chart contiene una colección ChartAreas, que puede contener objetos ChartArea que definen características de las áreas del gráfico. Por ejemplo, para usar 3D para un área de gráfico, use la propiedadArea3DStyle como en el ejemplo siguiente:
<asp:ChartArea Name="ChartArea1">
<area3dstyle
Rotation="10"
Perspective="10"
Enable3D="True"
Inclination="15"
IsRightAngleAxes="False"
WallWidth="0"
IsClustered="False" />
<%-- Additional markup here --%>
</asp:ChartArea>
En la ilustración siguiente se muestra un gráfico 3D con cuatro series del tipo de gráfico de barras.
Figura 3: Gráfico de barras 3D
Uso de saltos de escala y escalas logarítmicas
Las interrupciones de escala y las escalas logarítmicas son dos maneras adicionales de agregar sofisticación al gráfico. Estas características son específicas de cada eje de un área de gráfico. Por ejemplo, para usar estas características en el eje Y principal de un área de gráfico, use las propiedades AxisY.IsLogarithmic y ScaleBreakStyle en un objeto ChartArea. En el siguiente fragmento de código se muestra cómo usar saltos de escala en el eje Y principal.
<asp:ChartArea Name="ChartArea1">
<axisy>
<ScaleBreakStyle
BreakLineStyle="Wave"
CollapsibleSpaceThreshold="40"
Enabled="True" />
</axisy>
<%-- Additional markup here --%>
</asp:ChartArea>
En la ilustración siguiente se muestra el eje Y con saltos de escala habilitados.
Figura 4: Saltos de escala
Filtrado de datos con QueryExtender Control
Una tarea muy común para los desarrolladores que crean páginas web controladas por datos es filtrar los datos. Esto se ha realizado tradicionalmente mediante la creación de cláusulas Where en controles de origen de datos. Este enfoque puede ser complicado y, en algunos casos, la sintaxis Where no permite aprovechar la funcionalidad completa de la base de datos subyacente.
Para facilitar el filtrado, se ha agregado un nuevo control QueryExtender en ASP.NET 4. Este control se puede agregar a los controles EntityDataSource oLinqDataSource para filtrar los datos devueltos por estos controles. Dado que el control QueryExtender se basa en LINQ, el filtro se aplica en el servidor de bases de datos antes de que los datos se envíen a la página, lo que da como resultado operaciones muy eficaces.
El control QueryExtender admite una variedad de opciones de filtro. En estas secciones se describen estas opciones y se proporcionan ejemplos de cómo usarlas.
Buscar
Para la opción de búsqueda, el control QueryExtender realiza una búsqueda en campos especificados. En el ejemplo siguiente, el control usa el texto que se escribe en el control TextBoxSearch y busca su contenido en las columnas ProductName
y Supplier.CompanyName
de los datos que se devuelven desde el control LinqDataSource.
<asp:LinqDataSource ID="dataSource" runat="server"> TableName="Products">
</asp:LinqDataSource>
<asp:QueryExtender TargetControlID="dataSource" runat="server">
<asp:SearchExpression DataFields="ProductName, Supplier.CompanyName"
SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxSearch" />
</asp:SearchExpression>
</asp:QueryExtender>
Intervalo
La opción de intervalo es similar a la opción de búsqueda, pero especifica un par de valores para definir el intervalo. En el ejemplo siguiente, el control QueryExtender busca en la columna UnitPrice
de los datos devueltos desde el control LinqDataSource. El intervalo se lee desde los controles TextBoxFrom y TextBoxTo de la página.
<asp:LinqDataSource ID="dataSource" runat="server"> TableName="Products">
</asp:LinqDataSource>
<asp:QueryExtender TargetControlID="dataSource" runat="server">
<asp:RangeExpression DataField="UnitPrice" MinType="Inclusive"
MaxType="Inclusive">
<asp:ControlParameter ControlID="TextBoxFrom" />
<asp:ControlParameter ControlID="TexBoxTo" />
</asp:RangeExpression>
</asp:QueryExtender>
PropertyExpression
La opción de expresión de propiedad permite definir una comparación con un valor de propiedad. Si la expresión se evalúa como true, se devuelven los datos que se están examinando. En el ejemplo siguiente, el control QueryExtender filtra los datos comparando los datos de la columna Discontinued
con el valor del control CheckBoxDiscontinued de la página.
<asp:LinqDataSource ID="dataSource" runat="server" TableName="Products">
</asp:LinqDataSource>
<asp:QueryExtender TargetControlID="dataSource" runat="server">
<asp:PropertyExpression>
<asp:ControlParameter ControlID="CheckBoxDiscontinued" Name="Discontinued" />
</asp:PropertyExpression>
</asp:QueryExtender>
CustomExpression
Por último, puede especificar una expresión personalizada que se usará con el control QueryExtender. Esta opción le permite llamar a una función en la página que define la lógica de filtro personalizada. En el ejemplo siguiente se muestra cómo especificar mediante declaración una expresión personalizada en el control QueryExtender.
<asp:LinqDataSource ID="dataSource" runat="server" TableName="Products">
</asp:LinqDataSource>
<asp:QueryExtender TargetControlID="dataSource" runat="server">
<asp:CustomExpression OnQuerying="FilterProducts" />
</asp:QueryExtender>
En el ejemplo siguiente se muestra la función personalizada invocada por el control QueryExtender. En este caso, en lugar de usar una consulta de base de datos que incluya una cláusula Where, el código usa una consulta LINQ para filtrar los datos.
protected void FilterProducts(object sender, CustomExpressionEventArgs e)
{
e.Query = from p in e.Query.Cast()
where p.UnitPrice >= 10
select p;
}
Estos ejemplos muestran solo una expresión que se usa en el control QueryExtender a la vez. Sin embargo, puede incluir varias expresiones dentro del control QueryExtender.
Expresiones codificadas con código HTML
Algunos sitios de ASP.NET (especialmente con ASP.NET MVC) dependen en gran medida del uso de sintaxis <%
= expression %>
(a menudo denominados "nuggets de código") para escribir texto en la respuesta. Al usar expresiones de código, es fácil olvidarse de codificar el texto en HTML, si el texto procede de la entrada del usuario, puede dejar páginas abiertas a un ataque XSS (scripting entre sitios).
ASP.NET 4 presenta la siguiente nueva sintaxis para las expresiones de código:
<%: expression %>
Esta sintaxis usa la codificación HTML de forma predeterminada al escribir a la respuesta. Esta nueva expresión se traduce eficazmente como:
<%= HttpUtility.HtmlEncode(expression) %>
Por ejemplo, <%: Request["UserInput"] %> realiza la codificación HTML en el valor de Request["UserInput"].
El objetivo de esta característica es permitir reemplazar todas las instancias de la sintaxis antigua con la nueva sintaxis para que no se le obligue a decidir en cada paso cuál usar. Sin embargo, hay casos en los que el texto que se va a generar está destinado a ser HTML o ya está codificado, en cuyo caso esto podría dar lugar a la codificación doble.
En esos casos, ASP.NET 4 presenta una nueva interfaz, IHtmlString, junto con una implementación concreta, HtmlString. Las instancias de estos tipos permiten indicar que el valor devuelto ya está codificado correctamente (o examinado de otro modo) para mostrarse como HTML y, por lo tanto, el valor no debe volver a codificarse en HTML. Por ejemplo, lo siguiente no debe estar (y no es) codificado en HTML:
<%: new HtmlString("<strong>HTML that is not encoded</strong>") %>
Los métodos auxiliares de ASP.NET MVC 2 se han actualizado para que funcionen con esta nueva sintaxis y que no estén codificadas doblemente, solo cuando usted ejecute ASP.NET 4. Esta nueva sintaxis no funciona al ejecutar una aplicación con ASP.NET 3.5 SP1.
Tenga en cuenta que esto no garantiza la protección frente a ataques XSS. Por ejemplo, HTML que usa valores de atributo que no están entre comillas puede contener entradas de usuario que siguen siendo susceptibles. Tenga en cuenta que la salida de controles ASP.NET y asistentes de MVC ASP.NET siempre incluye valores de atributo entre comillas, que es el enfoque recomendado.
Del mismo modo, esta sintaxis no realiza la codificación de JavaScript como cuando se crea una cadena de JavaScript basada en la entrada del usuario.
Cambios en la plantilla de proyecto
En versiones anteriores de ASP.NET, cuando se usa Visual Studio para crear un proyecto de sitio web o un proyecto de Aplicación web, los proyectos resultantes solo contienen una página de Default.aspx, un archivo Web.config
predeterminado y la carpeta App_Data
, como se muestra en la siguiente ilustración:
Visual Studio también admite un tipo de proyecto de Sitio web vacío, que no contiene ningún archivo, como se muestra en la ilustración siguiente:
El resultado es que para el principiante hay muy pocas instrucciones sobre cómo crear una aplicación web de producción. Por lo tanto, ASP.NET 4 presenta tres plantillas nuevas: una para un proyecto de aplicación web vacía, otra para una proyecto de aplicación web y otra para un proyecto de sitio web.
Plantilla de aplicación web vacía
Como su propio nombre indica, la Plantilla de Aplicación web vacía es un proyecto de aplicación web en blanco. Seleccione esta plantilla de proyecto en el cuadro de diálogo Nuevo proyecto de Visual Studio, como se muestra en la ilustración siguiente:
(Haga clic para ver la imagen a tamaño completo.)
Al crear una Aplicación web ASP.NET vacía, Visual Studio crea el siguiente diseño de carpeta:
Esto es similar al diseño de Sitio web vacío de versiones anteriores de ASP.NET, con una excepción. En Visual Studio 2010, los proyectos Aplicación web vacía y Sitio web vacío contienen el siguiente archivo mínimo Web.config
que contiene información usada por Visual Studio para identificar el marco de trabajo destinado al proyecto:
Sin esta propiedadtargetFramework, Visual Studio tiene como destino .NET Framework 2.0 para conservar la compatibilidad al abrir aplicaciones anteriores.
Plantillas de Proyectos de aplicación web y sitio web
Las otras dos nuevas plantillas de proyecto que se incluyen con Visual Studio 2010 contienen cambios importantes. En la siguiente ilustración se muestra el diseño del proyecto que se genera al crear un nuevo proyecto de aplicación web. (El diseño de un proyecto de sitio web es prácticamente idéntico).
El proyecto incluye una serie de archivos que no se crearon en versiones anteriores. Además, el nuevo proyecto de Aplicación web se configura con la funcionalidad de pertenencia básica. Esto le permite empezar a proteger rápidamente el acceso a la nueva aplicación. Debido a esta inclusión, el archivo Web.config
del nuevo proyecto incluye entradas que se usan para configurar la pertenencia, los roles y los perfiles. En el ejemplo siguiente se muestra el archivo Web.config
de un nuevo proyecto de Aplicación web. (En este caso, roleManager está deshabilitado).
(Haga clic para ver la imagen a tamaño completo.)
El proyecto también contiene un segundo archivo Web.config
en el directorio Account
. El segundo archivo de configuración proporciona una manera de proteger el acceso a la página de ChangePassword.aspx para los usuarios que no han iniciado sesión. En el ejemplo siguiente se muestra el contenido del segundo archivo Web.config
.
Las páginas creadas de forma predeterminada en las nuevas plantillas de proyecto también contienen más contenido que en versiones anteriores. El proyecto contiene una página maestra predeterminada y un archivo CSS, y la página predeterminada (Default.aspx) está configurada para usar la página maestra de forma predeterminada. Así, cuando se ejecuta la aplicación web o el sitio web por primera vez, la página predeterminada (inicio) ya es funcional. De hecho, es similar a la página predeterminada que ve al iniciar una nueva aplicación MVC.
(Haga clic para ver la imagen a tamaño completo.)
El objetivo de estos cambios en las plantillas de proyecto es proporcionar instrucciones sobre cómo empezar a compilar una nueva aplicación web. Con un marcado semánticamente correcto y estrictamente conforme con XHTML 1.0 y con un diseño especificado mediante CSS, las páginas de las plantillas representan los procedimientos recomendados para compilar aplicaciones web ASP.NET 4. Las páginas predeterminadas también tienen un diseño de dos columnas que puede personalizar fácilmente.
Por ejemplo, imagine que para una nueva Aplicación web desea cambiar algunos de los colores e insertar el logotipo de la empresa en lugar del logotipo de Mi aplicación ASP.NET. Para ello, cree un nuevo directorio en Content
para almacenar la imagen del logotipo:
Para agregar la imagen a la página, abra el archivo Site.Master
, busque dónde se define el texto de Mi aplicación ASP.NET y reemplácelo por un elemento image cuyo atributo src esté establecido en la nueva imagen de logotipo, como en este ejemplo:
(Haga clic para ver la imagen a tamaño completo.)
A continuación, puede ir al archivo Site.css y modificar las definiciones de clase CSS para cambiar el color de fondo de la página, así como el del encabezado.
El resultado de estos cambios es que puede mostrar una página principal personalizada con muy poco esfuerzo:
(Haga clic para ver la imagen a tamaño completo.)
Mejoras de CSS
Una de las principales áreas de trabajo de ASP.NET 4 ha sido ayudar a representar HTML compatible con los estándares HTML más recientes. Esto incluye cambios en cómo los controles de servidor web ASP.NET usa estilos CSS.
Configuración de compatibilidad para la representación
De forma predeterminada, cuando una aplicación web o un sitio web tiene como destino .NET Framework 4, el atributo controlRenderingCompatibilityVersion del elemento pages se establece en "4.0". Este elemento se define en el archivo Web.config
de nivel de máquina y se aplica de forma predeterminada a todas las aplicaciones de ASP.NET 4:
<system.web>
<pages controlRenderingCompatibilityVersion="3.5|4.0"/>
</system.web>
El valor de controlRenderingCompatibility es una cadena, que permite posibles definiciones de nuevas versiones en futuras versiones. En la versión actual, se admiten los siguientes valores para esta propiedad:
- "3.5". Esta configuración indica la representación y el marcado heredados. El marcado representado por los controles es compatible con versiones anteriores del 100 % y se respeta la configuración de la propiedad xhtmlConformance.
- "4.0". Si la propiedad tiene esta configuración, los controles de servidor web ASP.NET hacen lo siguiente:
- La propiedad xhtmlConformance siempre se trata como "Strict". Como resultado, los controles representan el marcado XHTML 1.0 Strict.
- Deshabilitar controles que no son de entrada ya no representa estilos no válidos.
- Los elementos div alrededor de los campos ocultos ahora tienen el estilo, por lo que no interfieren con las reglas CSS creadas por el usuario.
- Los controles de menú representan el marcado que es semánticamente correcto y compatible con las directrices de accesibilidad.
- Los controles de validación no representan estilos insertados.
- Los controles que anteriormente representaron border="0" (controles que derivan del control tabla de ASP.NET y el control imagen de ASP.NET ) ya no representan este atributo.
Deshabilitación de controles
En ASP.NET 3.5 SP1 y versiones anteriores, el marco representa el atributo deshabilitado en el marcado HTML para cualquier control cuya propiedad Enabledesté establecida en false. Sin embargo, según la especificación HTML 4.01, solo los elementos de entrada deben tener este atributo.
En ASP.NET 4, puede establecer la propiedad controlRenderingCompatibilityVersion en "3.5", como en el ejemplo siguiente:
<system.web>
<pages controlRenderingCompatibilityVersion="3.5"/>
</system.web>
Puede crear marcado para un control Label como el siguiente, que deshabilita el control:
<asp:Label id="Label" runat="server" Text="Test" Enabled="false">
El control Label representaría el código HTML siguiente:
<span id="Label1" disabled="disabled">Test</span>
En ASP.NET 4, puede establecer controlRenderingCompatibilityVersion en "4.0". En ese caso, solo los controles que representan los elementos entrada representarán un atributo deshabilitado cuando la propiedad Enableddel control esté establecida en false. Los controles que no representan elementos de entradaHTML en su lugar representan un atributo de clase que hace referencia a una clase CSS que puede usar para definir una búsqueda deshabilitada para el control. Por ejemplo, el control Label que se muestra en el ejemplo anterior generaría el marcado siguiente:
<span id="Span1" class="aspnetdisabled">Test</span>
El valor predeterminado de la clase especificada para este control es "aspNetDisabled". Sin embargo, puede cambiar este valor predeterminado estableciendo la propiedad estática DisabledCssClass estática de la clase WebControl. Para los desarrolladores de controles, el comportamiento que se va a usar para un control específico también se puede definir mediante la propiedad SupportsDisabledAttribute.
Ocultar elementos div alrededor de campos ocultos
ASP.NET 2.0 y versiones posteriores representan campos ocultos específicos del sistema (como el elemento oculto usado para almacenar información de estado de vista) dentro del elemento div para cumplir con el estándar XHTML. Sin embargo, esto puede causar un problema cuando una regla CSS afecta a los elementos div de una página. Por ejemplo, puede dar lugar a que aparezca una línea de un píxel en la página alrededor de los elementos divocultos. En ASP.NET 4, los elementos div que incluyen los campos ocultos generados por ASP.NET agregar una referencia de clase CSS como en el ejemplo siguiente:
<div class="aspNetHidden">...</div>
A continuación, puede definir una clase CSS que solo se aplique a los elementos ocultos generados por ASP.NET, como en el ejemplo siguiente:
<style type="text/css">
DIV# aspNetHidden {border:0;}
</style>
Representación de una tabla externa para controles asados en modelos
De forma predeterminada, los siguientes controles de servidor web ASP.NET que admiten plantillas se encapsulan automáticamente en una tabla externa que se usa para aplicar estilos insertados:
- FormView
- Inicio de sesión
- PasswordRecovery
- ChangePassword
- Asistente
- CreateUserWizard
Se ha agregado una nueva propiedad denominada RenderOuterTable a estos controles que permite quitar la tabla externa del marcado. Por ejemplo, considere el ejemplo siguiente de un control FormView:
<asp:FormView ID="FormView1" runat="server">
<ItemTemplate>
Content
</ItemTemplate>
</asp:FormView>
Este marcado representa la siguiente salida en la página, que incluye una tabla HTML:
<table cellspacing="0" border="0" id="Table1" style="border-collapse:collapse;">
<tr>
<td colspan="2">
Content
</td>
</tr>
</table>
Para evitar que la tabla se represente, puede establecer la propiedad RenderOuterTable del control FormView, como en el ejemplo siguiente:
<asp:FormView ID="FormView1" runat="server" RenderOuterTable="false">
En el ejemplo anterior se representa la siguiente salida, sin los elementos table, try td:
Contenido
Esta mejora puede facilitar el estilo del contenido del control con CSS, ya que el control no representa ninguna etiqueta inesperada.
Nota:
Nota: este cambio deshabilita la compatibilidad con la función de formato automático en el diseñador de Visual Studio 2010, ya que ya no hay un elemento de tabla que pueda hospedar atributos de estilo generados por la opción de formato automático.
Mejoras de Control ListView
El control ListView se ha hecho más fácil de usar en ASP.NET 4. La versión anterior del control requería especificar una plantilla de diseño que contenía un control de servidor con un identificador conocido. El marcado siguiente muestra un ejemplo típico de cómo usar el control ListView en ASP.NET 3.5.
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<asp:PlaceHolder ID="ItemPlaceHolder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<% Eval("LastName")%>
</ItemTemplate>
</asp:ListView>
En ASP.NET 4, el control ListView no requiere una plantilla de diseño. El marcado que se muestra en el ejemplo anterior se puede reemplazar por el marcado siguiente:
<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<% Eval("LastName")%>
</ItemTemplate>
</asp:ListView>
Mejoras del control CheckBoxList y RadioButtonList
En ASP.NET 3.5, puede especificar el diseño de CheckBoxList y RadioButtonList con los dos valores siguientes:
- Flujo. El control representa los elementos span para que contengan su contenido.
- Table. El control representa un elemento de tabla que contiene su contenido.
En el ejemplo siguiente se muestra el marcado de cada uno de estos controles.
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatLayout="Flow">
<asp:ListItem Text="CheckBoxList" Value="cbl" />
</asp:CheckBoxList>
<asp:RadioButtonList runat="server" RepeatLayout="Table">
<asp:ListItem Text="RadioButtonList" Value="rbl" />
</asp:RadioButtonList>
De forma predeterminada, los controles representan HTML similar al siguiente:
<span id="Span2"><input id="CheckBoxList1_0" type="checkbox"
name="CheckBoxList1$0" /><label for="CheckBoxList1_0">CheckBoxList</label></span>
<table id="RadioButtonList1" border="0">
<tr>
<td><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="rbl" /><label for="RadioButtonList1_0">RadioButtonList</label></td>
</tr>
</table>
Dado que estos controles contienen listas de elementos, para representar HTML semánticamente correctos, deben representar su contenido mediante elementos de lista HTML (li). Esto facilita a los usuarios que leen páginas web mediante tecnología de asistencia y facilita el estilo de los controles mediante CSS.
En ASP.NET 4, los controles CheckBoxList y RadioButtonList admiten los siguientes valores nuevos para la propiedad RepeatLayout:
- OrderedList: el contenido se representa como elementos li dentro de un elemento ol.
- UnorderedList: el contenido se representa como elementos li dentro de un elemento ul.
En el siguiente ejemplo se muestra cómo usar estos nuevos valores.
<asp:CheckBoxList ID="CheckBoxList1" runat="server"
RepeatLayout="OrderedList">
<asp:ListItem Text="CheckBoxList" Value="cbl" />
</asp:CheckBoxList>
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
RepeatLayout="UnorderedList">
<asp:ListItem Text="RadioButtonList" Value="rbl" />
</asp:RadioButtonList>
El marcado anterior genera el siguiente código HTML:
<ol id="CheckBoxList1">
<li><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" value="cbl" /><label for="CheckBoxList1_0">CheckBoxList</label></li>
</ol>
<ul id="RadioButtonList1">
<li><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="rbl" /><label for="RadioButtonList1_0">RadioButtonList</label></li>
</ul>
Nota:
Nota: si establece RepeatLayout en OrderedListo UnorderedList, la propiedad RepeatDirectionya no se puede usar y producirá una excepción durante el tiempo de ejecución si la propiedad se ha establecido en el marcado o el código. La propiedad no tendría ningún valor porque el diseño visual de estos controles se define mediante CSS en su lugar.
Mejoras en el control de menú
Antes de ASP.NET 4, el control Menu representa una serie de tablas HTML. Esto dificultaba la aplicación de estilos CSS fuera de la configuración de propiedades insertadas y tampoco era compatible con los estándares de accesibilidad.
En ASP.NET 4, el control ahora representa HTML mediante el marcado semántico que consta de una lista y elementos de lista no ordenados. En el ejemplo siguiente se muestra el marcado en una página de ASP.NET para el control Menú.
<asp:Menu ID="Menu1" runat="server">
<Items> <asp:MenuItem Text="Home" Value="Home" />
<asp:MenuItem Text="About" Value="About" />
</Items>
</asp:Menu>
Cuando se representa la página, el control genera el código HTML siguiente (se ha omitido el código onclick para mayor claridad):
<div id="Menu1">
<ul>
<li><a href="#" onclick="...">Home</a></li>
<li><a href="#" onclick="...">About</a></li>
</ul>
</div>
<script type="text/javascript">
new Sys.WebForms.Menu('Menu1');
</script>
Además de las mejoras de representación, también se ha mejorado la navegación por teclado del menú mediante la administración del foco. Cuando el control Menú obtiene el foco, puede usar las teclas de dirección para navegar por los elementos. El control Menú también asocia ahora roles y atributos de aplicaciones de Internet enriquecidas accesibles(ARIA) para mejorar laaccesibilidad.
Los estilos del control de menú se representan en un bloque de estilo en la parte superior de la página, en lugar de en línea con los elementos HTML representados. Si desea tener control total sobre el estilo del control, puede establecer la nueva propiedad IncludeStyleBlock en false, en cuyo caso no se emite el bloque de estilo. Una manera de usar esta propiedad es usar la característica de formato automático en el diseñador de Visual Studio para establecer la apariencia del menú. A continuación, puede ejecutar la página, abrir el origen de la página y, a continuación, copiar el bloque de estilo representado en un archivo CSS externo. En Visual Studio, deshaga el estilo y establezca IncludeStyleBlock en false. El resultado es que la apariencia del menú se define mediante estilos en una hoja de estilos externa.
Controles Wizard y CreateUserWizard
Los controles ASP.NET Wizard y CreateUserWizard admiten plantillas que permiten definir el CÓDIGO HTML que representan. (CreateUserWizard deriva del Asistente). En el ejemplo siguiente se muestra el marcado de un control CreateUserWizard totalmente con plantilla:
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server" ActiveStepIndex="0">
<HeaderTemplate>
</HeaderTemplate>
<SideBarTemplate>
</SideBarTemplate>
<StepNavigationTemplate>
</StepNavigationTemplate>
<StartNavigationTemplate>
</StartNavigationTemplate>
<FinishNavigationTemplate>
</FinishNavigationTemplate>
<WizardSteps>
<asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
<ContentTemplate>
</ContentTemplate>
<CustomNavigationTemplate>
</CustomNavigationTemplate>
</asp:CreateUserWizardStep>
<asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
<ContentTemplate>
</ContentTemplate>
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
El control representa HTML similar al siguiente:
<table cellspacing="0" cellpadding="0" border="0" id="CreateUserWizard1" style="border-collapse:collapse;">
<tr>
<td>Header</td>
</tr>
<tr style="height:100%;">
<td>
<table cellspacing="0" cellpadding="0" border="0" style="height:100%;width:100%;border-collapse:collapse;">
<tr>
<td style="height:100%;width:100%;"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="right"></td>
</tr>
</table>
En ASP.NET 3.5 SP1, aunque puede cambiar el contenido de la plantilla, todavía tiene un control limitado sobre la salida del control Wizard. En ASP.NET 4, puede crear una plantilla LayoutTemplate e insertar controles PlaceHolder (mediante nombres reservados) para especificar cómo desea que se represente el control Wizard. Esto se muestra en el ejemplo siguiente:
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server" ActiveStepIndex="1">
<LayoutTemplate>
<asp:PlaceHolder ID="headerPlaceholder" runat="server" />
<asp:PlaceHolder ID="sideBarPlaceholder" runat="server" />
<asp:PlaceHolder id="wizardStepPlaceholder" runat="server" />
<asp:PlaceHolder id="navigationPlaceholder" runat="server" />
</LayoutTemplate>
<HeaderTemplate>
Header
</HeaderTemplate>
<WizardSteps>
<asp:CreateUserWizardStep runat="server">
<ContentTemplate>
</ContentTemplate>
</asp:CreateUserWizardStep>
<asp:CompleteWizardStep runat="server">
<ContentTemplate>
</ContentTemplate>
</asp:CreateUserWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
El ejemplo contiene los siguientes marcadores de posición con nombre en el elemento LayoutTemplate:
- headerPlaceholder: en tiempo de ejecución, esto se reemplaza por el contenido del elemento HeaderTemplate.
- sideBarPlaceholder: en tiempo de ejecución, esto se reemplaza por el contenido del elemento SideBarTemplate.
- wizardStepPlaceHolder: en tiempo de ejecución, esto se reemplaza por el contenido del elemento WizardStepTemplate.
- navigationPlaceholder: en tiempo de ejecución, esto se reemplaza por las plantillas de navegación que haya definido.
El marcado del ejemplo que usa marcadores de posición representa el código HTML siguiente (sin el contenido definido realmente en las plantillas):
<span>
</span>
El único HTML que ahora no está definido por el usuario es un elemento span. (Se prevé que en futuras versiones, incluso el elemento span no se representará). Esto ahora le proporciona control total sobre prácticamente todo el contenido generado por el control Asistente.
ASP.NET MVC
ASP.NET MVC se introdujo como un marco de complemento para ASP.NET 3.5 SP1 en marzo de 2009. Visual Studio 2010 incluye ASP.NET MVC 2, que incluye nuevas características y funcionalidades.
Soporte técnico para áreas
Las áreas permiten agrupar controladores y vistas en secciones de una aplicación grande en aislamiento relativo de otras secciones. Cada área se puede implementar como un proyecto de MVC ASP.NET independiente al que puede hacer referencia la aplicación principal. Esto ayuda a administrar la complejidad al compilar una aplicación grande y facilita que varios equipos trabajen juntos en una sola aplicación.
Soporte técnico para la validación de atributos de anotación de datos
Los atributos DataAnnotations permiten adjuntar lógica de validación a un modelo mediante atributos de metadatos. Los atributos DataAnnotations se introdujeron en Datos dinámicos ASP.NET en ASP.NET 3.5 SP1. Estos atributos se han integrado en el enlazador de modelos predeterminado y proporcionan un medio controlado por metadatos para validar la entrada del usuario.
Asistentes con plantilla
Los asistentes con plantilla le permiten asociar automáticamente plantillas de edición y visualización con tipos de datos. Por ejemplo, puede usar un asistente de plantilla para especificar que un elemento de interfaz de usuario de selector de fecha se representa automáticamente para un valor System.DateTime. Esto es similar a las plantillas de campo de ASP.NET datos dinámicos.
Los métodos auxiliares Html.EditorFor y Html.DisplayFor tienen compatibilidad integrada para representar tipos de datos estándar, así como objetos complejos con varias propiedades. También personalizan la representación al permitirle aplicar atributos de anotación de datos como DisplayName y ScaffoldColumn al objeto ViewModel.
A menudo, quiere personalizar la salida de los asistentes de interfaz de usuario aún más y tener un control completo sobre lo que se genera. Los métodos auxiliares Html.EditorFor y Html.DisplayFor admiten esto mediante un mecanismo de plantillas que permite definir plantillas externas que pueden invalidar y controlar la salida representada. Las plantillas se pueden representar individualmente para una clase.
Datos dinámicos
Los datos dinámicos se introdujeron en la versión de .NET Framework 3.5 SP1 a mediados de 2008. Esta característica proporciona muchas mejoras para crear aplicaciones controladas por datos, incluidas las siguientes:
- Una experiencia RAD para crear rápidamente un sitio web controlado por datos.
- Validación automática basada en restricciones definidas en el modelo de datos.
- La capacidad de cambiar fácilmente el marcado que se genera para los campos de los controles GridView yDetailsView mediante plantillas de campo que forman parte del proyecto de datos dinámicos.
Nota:
Nota: para más información, consulte la Documentación de datos dinámicos en MSDN Library.
Para ASP.NET 4, los datos dinámicos se han mejorado para ofrecer a los desarrolladores aún más potencia para crear rápidamente sitios web controlados por datos.
Habilitación de datos dinámicos para proyectos existentes
Las características de datos dinámicos que se incluyen en .NET Framework 3.5 SP1 incorporaron nuevas características como las siguientes:
- Plantillas de campo: proporcionan plantillas basadas en tipos de datos para controles enlazados a datos. Las plantillas de campo proporcionan una manera más sencilla de personalizar la apariencia de los controles de datos que el uso de campos de plantilla para cada campo.
- Validación: los datos dinámicos permiten usar atributos en clases de datos para especificar la validación de escenarios comunes, como campos obligatorios, comprobación de intervalos, comprobación de tipos, coincidencia de patrones mediante expresiones regulares y validación personalizada. Los controles de datos aplican la validación.
Sin embargo, estas características tenían los siguientes requisitos:
- La capa de acceso a datos tenía que basarse en Entity Framework o LINQ to SQL.
- Los únicos controles de origen de datos admitidos para estas características eran los controles EntityDataSource oLinqDataSource.
- Las características requerían un proyecto web que se había creado con las plantillas Datos dinámicos o Entidades de datos dinámicos para tener todos los archivos necesarios para admitir la característica.
Unos de los objetivos principales de la compatibilidad con datos dinámicos en ASP.NET 4 es habilitar la nueva funcionalidad de datos dinámicos para cualquier aplicación ASP.NET. En el ejemplo siguiente se muestra el marcado de los controles que pueden aprovechar las ventajas de la funcionalidad Datos dinámicos en una página existente.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True"
DataKeyNames="ProductID" DataSourceID="LinqDataSource1">
</asp:GridView>
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="DataClassesDataContext" EnableDelete="True" EnableInsert="True"
EnableUpdate="True" TableName="Products">
</asp:LinqDataSource>
En el código de la página, se debe agregar el código siguiente para habilitar la compatibilidad con datos dinámicos para estos controles:
GridView1.EnableDynamicData(typeof(Product));
Cuando el control GridView está en modo de edición, los datos dinámicos validan automáticamente que los datos especificados tienen el formato adecuado. Si no es así, se muestra un mensaje de error.
Esta funcionalidad también proporciona otras ventajas, como la posibilidad de especificar valores predeterminados para el modo de inserción. Sin datos dinámicos, para implementar un valor predeterminado para un campo, debe adjuntar a un evento, buscar el control (mediante FindControl) y establecer su valor. En ASP.NET 4, la llamada EnableDynamicData admite un segundo parámetro que le permite pasar valores predeterminados para cualquier campo del objeto, como se muestra en este ejemplo:
DetailsView1.EnableDynamicData(typeof(Product), new { ProductName = "DefaultName" });
Sintaxis de control DynamicDataManager declarativa
El control DynamicDataManager se ha mejorado para que pueda configurarlo mediante declaración, como con la mayoría de los controles de ASP.NET, en lugar de solo en el código. El marcado del control DynamicDataManager tiene el siguiente aspecto:
<asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
AutoLoadForeignKeys="true">
<DataControls>
<asp:DataControlReference ControlID="GridView1" />
</DataControls>
</asp:DynamicDataManager>
<asp:GridView id="GridView1" runat="server"
</asp:GridView>
Este marcado habilita el comportamiento de datos dinámicos para el control GridView1 al que se hace referencia en la sección DataControls del control DynamicDataManager.
Plantillas de entidad
Las plantillas de entidad ofrecen una nueva manera de personalizar el diseño de los datos sin necesidad de crear una página personalizada. Las plantillas de página usan el control FormView (en lugar del control DetailsView, como se usa en plantillas de página en versiones anteriores de datos dinámicos) y el control DynamicEntity para representar plantillas de entidad. Esto le proporciona más control sobre el marcado que representan los datos dinámicos.
En la lista siguiente se muestra el nuevo diseño del directorio de proyecto que contiene plantillas de entidad:
\DynamicData\EntityTemplates
\DynamicData\EntityTemplates\Default.ascx
\DynamicData\EntityTemplates\Default_Edit.ascx
\DynamicData\EntityTemplates\Default_Insert.ascx
El directorio EntityTemplate
contiene plantillas para mostrar objetos del modelo de datos. De forma predeterminada, los objetos se representan mediante la plantilla Default.ascx
, que proporciona marcado similar al marcado creado por el DetailsView usado por datos dinámicos en ASP.NET 3.5 SP1. En el ejemplo siguiente se muestra del control Default.ascx
:
<asp:EntityTemplate runat="server" ID="TemplateContainer1">
<ItemTemplate>
<tr
<td>
<asp:Label ID="Label1" runat="server" OnInit="Label_Init" />
</td>
<td>
<asp:DynamicControl runat="server" OnInit="DynamicControl_Init" />
</td>
</tr>
</ItemTemplate>
</asp:EntityTemplate>
Las plantillas predeterminadas se pueden editar para cambiar la apariencia de todo el sitio. Hay plantillas para las operaciones de visualización, edición e inserción. Las nuevas plantillas se pueden agregar en función del nombre del objeto de datos para cambiar la apariencia de un único tipo de objeto. Por ejemplo, puede agregar la plantilla siguiente:
\DynamicData\EntityTemplates\Products.aspx
La plantilla puede contener el marcado siguiente:
<tr>
<td>Name</td>
<td><asp:DynamicControl runat="server" DataField="ProductName" /></td>
<td>Category</td>
<td><asp:DynamicControl runat="server" DataField="Category" /></td>
</tr>
Las nuevas plantillas de entidad se muestran en una página mediante el nuevo control DynamicEntity. En tiempo de ejecución, este control se reemplaza por el contenido de la plantilla de entidad. El marcado siguiente muestra el control FormView en la plantilla de página Detail.aspx
que usa la plantilla de entidad. Observe el elemento DynamicEntity en el marcado.
<asp:FormView runat="server" ID="FormView1"
DataSourceID="DetailsDataSource"
OnItemDeleted="FormView1_ItemDeleted">
<ItemTemplate>
<table class="DDDetailsTable" cellpadding="6">
<asp:DynamicEntity runat="server" />
<tr class="td">
<td colspan="2">
<asp:DynamicHyperLink ID="EditHyperLink" runat="server"
Action="Edit" Text="Edit" />
<asp:LinkButton ID="DeleteLinkButton" runat="server"
CommandName="Delete"
CausesValidation="false"
OnClientClick='return confirm("Are you sure you want to delete this item?");'
Text="Delete" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:FormView>
Nuevas plantillas de campo para direcciones URL y direcciones de correo electrónico
ASP.NET 4 presenta dos nuevas plantillas de campo integradas: EmailAddress.ascx
y Url.ascx
. Estas plantillas se usan para campos marcados como EmailAddress oUrlcon el atributo DataType. En el caso de los objetos EmailAddress, el campo se muestra como un hipervínculo que se crea mediante el protocolo mailto:. Cuando los usuarios hacen clic en el vínculo, este abre el cliente de correo electrónico del usuario y crea un mensaje maestro. Los objetos de tipo Url se muestran como hipervínculos normales.
En el ejemplo siguiente se muestra cómo se marcarían los campos.
[DataType(DataType.EmailAddress)]
public object HomeEmail { get; set; }
[DataType(DataType.Url)]
public object Website { get; set; }
Crear vínculos con el control DynamicHyperLink
Los datos dinámicos usan la nueva característica de enrutamiento que se agregó en .NET Framework 3.5 SP1 para controlar las direcciones URL que ven los usuarios finales cuando acceden al sitio web. El nuevo control DynamicHyperLink facilita la creación de vínculos a páginas de un sitio de datos dinámicos. En el ejemplo siguiente se muestra cómo usar el control DynamicHyperLink:
<asp:DynamicHyperLink ID="ListHyperLink" runat="server"
Action="List" TableName="Products">
Show all products
</asp:DynamicHyperLink>
Este marcado crea un vínculo que apunta a la página Lista de la tabla Products
en función de las rutas definidas en el archivo Global.asax
. El control usa automáticamente el nombre de tabla predeterminado en el que se basa la página Datos dinámicos.
Compatibilidad con la herencia en el modelo de datos
Entity Framework y LINQ to SQL admiten la herencia en sus modelos de datos. Un ejemplo de esto podría ser una base de datos que tiene una tablaInsurancePolicy
. También puede contener tablas CarPolicy
y HousePolicy
que tienen los mismos campos queInsurancePolicy
y, a continuación, agregar más campos. Los Datos dinámicos se han modificado para comprender los objetos heredados en el modelo de datos y para admitir scaffolding para las tablas heredadas.
Compatibilidad con relaciones de varios a varios (solo Entity Framework)
Entity Framework tiene gran compatibilidad con las relaciones de varios a varios entre tablas, que se implementa al exponer la relación como una colección en un objeto Entity. Se han agregado nuevas plantillas de campo ManyToMany.ascx
y ManyToMany_Edit.ascx
para proporcionar compatibilidad con la visualización y edición de datos implicados en relaciones de varios a varios.
Nuevos atributos para controlar las enumeraciones de visualización y soporte técnico
Se ha agregado DisplayAttribute para proporcionarle un control adicional sobre cómo se muestran los campos. El atributo DisplayName en versiones anteriores de Datos dinámicos le permitió cambiar el nombre que se usa como título para un campo. La nueva clase DisplayAttribute permite especificar más opciones para mostrar un campo, como el orden en el que se muestra un campo y si se usará un campo como filtro. El atributo también proporciona control independiente del nombre usado para las etiquetas de un control GridView, el nombre usado en un control DetailsView, el texto de ayuda del campo y la marca de agua usada para el campo (si el campo acepta la entrada de texto).
Se ha agregado la clase EnumDataTypeAttribute para permitirle asignar campos a enumeraciones. Al aplicar este atributo a un campo, se especifica un tipo de enumeración. Datos dinámicos usa la nueva plantilla Enumeration.ascx
de campo para crear la interfaz de usuario para mostrar y editar valores de enumeración. La plantilla asigna los valores de la base de datos a los nombres de la enumeración.
Compatibilidad mejorada con filtros
Datos dinámicos 1.0 incluidos con filtros integrados para columnas booleanas y columnas de clave externa. Los filtros no le permitieron especificar si se mostraron o en qué orden se mostraron. El nuevo atributo DisplayAttribute soluciona estos dos problemas al darle control sobre si una columna se muestra como filtro y en qué orden se mostrará.
Una mejora adicional es que se ha vuelto a escribir la compatibilidad con el filtrado para usar la nueva característica de Formularios web. Esto le permite crear filtros sin necesidad de conocer el control de origen de datos con el que se usarán los filtros. Junto con estas extensiones, los filtros también se han convertido en controles de plantilla, lo que permite agregar nuevos. Por último, la clase DisplayAttribute mencionada anteriormente permite reemplazar el filtro predeterminado, de la misma manera que UIHint permite invalidar la plantilla de campo predeterminada para una columna.
Mejoras en el desarrollo web de Visual Studio 2010
El desarrollo web en Visual Studio 2010 se ha mejorado para mejorar la compatibilidad con CSS, aumentar la productividad a través de fragmentos de código de marcado HTML y ASP.NET y nuevos JavaScript dinámicos de IntelliSense.
Compatibilidad de CSS mejorada
El diseñador de Visual Web Developer de Visual Studio 2010 se ha actualizado para mejorar el cumplimiento de los estándares CSS 2.1. El diseñador conserva mejor la integridad del origen HTML y es más sólido que en versiones anteriores de Visual Studio. En segundo plano, también se han realizado mejoras arquitectónicas que permitirán mejoras futuras en la representación, el diseño y la capacidad de servicio.
Fragmentos de código HTML y JavaScript
En el editor HTML, IntelliSense completa automáticamente los nombres de etiqueta. La característica Fragmentos de código de IntelliSense completa automáticamente etiquetas completas y mucho más. En Visual Studio 2010, se admiten fragmentos de código de IntelliSense para JavaScript, junto con C# y Visual Basic, que se admitieron en versiones anteriores de Visual Studio.
Visual Studio 2010 incluye más de 200 fragmentos de código que le ayudan a completar automáticamente etiquetas comunes de ASP.NET y HTML, incluidos los atributos necesarios (como runat="server") y atributos comunes específicos de una etiqueta (como ID, DataSourceID,ControlToValidate y Text).
Puede descargar fragmentos de código adicionales o bien puede escribir sus propios fragmentos de código que encapsulen los bloques de marcado que usted o su equipo usan para tareas comunes.
Mejoras de IntelliSense de JavaScript
En Visual 2010, IntelliSense de JavaScript se ha rediseñado para proporcionar una experiencia de edición aún más completa. IntelliSense ahora reconoce objetos generados dinámicamente por métodos como registerNamespace y por técnicas similares usadas por otros marcos de JavaScript. Se ha mejorado el rendimiento para analizar bibliotecas grandes de scripts y mostrar IntelliSense con poco o ningún retraso de procesamiento. La compatibilidad se ha aumentado considerablemente para admitir casi todas las bibliotecas de terceros y para admitir diversos estilos de codificación. Los comentarios de documentación ahora se analizan a medida que escribe y IntelliSense aprovecha inmediatamente.
Implementación de aplicaciones web con Visual Studio 2010
Cuando los desarrolladores de ASP.NET implementan una aplicación web, a menudo se encuentran problemas como estos:
- La implementación en un sitio de hospedaje compartido requiere tecnologías como FTP, que pueden ser lentas. Además, debe realizar manualmente tareas como ejecutar scripts SQL para configurar una base de datos y debe cambiar la configuración de IIS, como configurar una carpeta de directorio virtual como una aplicación.
- En un entorno empresarial, además de implementar los archivos de aplicación web, los administradores suelen modificar archivos de configuración ASP.NET y los valores de IIS. Los administradores de bases de datos deben ejecutar una serie de scripts SQL para ejecutar la base de datos de la aplicación. Estas instalaciones consumen mucha mano de obra, a menudo tardan horas en completarse y deben documentarse cuidadosamente.
Visual Studio 2010 tiene tecnologías que abordan estos problemas y que permiten implementar aplicaciones web sin problemas. Una de estas tecnologías es la herramienta de implementación web de IIS (MsDeploy.exe).
Las características de implementación web de Visual Studio 2010 incluyen las siguientes áreas principales:
- Empaquetado web
- Transformación de Web.config
- Implementación de bases de datos
- Publicación con un solo clic para aplicaciones web
En las siguientes secciones se proporcionan detalles sobre estas características.
Empaquetado web
Visual Studio 2010 usa la herramienta MSDeploy para crear un archivo comprimido (.zip) para la aplicación, lo que se conoce como paquete web. El archivo de paquete contiene metadatos sobre la aplicación más el siguiente contenido:
- Configuración de IIS, que incluye la configuración del grupo de aplicaciones, la configuración de página de errores, etc.
- El contenido web real, que incluye páginas web, controles de usuario, contenido estático (imágenes y archivos HTML), etc.
- Esquemas y datos de base de datos de SQL Server.
- Certificados de seguridad, componentes que se instalarán en la GAC, la configuración del Registro, etc.
Un paquete web se puede copiar en cualquier servidor y, a continuación, instalarlo manualmente mediante el Administrador de IIS. Como alternativa, para la implementación automatizada, el paquete se puede instalar mediante comandos de línea de comandos o mediante api de implementación.
Visual Studio 2010 proporciona tareas y destinos integrados de MSBuild para crear paquetes web. Para más información, consulte Introducción a la implementación de proyectos de aplicaciones web ASP.NET en el sitio web de MSDN y 10 + 20 razones por las que debe crear un Paquete web en el blog de Vishal Joshi.
Transformación Web.config
Para la implementación de aplicaciones web, Visual Studio 2010 presenta Transformación de documentos XML (XDT), que es una característica que permite transformar un archivo Web.config
de la configuración de desarrollo a la configuración de producción. La configuración de transformación se especifica en los archivos de transformación denominados web.debug.config
, web.release.config
, etc. (Los nombres de estos archivos coinciden con las configuraciones de MSBuild). Un archivo de transformación incluye solo los cambios que debe realizar en un archivo Web.config
implementado. Los cambios se especifican mediante sintaxis simple.
En el ejemplo siguiente se muestra una parte de un archivo web.release.config
que podría generarse para la implementación de la configuración de versión. La palabra clave Replace del ejemplo especifica que durante la implementación, el nodo connectionString del archivoWeb.config
se reemplazará por los valores que aparecen en el ejemplo.
<connectionStrings xdt:Transform="Replace">
<add name="BlogDB" connectionString="connection string detail]" />
</connectionStrings>
Para más información, consulte Sintaxis de transformación Web.config para la Implementación de proyectos de aplicación web en el sitio web de MSDN y Implementación web: transformación Web.Config en el blog de Vishal Joshi.
Implementación de bases de datos
Un paquete de implementación de Visual Studio 2010 puede incluir dependencias en bases de datos de SQL Server. Como parte de la definición del paquete, proporcione la cadena de conexión para la base de datos de origen. Al crear el paquete web, Visual Studio 2010 crea scripts SQL para el esquema de base de datos y, opcionalmente, para los datos y, a continuación, los agrega al paquete. También puede proporcionar scripts SQL personalizados y especificar la secuencia en la que deben ejecutarse en el servidor. En el momento de la implementación, se proporciona una cadena de conexión adecuada para el servidor de destino. Después, el proceso de implementación usa esta cadena de conexión para ejecutar los scripts que crean el esquema de la base de datos y agregan los datos.
Además, mediante la publicación con un solo clic puede configurar la implementación para publicar la base de datos directamente cuando la aplicación se publica en un sitio remoto de hospedaje compartido. Para obtener más información, vea Cómo implementar una base de datos con un proyecto de aplicación web en el sitio web de MSDN y Implementación de bases de datos con VS 2010 en el blog de Vishal Joshi.
Publicar con un solo clic para Aplicaciones web
Visual Studio 2010 también permite usar el servicio de administración remota de IIS para publicar una aplicación web en un servidor remoto. Puede crear un perfil de publicación para la cuenta de hospedaje o para probar servidores o servidores de ensayo. Cada perfil puede guardar las credenciales adecuadas de forma segura. A continuación, puede implementar en cualquiera de los servidores de destino con un solo clic mediante la barra de herramientas Publicar con un solo clic web. Con Visual Studio 2010, también puede publicar mediante la línea de comandos de MSBuild. Esto le permite configurar el entorno de compilación del equipo para incluir la publicación en un modelo de integración continua.
Para más información, consulte Cómo implementar un proyecto de aplicación web utilizando la publicación con un solo clic y Web Deploy en el sitio web de MSDN y Publicación con un solo clic en web con VS 2010 en el blog de Vishal Joshi. Para ver videopresentaciones sobre la implementación de aplicaciones web en Visual Studio 2010, consulte VS 2010 for Web Developer Previews en el blog de Vishal Joshi.
Recursos
Estos sitios web proporcionan información adicional sobre ASP.NET 4 y Visual Studio 2010.
- ASP.NET 4: la documentación oficial de ASP.NET 4 en el sitio web de MSDN.
- https://www.asp.net/: Sitio web propio del equipo de ASP.NET.
- https://www.asp.net/dynamicdata/ y ASP.NET mapa de contenido de datos dinámicos: recursos en línea en el sitio de grupo de ASP.NET y en la documentación oficial para ASP.NET datos dinámicos.
- https://www.asp.net/ajax/ : el recurso web principal para ASP.NET desarrollo de AJAX.
- https://devblogs.microsoft.com/dotnet/category/aspnet/: blog del equipo para desarrolladores web de Visual, que incluye información sobre las características de Visual Studio 2010.
- ASP.NET WebStack: el recurso web principal para versiones preliminares de ASP.NET.
Declinación de responsabilidades
Este documento es preliminar y puede cambiar considerablemente antes de la versión comercial final del software que se describe en él.
La información contenida en este documento representa la visión actual de Microsoft Corporation sobre los asuntos tratados a fecha de su publicación. Dado que Microsoft debe responder a condiciones de mercado variables, no debe interpretarse como un compromiso por parte de Microsoft, y Microsoft no puede garantizar la precisión de la información presentada tras la fecha de publicación.
Estas notas del producto solo tienen fines informativos. MICROSOFT NO OTORGA NINGUNA GARANTÍA, EXPRESA, IMPLÍCITA O ESTUTARIAS, EN LA INFORMACIÓN DE ESTE DOCUMENTO.
Es responsabilidad del usuario el cumplimiento de todas las leyes de propiedad intelectual aplicables. Sin perjuicio de los derechos que conforman la legislación de propiedad intelectual, ninguna parte de este documento se puede reproducir, almacenar o incorporar en un sistema de recuperación, ni se puede transmitir de forma alguna o por ningún medio (electrónico, mecánico, fotocopia, grabación o de otro modo) ni para ningún propósito, sin el expreso permiso por escrito de Microsoft Corporation.
Microsoft puede ser titular de patentes, solicitudes de patentes, marcas, derechos de autor y otros derechos de propiedad intelectual sobre los contenidos de este documento. El suministro de este documento no le otorga ninguna licencia sobre estas patentes, marcas, derechos de autor u otros derechos de propiedad intelectual, a menos que ello se prevea en un contrato por escrito de licencia de Microsoft.
A menos que se indique lo contrario, los ejemplos de nombres de compañías, organizaciones, productos, nombres de dominio, direcciones de correo electrónico, logotipos, personas, lugares y eventos aquí mencionados son ficticios, y no se pretende ni se debe deducir asociación alguna con compañías, organizaciones, productos, nombres de dominio, direcciones de correo electrónico, logotipos, personas, lugares o eventos reales.
© 2009 Microsoft Corporation. Todos los derechos reservados.
Microsoft y Windows son marcas registradas o marcas comerciales de Microsoft Corporation en Estados Unidos y en otros países.
Los nombres de las compañías y productos reales mencionados en el presente documento pueden ser marcas comerciales de sus respectivos propietarios.