Introducción a trabajar con una base de datos en sitios de ASP.NET Web Pages (Razor)

por Tom FitzMacken

En este artículo se describe cómo usar las herramientas de Microsoft WebMatrix para crear una base de datos en un sitio web de ASP.NET Web Pages (Razor) y cómo crear páginas que le permiten mostrar, agregar, editar y eliminar datos.

Lo que aprenderá:

  • Cómo crear una base de datos.
  • Cómo conectarse a una base de datos.
  • Cómo mostrar datos en una página web.
  • Cómo insertar, actualizar y eliminar registros de base de datos.

Estas son las características introducidas en el artículo:

  • Trabajar con una base de datos de Microsoft SQL Server Compact Edition.
  • Trabajar con consultas SQL.
  • La clase Database.

Versiones de software usadas en el tutorial

  • páginas web de ASP.NET (Razor) 2
  • WebMatrix 2

Este tutorial también funciona con WebMatrix 3. Puede usar ASP.NET Web Pages 3 y Visual Studio 2013 (o Visual Studio Express 2013 para Web); sin embargo, la interfaz de usuario será diferente.

Introducción a las bases de datos

Imagine una libreta de direcciones típica. Para cada entrada de la libreta de direcciones (es decir, para cada persona) tiene varios fragmentos de información, como el nombre, el apellido, la dirección, la dirección de correo electrónico y el número de teléfono.

Una manera típica de representar datos como estos es como una tabla con filas y columnas. En términos de base de datos, cada fila se conoce a menudo como un registro. Cada columna (a veces denominada campos) contiene un valor para cada tipo de datos: nombre, apellido, etc.

ID FirstName LastName Dirección Correo electrónico Teléfono
1 Jim Abrus 210 100th St SE Orcas WA 98031 jim@contoso.com 555 0100
2 Terry Adams 1234 Main St. Seattle WA 99011 terry@cohowinery.com 555 0101

Para la mayoría de las tablas de base de datos, la tabla debe tener una columna que contenga un identificador único, como un número de cliente, un número de cuenta, etc. Esto se conoce como clave principal de la tabla y se usa para identificar cada fila de la tabla. En el ejemplo, la columna ID es la clave principal de la libreta de direcciones.

Con esta comprensión básica de las bases de datos, está listo para aprender a crear una base de datos sencilla y realizar operaciones como agregar, modificar y eliminar datos.

Sugerencia

Bases de datos relacionales

Puede almacenar datos de muchas maneras, incluidos archivos de texto y hojas de cálculo. Sin embargo, para la mayoría de los usos empresariales, los datos se almacenan en una base de datos relacional.

En este artículo no se profundiza mucho en las bases de datos. Sin embargo, es posible que le resulte útil comprender un poco sobre ellos. En una base de datos relacional, la información se divide lógicamente en tablas independientes. Por ejemplo, una base de datos para una escuela podría contener tablas independientes para los alumnos y para las ofertas de clase. El software de base de datos (como SQL Server) admite comandos eficaces que permiten establecer dinámicamente relaciones entre las tablas. Por ejemplo, puede usar la base de datos relacional para establecer una relación lógica entre alumnos y clases con el fin de crear una programación. El almacenamiento de datos en tablas independientes reduce la complejidad de la estructura de la tabla y reduce la necesidad de mantener los datos redundantes en las tablas.

Creación de una base de datos

