asp.net-web-api
OData con la API web de Asp.net
Buscar..
Instalar los paquetes OData
En el menú Herramientas, seleccione NuGet Package Manager> Package Manager Console. En la ventana de la consola del Administrador de paquetes, escriba:
Install-Package Microsoft.AspNet.Odata
Este comando instala los últimos paquetes OData NuGet.
Habilitar Entity Framework
Para este tutorial, usaremos Entity Framework (EF) Code First para crear la base de datos de back-end.
Web API OData no requiere EF. Utilice cualquier capa de acceso a datos que pueda convertir las entidades de la base de datos en modelos.
Primero, instale el paquete NuGet para EF. En el menú Herramientas , seleccione NuGet Package Manager > Package Manager Console . En la ventana de la consola del Administrador de paquetes, escriba:
Install-Package EntityFramework
Abra el archivo Web.config y agregue la siguiente sección dentro del elemento de configuración , después del elemento configSections .
<configuration>
<configSections>
<!-- ... -->
</configSections>
<!-- Add this: -->
<connectionStrings>
<add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0;
Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
AttachDbFilename=|DataDirectory|ProductsContext.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>
Esta configuración agrega una cadena de conexión para una base de datos LocalDB. Esta base de datos se utilizará cuando ejecute la aplicación localmente.
A continuación, agregue una clase llamada ProductsContext a la carpeta Modelos:
using System.Data.Entity;
namespace ProductService.Models
{
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
}
}
En el constructor, "name = ProductsContext" proporciona el nombre de la cadena de conexión.
Configurar el punto final OData
Abra el archivo App_Start / WebApiConfig.cs. Agregue las siguientes declaraciones de uso :
using ProductService.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
Luego agregue el siguiente código al método de registro :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
}
}
Este código hace dos cosas:
- Crea un modelo de datos de entidad (EDM).
- Agrega una ruta.
Un EDM es un modelo abstracto de los datos. El EDM se utiliza para crear el documento de metadatos del servicio. La clase ODataConventionModelBuilder crea un EDM utilizando las convenciones de nomenclatura predeterminadas. Este enfoque requiere el menor código. Si desea tener más control sobre el EDM, puede usar la clase ODataModelBuilder para crear el EDM agregando propiedades, claves y propiedades de navegación explícitamente.
Una ruta le dice a la API web cómo enrutar las solicitudes HTTP al punto final. Para crear una ruta OData v4, llame al método de extensión MapODataServiceRoute .
Si su aplicación tiene múltiples puntos finales OData, cree una ruta separada para cada uno. Dé a cada ruta un nombre y prefijo de ruta únicos.
Agregue el controlador OData
Un controlador es una clase que maneja solicitudes HTTP. Crea un controlador separado para cada entidad establecida en su servicio OData. En este tutorial, creará un controlador, para la entidad Producto.
En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Controladores y seleccione Agregar > Clase . Nombre la clase ProductsController.
La versión de este tutorial para OData v3 usa el andamio Agregar controlador. Actualmente, no hay andamios para OData v4.
Reemplace el código de boilerplate en ProductsController.cs con lo siguiente.
using ProductService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.OData;
namespace ProductService.Controllers
{
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
private bool ProductExists(int key)
{
return db.Products.Any(p => p.Id == key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
El controlador utiliza la clase ProductsContext para acceder a la base de datos utilizando EF. Tenga en cuenta que el controlador anula el método Dispose para eliminar el ProductsContext .
Este es el punto de partida para el controlador. A continuación, agregaremos métodos para todas las operaciones de CRUD.
Ejecución de CRUD en el conjunto de entidades
Consultar el conjunto de entidades
Agregue los siguientes métodos a ProductsController .
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
IQueryable<Product> result = db.Products.Where(p => p.Id == key);
return SingleResult.Create(result);
}
La versión sin parámetros del método Get devuelve la colección de Productos completa. El método Get con un parámetro clave busca un producto por su clave (en este caso, la propiedad Id).
El atributo [EnableQuery] permite a los clientes modificar la consulta mediante el uso de opciones de consulta como $ filter, $ sort y $ page. Para obtener más información, consulte Compatibilidad con las opciones de consulta de OData .
Agregar una entidad al conjunto de entidades
Para permitir que los clientes agreguen un nuevo producto a la base de datos, agregue el siguiente método a ProductsController .
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
Actualización de una entidad
OData admite dos semánticas diferentes para actualizar una entidad, PATCH y PUT.
- PATCH realiza una actualización parcial. El cliente especifica solo las propiedades para actualizar.
- PUT reemplaza a toda la entidad.
La desventaja de PUT es que el cliente debe enviar valores para todas las propiedades en la entidad, incluidos los valores que no están cambiando. La especificación OData establece que se prefiere PATCH.
En cualquier caso, aquí está el código para los métodos PATCH y PUT:
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entity = await db.Products.FindAsync(key);
if (entity == null)
{
return NotFound();
}
product.Patch(entity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != update.Id)
{
return BadRequest();
}
db.Entry(update).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(update);
}
En el caso de PATCH, el controlador usa el tipo Delta <T> para rastrear los cambios.
Borrando una entidad
Para permitir que los clientes eliminen un producto de la base de datos, agregue el siguiente método a ProductsController .
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
var product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
db.Products.Remove(product);
await db.SaveChangesAsync();
return StatusCode(HttpStatusCode.NoContent);
}