En este procedimiento se muestra cómo crear una base de datos denominada SmallBakery mediante la herramienta de diseño de base de datos de SQL Server Compact que se incluye en WebMatrix. Aunque puede crear una base de datos mediante código, es más habitual crear la base de datos y las tablas de base de datos mediante una herramienta de diseño como WebMatrix.

  1. Inicie WebMatrix y, en la página Inicio rápido, haga clic en Sitio desde plantilla.

  2. Seleccione Sitio vacío y, en el cuadro Nombre del sitio , escriba "SmallBakery" y, a continuación, haga clic en Aceptar. El sitio se crea y se muestra en WebMatrix.

  3. En el panel izquierdo, haga clic en el área de trabajo Bases de datos .

  4. En la cinta de opciones, haga clic en Nueva base de datos. Se crea una base de datos vacía con el mismo nombre que el sitio.

  5. En el panel izquierdo, expanda el nodo SmallBakery.sdf y, a continuación, haga clic en Tablas.

  6. En la cinta de opciones, haga clic en Nueva tabla. WebMatrix abre el diseñador de tablas.

    [Captura de pantalla que muestra la matriz web al abrir el diseñador de tablas].

  7. Haga clic en la columna Nombre y escriba "Id".

  8. En la columna Tipo de datos , seleccione int.

  9. Establezca las opciones Is Primary Key? (¿Es la clave principal?) y Is Identify? (¿Identificar?) en .

    Como sugiere el nombre, Is Primary Key indica a la base de datos que será la clave principal de la tabla. Is Identity indica a la base de datos que cree automáticamente un número de identificador para cada registro nuevo y asígnele el siguiente número secuencial (a partir de 1).

  10. Haga clic en la fila siguiente. El editor inicia una nueva definición de columna.

  11. En el valor Nombre, escriba "Nombre".

  12. En Tipo de datos, elija "nvarchar" y establezca la longitud en 50. La parte var de nvarchar indica a la base de datos que los datos de esta columna serán una cadena cuyo tamaño puede variar de un registro a otro. (El prefijo n representa nacional, lo que indica que el campo puede contener datos de caracteres que representen cualquier sistema de escritura o alfabeto, es decir, que el campo contenga datos Unicode).

  13. Establezca la opción Permitir valores NULL en No. Esto aplicará que la columna Nombre no quede en blanco.

  14. Con este mismo proceso, cree una columna denominada Descripción. Establezca Tipo de datos en "nvarchar" y 50 para la longitud y establezca Permitir valores NULL en false.

  15. Cree una columna denominada Price. Establezca Tipo de datos en "money" y establezca Permitir valores NULL en false.

  16. En el cuadro de la parte superior, asigne un nombre a la tabla "Producto".

    Cuando haya terminado, la definición tendrá este aspecto:

    [Captura de pantalla que muestra el aspecto de la definición cuando termine.]

  17. Presione Ctrl+S para guardar la tabla.

Agregar datos a la base de datos

Ahora puede agregar algunos datos de ejemplo a la base de datos con la que trabajará más adelante en el artículo.

  1. En el panel izquierdo, expanda el nodo SmallBakery.sdf y, a continuación, haga clic en Tablas.

  2. Haga clic con el botón derecho en la tabla Product y, a continuación, haga clic en Datos.

  3. En el panel de edición, escriba los siguientes registros:

    Nombre Descripción Precio
    Pan Horneado fresco todos los días. 2,99
    Tarta de fresa Hecho con fresas orgánicas de nuestro jardín. 9.99
    Apple Pie Solo superado por el pastel de tu madre. 12.99
    Pastel pecan Si te gustan las pecanes, esto es para ti. 10,99
    Pastel de limón Hecho con los mejores limones del mundo. 11,99
    Magdalenas Tus hijos y el niño en ti te encantarán. 7,99

    Recuerde que no tiene que escribir nada para la columna Id . Al crear la columna Id , se establece su propiedad Is Identity en true, lo que hace que se rellene automáticamente.

    Cuando haya terminado de escribir los datos, el diseñador de tablas tendrá este aspecto:

    [Captura de pantalla que muestra el aspecto que tendrá el diseñador de tablas cuando terminen de escribirse los datos].

  4. Cierre la pestaña que contiene los datos de la base de datos.

Mostrar datos de una base de datos

Una vez que tenga una base de datos con datos en ella, puede mostrar los datos en una página web de ASP.NET. Para seleccionar las filas de tabla que se van a mostrar, use una instrucción SQL, que es un comando que se pasa a la base de datos.

  1. En el panel izquierdo, haga clic en el área de trabajo Archivos .

  2. En la raíz del sitio web, cree una nueva página CSHTML denominada ListProducts.cshtml.

  3. Reemplace el marcado existente por lo siguiente:

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
     }
    <!DOCTYPE html>
    <html>
     <head>
       <title>Small Bakery Products</title>
       <style>
           table, th, td {
             border: solid 1px #bbbbbb;
             border-collapse: collapse;
             padding: 2px;
           }
        </style>
     </head>
     <body>
       <h1>Small Bakery Products</h1>
       <table>
           <thead>
               <tr>
                   <th>Id</th>
                   <th>Product</th>
                   <th>Description</th>
           <th>Price</th>
               </tr>
           </thead>
           <tbody>
               @foreach(var row in db.Query(selectQueryString)){
                <tr>
                   <td>@row.Id</td>
                       <td>@row.Name</td>
                       <td>@row.Description</td>
                       <td>@row.Price</td>
                </tr>
               }
           </tbody>
       </table>
     </body>
    </html>
    

    En el primer bloque de código, abra el archivo SmallBakery.sdf (base de datos) que creó anteriormente. El Database.Open método supone que el archivo .sdf está en la carpeta App_Data del sitio web. (Tenga en cuenta que no es necesario especificar la extensión .sdf ; de hecho, si lo hace, el Open método no funcionará).

    Nota:

    La carpeta App_Data es una carpeta especial en ASP.NET que se usa para almacenar archivos de datos. Para obtener más información, consulte Conexión a una base de datos más adelante en este artículo.

    A continuación, realice una solicitud para consultar la base de datos mediante la siguiente instrucción SQL Select :

    SELECT * FROM Product ORDER BY Name
    

    En la instrucción , Product identifica la tabla que se va a consultar. El * carácter especifica que la consulta debe devolver todas las columnas de la tabla. (También puede enumerar columnas individualmente, separadas por comas, si desea ver solo algunas de las columnas). La Order By cláusula indica cómo se deben ordenar los datos; en este caso, por la columna Nombre . Esto significa que los datos se ordenan alfabéticamente en función del valor de la columna Nombre para cada fila.

    En el cuerpo de la página, el marcado crea una tabla HTML que se usará para mostrar los datos. Dentro del <tbody> elemento , se usa un foreach bucle para obtener individualmente cada fila de datos devuelta por la consulta. Para cada fila de datos, se crea una fila de tabla HTML (<tr> elemento). A continuación, se crean celdas de tabla HTML (<td> elementos) para cada columna. Cada vez que se recorra el bucle, la siguiente fila disponible de la base de datos se encuentra en row variable (se configura en la sentencia foreach). Para obtener una columna individual de la fila, puede usar row.Name o row.Description cualquiera que sea el nombre de la columna que desee.

  4. Ejecute la página en un explorador. (Asegúrese de que la página está seleccionada en el área de trabajo Archivos antes de ejecutarla). La página muestra una lista similar a la siguiente:

    [Captura de pantalla que muestra la lista en la que se mostrará la página en el explorador.

Sugerencia

Lenguaje de consulta estructurado (SQL)

SQL es un lenguaje que se usa en la mayoría de las bases de datos relacionales para administrar datos en una base de datos. Incluye comandos que permiten recuperar datos y actualizarlos, y que permiten crear, modificar y administrar tablas de base de datos. SQL es diferente de un lenguaje de programación (como el que usa en WebMatrix) porque con SQL, la idea es que indique a la base de datos lo que desea y es el trabajo de la base de datos averiguar cómo obtener los datos o realizar la tarea. Estos son ejemplos de algunos comandos SQL y lo que hacen:

SELECT Id, Name, Price FROM Product WHERE Price > 10.00 ORDER BY Name

Esto captura las columnas Id, Name y Price de los registros de la tabla Product si el valor de Price es superior a 10 y devuelve los resultados en orden alfabético en función de los valores de la columna Name . Este comando devolverá un conjunto de resultados que contiene los registros que cumplen los criterios o un conjunto vacío si no coinciden registros.

INSERT INTO Product (Name, Description, Price) VALUES ("Croissant", "A flaky delight", 1.99)

Esto inserta un nuevo registro en la tabla Product, estableciendo la columna Name como "Croissant", la columna Description como "A flaky delight" y el precio en 1,99.

DELETE FROM Product WHERE ExpirationDate < "01/01/2008"

Este comando elimina los registros de la tabla Product cuya columna de fecha de expiración es anterior al 1 de enero de 2008. (Esto supone que la tabla Product tiene tal columna, por supuesto). La fecha se especifica aquí en formato MM/DD/AAAA, pero debe escribirse en el formato que se usa para la configuración regional.

Los Insert Into comandos y Delete no devuelven conjuntos de resultados. En su lugar, devuelven un número que indica cuántos registros se han visto afectados por el comando .

Para algunas de estas operaciones (como insertar y eliminar registros), el proceso que solicita la operación debe tener los permisos adecuados en la base de datos. Este es el motivo por el que, para las bases de datos de producción, a menudo tiene que proporcionar un nombre de usuario y una contraseña al conectarse a la base de datos.

Hay docenas de comandos SQL, pero todos siguen un patrón similar al siguiente. Puede usar comandos SQL para crear tablas de base de datos, contar el número de registros de una tabla, calcular los precios y realizar muchas más operaciones.

Insertar datos en una base de datos

En esta sección se muestra cómo crear una página que permita a los usuarios agregar un nuevo producto a la tabla base de datos Product . Después de insertar un nuevo registro de producto, la página muestra la tabla actualizada con la página ListProducts.cshtml que creó en la sección anterior.

La página incluye validación para asegurarse de que los datos que escribe el usuario son válidos para la base de datos. Por ejemplo, el código de la página garantiza que se ha escrito un valor para todas las columnas necesarias.

  1. En el sitio web, cree un nuevo archivo CSHTML denominado InsertProducts.cshtml.

  2. Reemplace el marcado existente por lo siguiente:

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var db = Database.Open("SmallBakery");
        var Name = Request.Form["Name"];
        var Description = Request.Form["Description"];
        var Price = Request.Form["Price"];
    
        if (IsPost && Validation.IsValid()) {
            // Define the insert query. The values to assign to the
            // columns in the Product table are defined as parameters
            // with the VALUES keyword.
            if(ModelState.IsValid) {
                var insertQuery = "INSERT INTO Product (Name, Description, Price) " +
                    "VALUES (@0, @1, @2)";
                db.Execute(insertQuery, Name, Description, Price);
                // Display the page that lists products.
                Response.Redirect("~/ListProducts");
            }
        }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
     <title>Add Products</title>
     <style type="text/css">
        label {float:left; width: 8em; text-align: right;
               margin-right: 0.5em;}
        fieldset {padding: 1em; border: 1px solid; width: 50em;}
        legend {padding: 2px 4px; border: 1px solid; font-weight:bold;}
        .validation-summary-errors {font-weight:bold; color:red;
               font-size: 11pt;}
     </style>
    </head>
    <body>
     <h1>Add New Product</h1>
    
     @Html.ValidationSummary("Errors with your submission:")
    
     <form method="post" action="">
       <fieldset>
         <legend>Add Product</legend>
         <div>
           <label>Name:</label>
           <input name="Name" type="text" size="50" value="@Name" />
         </div>
         <div>
           <label>Description:</label>
           <input name="Description" type="text" size="50"
               value="@Description" />
         </div>
         <div>
           <label>Price:</label>
           <input name="Price" type="text" size="50" value="@Price" />
         </div>
         <div>
           <label>&nbsp;</label>
           <input type="submit" value="Insert" class="submit" />
         </div>
       </fieldset>
     </form>
    </body>
    </html>
    

    El cuerpo de la página contiene un formulario HTML con tres cuadros de texto que permiten a los usuarios escribir un nombre, una descripción y un precio. Cuando los usuarios hacen clic en el botón Insertar , el código de la parte superior de la página abre una conexión a la base de datos SmallBakery.sdf . A continuación, obtiene los valores que el usuario ha enviado mediante el Request objeto y asigna esos valores a variables locales.

    Para validar que el usuario escribió un valor para cada columna necesaria, registre cada <input> elemento que desee validar:

    Validation.RequireField("Name", "Product name is required.");
    Validation.RequireField("Description", "Product description is required.");
    Validation.RequireField("Price", "Product price is required.");
    

    El Validation asistente comprueba que hay un valor en cada uno de los campos que ha registrado. Puede probar si todos los campos han superado la validación comprobando Validation.IsValid(), lo cual normalmente hace antes de procesar la información que obtiene del usuario:

    if (IsPost && Validation.IsValid()) {
        // Process information here
    }
    

    (El && operador significa AND— esta prueba es Si se trata de un envío de formulario Y todos los campos han superado la validación).

    Si todas las columnas validadas (ninguna estaban vacías), continúe y cree una instrucción SQL para insertar los datos y, a continuación, ejecútelo como se muestra a continuación:

    var insertQuery =
        "INSERT INTO Product (Name, Description, Price) VALUES (@0, @1, @2)";
    

    Para que los valores se inserten, incluya los marcadores de posición de los parámetros (@0, @1, @2).

    Nota:

    Como precaución de seguridad, pase siempre valores a una instrucción SQL mediante parámetros, como se muestra en el ejemplo anterior. Esto le ofrece la oportunidad de validar los datos del usuario, además de que ayuda a protegerse frente a intentos de enviar comandos malintencionados a la base de datos (a veces denominados ataques por inyección de CÓDIGO SQL).

    Para ejecutar la consulta, use esta instrucción y pase a ella las variables que contienen los valores que se van a sustituir por los marcadores de posición:

    db.Execute(insertQuery, Name, Description, Price);
    

    Una vez ejecutada la Insert Into instrucción , se envía al usuario a la página que muestra los productos mediante esta línea:

    Response.Redirect("~/ListProducts");
    

    Si la validación no se realizó correctamente, omita la inserción. En su lugar, tiene un asistente en la página que puede mostrar los mensajes de error acumulados (si los hay):

    @Html.ValidationSummary("Errors with your submission:")
    

    Observe que el bloque de estilo del marcado incluye una definición de clase CSS denominada .validation-summary-errors. Este es el nombre de la clase CSS que se usa de forma predeterminada para el <div> elemento que contiene los errores de validación. En este caso, la clase CSS especifica que los errores de resumen de validación se muestran en rojo y en negrita, pero puede definir la .validation-summary-errors clase para mostrar cualquier formato que desee.

Probar la página de inserción

  1. Vea la página en un explorador. La página muestra un formulario similar al que se muestra en la ilustración siguiente.

    [Captura de pantalla que muestra un formulario que se mostrará en la página en un explorador].

  2. Escriba los valores de todas las columnas, pero asegúrese de dejar en blanco la columna Precio .

  3. Haga clic en Insertar. La página muestra un mensaje de error, como se muestra en la ilustración siguiente. (No se crea ningún registro nuevo).

    [Captura de pantalla que muestra un mensaje de error].

  4. Rellene el formulario por completo y, a continuación, haga clic en Insertar. Esta vez, se muestra la página ListProducts.cshtml y muestra el nuevo registro.

Actualizar datos en una base de datos

Después de escribir los datos en una tabla, es posible que tenga que actualizarlos. Este procedimiento muestra cómo crear dos páginas similares a las que creó anteriormente para la inserción de datos. La primera página muestra los productos y permite a los usuarios seleccionar uno para cambiar. La segunda página permite a los usuarios realizar las modificaciones y guardarlas.

Nota:

Importante En un sitio web de producción, normalmente restringe quién puede realizar cambios en los datos. Para obtener información sobre cómo configurar la pertenencia y sobre las formas de autorizar a los usuarios a realizar tareas en el sitio, vea Agregar seguridad y pertenencia a un sitio de páginas web de ASP.NET.

  1. En el sitio web, cree un nuevo archivo CSHTML denominado EditProducts.cshtml.

  2. Reemplace el marcado existente en el archivo por lo siguiente:

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Edit Products</title>
        <style type="text/css">
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
        </style>
    </head>
    <body>
        <h1>Edit Small Bakery Products</h1>
        <table>
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
    </body>
    </html>
    

    La única diferencia entre esta página y la página ListProducts.cshtml de anteriormente es que la tabla HTML de esta página incluye una columna adicional que muestra un vínculo Editar . Al hacer clic en este vínculo, se le lleva a la página UpdateProducts.cshtml (que creará a continuación) donde puede editar el registro seleccionado.

    Examine el código que crea el vínculo Editar :

    <a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
    

    Esto crea un elemento HTML <a> cuyo href atributo se establece dinámicamente. El href atributo especifica la página que se va a mostrar cuando el usuario hace clic en el vínculo. También pasa el Id valor de la fila actual al vínculo. Cuando se ejecuta la página, el origen de la página puede contener vínculos como estos:

    <a href="UpdateProducts/1">Edit</a></td>
    <a href="UpdateProducts/2">Edit</a></td>
    <a href="UpdateProducts/3">Edit</a></td>
    

    Observe que el atributo href se establece en UpdateProducts/n, donde n es un número de producto. Cuando un usuario hace clic en uno de estos vínculos, la dirección URL resultante tendrá un aspecto similar al siguiente:

    http://localhost:18816/UpdateProducts/6

    En otras palabras, se pasará el número de producto que se va a editar en la URL.

  3. Vea la página en un explorador. La página muestra los datos en un formato similar al siguiente:

    [Captura de pantalla que muestra los datos mostrados en la página del explorador.

    A continuación, creará la página que permite a los usuarios actualizar realmente los datos. La página de actualización incluye la validación para validar los datos que escribe el usuario. Por ejemplo, el código de la página garantiza que se ha escrito un valor para todas las columnas necesarias.

  4. En el sitio web, cree un nuevo archivo CSHTML denominado UpdateProducts.cshtml.

  5. Reemplace el marcado existente en el archivo por lo siguiente.

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var Name = "";
        var Description = "";
        var Price = Decimal.Zero;
    
        var ProductId  = UrlData[0];
        if (ProductId.IsEmpty()) {
             Response.Redirect("~/EditProducts");
        }
    
        var db = Database.Open("SmallBakery");
    
        if (IsPost && Validation.IsValid()) {
            var updateQueryString =
                "UPDATE Product SET Name=@0, Description=@1, Price=@2 WHERE Id=@3" ;
            Name = Request["Name"];
            Description = Request["Description"];
            Price = Request["Price"].AsDecimal();
            db.Execute(updateQueryString, Name, Description, Price, ProductId);
            Response.Redirect(@Href("~/EditProducts"));
        }
        else {
            var selectQueryString = "SELECT * FROM Product WHERE Id=@0";
    
            var row = db.QuerySingle(selectQueryString, ProductId);
            Name = row.Name;
            Description = row.Description;
            Price = row.Price;
        }
    
    }
    
    <!DOCTYPE html>
    <html>
    <head>
      <title>Add Products</title>
      <style type="text/css">
         label { float: left; width: 8em; text-align: right;
                 margin-right: 0.5em;}
         fieldset { padding: 1em; border: 1px solid; width: 35em;}
         legend { padding: 2px 4px;  border: 1px solid; font-weight: bold;}
         .validation-summary-errors {font-weight:bold; color:red; font-size:11pt;}
      </style>
    </head>
    <body>
      <h1>Update Product</h1>
       @Html.ValidationSummary("Errors with your submission:")
       <form method="post" action="">
         <fieldset>
           <legend>Update Product</legend>
           <div>
             <label>Name:</label>
             <input name="Name" type="text" size="50" value="@Name" />
           </div>
           <div>
             <label>Description:</label>
             <input name="Description" type="text" size="50"
                value="@Description" />
           </div>
           <div>
              <label>Price:</label>
              <input name="Price" type="text" size="50" value="@Price" />
           </div>
           <div>
              <label>&nbsp;</label>
              <input type="submit" value="Update" class="submit" />
           </div>
        </fieldset>
      </form>
    </body>
    </html>
    

    El cuerpo de la página contiene un formulario HTML donde se muestra un producto y donde los usuarios pueden editarlo. Para que se muestre el producto, use esta instrucción SQL:

    SELECT * FROM Product WHERE Id=@0
    

    Esto seleccionará el producto cuyo identificador coincide con el valor que se pasa en el @0 parámetro . (Dado que Id es la clave principal y, por lo tanto, debe ser único, solo se puede seleccionar un registro de producto de esta manera). Para obtener el valor de identificador que se va a pasar a esta Select instrucción, puede leer el valor que se pasa a la página como parte de la dirección URL mediante la sintaxis siguiente:

    var ProductId  = UrlData[0];
    

    Para capturar realmente el registro del producto, use el QuerySingle método , que devolverá solo un registro:

    var row = db.QuerySingle(selectQueryString, ProductId);
    

    La fila única se devuelve a la row variable . Puede obtener datos de cada columna y asignarlos a variables locales como esta:

    var Name = row.Name;
    var Description = row.Description;
    var Price = row.Price;
    

    En el marcado del formulario, estos valores se muestran automáticamente en cuadros de texto individuales mediante código incrustado como el siguiente:

    <input name="Name" type="text" size="50" value="@Name" />
    

    Esa parte del código muestra el registro del producto que se va a actualizar. Una vez que se haya mostrado el registro, el usuario puede editar columnas individuales.

    Cuando el usuario envía el formulario haciendo clic en el botón Actualizar , se ejecuta el código del if(IsPost) bloque. Esto obtiene los valores del usuario del Request objeto , almacena los valores en variables y valida que cada columna se ha rellenado. Si se supera la validación, el código crea la siguiente instrucción SQL Update:

    UPDATE Product SET Name=@0, Description=@1, Price=@2, WHERE ID=@3
    

    En una instrucción SQL Update , especifique cada columna en la que se va a actualizar y el valor en el que se va a establecer. En este código, los valores se especifican mediante los marcadores @0de posición del parámetro , @1, @2, etc. (Como se indicó anteriormente, para la seguridad, siempre debe pasar valores a una instrucción SQL mediante parámetros).

    Al llamar al db.Execute método , se pasan las variables que contienen los valores en el orden que corresponde a los parámetros de la instrucción SQL:

    db.Execute(updateQueryString, Name, Description, Price, ProductId);
    

    Una vez ejecutada la Update instrucción , llame al método siguiente para redirigir al usuario de nuevo a la página de edición:

    Response.Redirect(@Href("~/EditProducts"));
    

    El efecto es que el usuario ve una lista actualizada de los datos de la base de datos y puede editar otro producto.

  6. Guarde la página.

  7. Ejecute la página EditProducts.cshtml (no la página de actualización) y, a continuación, haga clic en Editar para seleccionar un producto que desea editar. Se muestra la página UpdateProducts.cshtml , que muestra el registro seleccionado.

    [Captura de pantalla que muestra la página Actualizar productos, junto con el registro seleccionado.]

  8. Realice un cambio y haga clic en Actualizar. La lista de productos se muestra de nuevo con los datos actualizados.

Eliminación de datos en una base de datos

En esta sección se muestra cómo permitir que los usuarios eliminen un producto de la tabla base de datos Product . El ejemplo consta de dos páginas. En la primera página, los usuarios seleccionan un registro que desea eliminar. El registro que se va a eliminar se muestra en una segunda página que les permite confirmar que quieren eliminar el registro.

Nota:

Importante En un sitio web de producción, normalmente restringe quién puede realizar cambios en los datos. Para obtener información sobre cómo configurar la pertenencia y sobre las formas de autorizar al usuario a realizar tareas en el sitio, vea Agregar seguridad y pertenencia a un sitio de páginas web de ASP.NET.

  1. En el sitio web, cree un nuevo archivo CSHTML denominado ListProductsForDelete.cshtml.

  2. Reemplace el marcado existente por lo siguiente:

    @{
      var db = Database.Open("SmallBakery");
      var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete a Product</title>
        <style>
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
         </style>
    </head>
    <body>
      <h1>Delete a Product</h1>
      <form method="post" action="" name="form">
        <table border="1">
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/DeleteProduct", row.Id)">Delete</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
      </form>
    </body>
    </html>
    

    Esta página es similar a la página EditProducts.cshtml de la anterior. Sin embargo, en lugar de mostrar un vínculo Editar para cada producto, muestra un vínculo Eliminar . El vínculo Eliminar se crea con el siguiente código incrustado en el marcado:

    <a href="@Href("~/DeleteProduct", row.Id)">Delete</a>
    

    Esto crea una dirección URL similar a esta cuando los usuarios hacen clic en el vínculo:

    http://<server>/DeleteProduct/4

    La dirección URL llama a una página denominada DeleteProduct.cshtml (que creará a continuación) y la pasa el identificador del producto que se va a eliminar (aquí, 4).

  3. Guarde el archivo, pero déjelo abierto.

  4. Cree otro archivo CHTML denominado DeleteProduct.cshtml. Reemplace el contenido existente por lo siguiente:

    @{
      var db = Database.Open("SmallBakery");
      var ProductId = UrlData[0];
      if (ProductId.IsEmpty()) {
        Response.Redirect("~/ListProductsForDelete");
      }
      var prod = db.QuerySingle("SELECT * FROM PRODUCT WHERE ID = @0", ProductId);
      if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
      }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete Product</title>
    </head>
    <body>
      <h1>Delete Product - Confirmation</h1>
      <form method="post" action="" name="form">
        <p>Are you sure you want to delete the following product?</p>
    
        <p>Name: @prod.Name <br />
           Description: @prod.Description <br />
           Price: @prod.Price</p>
        <p><input type="submit" value="Delete" /></p>
      </form>
    </body>
    </html>
    

    ListProductsForDelete.cshtml llama a esta página y permite a los usuarios confirmar que quieren eliminar un producto. Para enumerar el producto que se va a eliminar, obtendrá el identificador del producto que se va a eliminar de la dirección URL mediante el código siguiente:

    var ProductId = UrlData[0];
    

    A continuación, la página pide al usuario que haga clic en un botón para eliminar realmente el registro. Esta es una medida de seguridad importante: al realizar operaciones confidenciales en su sitio web, como actualizar o eliminar datos, estas operaciones siempre deben realizarse mediante una operación POST, no una operación GET. Si el sitio está configurado para que se pueda realizar una operación de eliminación mediante una operación GET, cualquier usuario puede pasar una dirección URL como http://<server>/DeleteProduct/4 y eliminar todo lo que desee de la base de datos. Al agregar la confirmación y codificar la página para que la eliminación solo se pueda realizar mediante post, agregue una medida de seguridad al sitio.

    La operación de eliminación real se realiza con el código siguiente, que confirma primero que se trata de una operación posterior y que el identificador no está vacío:

    if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
    }
    

    El código ejecuta una instrucción SQL que elimina el registro especificado y, a continuación, redirige al usuario de nuevo a la página de lista.

  5. Ejecute ListProductsForDelete.cshtml en un explorador.

    [Captura de pantalla que muestra productos de la lista en ejecución para eliminar CSHTML en el navegador.]

  6. Haga clic en el vínculo Eliminar para uno de los productos. Se muestra la página DeleteProduct.cshtml para confirmar que desea eliminar ese registro.

  7. Haga clic en el botón Eliminar . El registro del producto se elimina y la página se actualiza con una lista de productos actualizada.

Sugerencia

Conexión a una base de datos

Puede conectarse a una base de datos de dos maneras. La primera consiste en usar el Database.Open método y especificar el nombre del archivo de base de datos (menos la extensión .sdf ):

var db = Database.Open("SmallBakery");

El Open método supone que .el archivo sdf se encuentra en la carpeta App_Data del sitio web. Esta carpeta está diseñada específicamente para contener datos. Por ejemplo, tiene los permisos adecuados para permitir que el sitio web lea y escriba datos, y como medida de seguridad, WebMatrix no permite el acceso a archivos desde esta carpeta.

La segunda forma es usar una cadena de conexión. Una cadena de conexión contiene información sobre cómo conectarse a una base de datos. Esto puede incluir una ruta de acceso de archivo o puede incluir el nombre de una base de datos de SQL Server en un servidor local o remoto, junto con un nombre de usuario y una contraseña para conectarse a ese servidor. (Si mantiene los datos en una versión administrada centralmente de SQL Server, como en el sitio de un proveedor de hospedaje, siempre usará una cadena de conexión para especificar la información de conexión de la base de datos).

En WebMatrix, las cadenas de conexión normalmente se almacenan en un archivo XML denominado Web.config. Como indica el nombre, puede usar un archivo Web.config en la raíz de su sitio web para almacenar la información de configuración del sitio, incluidas las cadenas de conexión que su sitio podría necesitar. Un ejemplo de una cadena de conexión en un archivo Web.config podría tener un aspecto similar al siguiente. Nota $CREDENTIAL_PLACEHOLDER$ es un marcador de posición para el par clave-valor de contraseña:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
   <add
     name="SQLServerConnectionString"
     connectionString= "server=myServer;database=myDatabase;uid=username;$CREDENTIAL_PLACEHOLDER$"
     providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

En el ejemplo, la cadena de conexión apunta a una base de datos en una instancia de SQL Server que se ejecuta en un servidor en algún lugar (en lugar de un archivo .sdf local). Tendría que sustituir los nombres adecuados para myServer y myDatabase, y especificar los valores de inicio de sesión de SQL Server para username y password. (Los valores de nombre de usuario y contraseña no son necesariamente los mismos que las credenciales de Windows o los valores que el proveedor de hospedaje le ha proporcionado para iniciar sesión en sus servidores. Compruebe con el administrador los valores exactos que necesita).

El Database.Open método es flexible, ya que permite pasar el nombre de un archivo .sdf de base de datos o el nombre de una cadena de conexión almacenada en el archivo Web.config . En el ejemplo siguiente se muestra cómo conectarse a la base de datos mediante la cadena de conexión que se muestra en el ejemplo anterior:

@{
    var db = Database.Open("SQLServerConnectionString");
}

Como se indicó, el Database.Open método le permite pasar un nombre de base de datos o una cadena de conexión y averiguará qué usar. Esto es muy útil al implementar (publicar) su sitio web. Puede usar un archivo .sdf en la carpeta App_Data al desarrollar y probar el sitio. Después, al mover el sitio a un servidor de producción, puede usar una cadena de conexión en el archivo Web.config que tenga el mismo nombre que el archivo .sdf , pero que apunte a la base de datos del proveedor de hospedaje, todo ello sin tener que cambiar el código.

Por último, si desea trabajar directamente con una cadena de conexión, puede llamar al método Database.OpenConnectionString y pasarle la cadena de conexión en sí misma, en lugar de solo el nombre de una en el archivo Web.config. Esto puede ser útil en situaciones en las que, por algún motivo, no tiene acceso a la cadena de conexión (o valores en ella, como el nombre del archivo .sdf ) hasta que se ejecute la página. Sin embargo, para la mayoría de los escenarios, puede usar Database.Open como se describe en este artículo.

Recursos adicionales