# 7.1.6 Creando el Controller para clientes

Agregamos un nuevo controlador de Api en blanco y lo llamamos **ClientesController** este hereda de la clase **ODataController** que esta en el espacio de nombres **Microsoft.AspNetCore.OData.Routing.Controllers**.

Agregamos nuestro constructor para recibir el contexto y nuestro objeto para traducir los mensajes de error.

Agregamos nuestros servicios get y agregamos la opción **\[EnableQuery]** la cual nos permitirá acceder a los datos de los clientes de acuerdo a las reglas de OData.

Para que filtren adecuadamente los servicios por Id el parámetro debe llamarse **key**.

{% code title="ClientesController.cs" %}

```csharp
using CaducaRest.Core;
using CaducaRest.DAO;
using CaducaRest.Models;
using CaducaRest.Resources;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Formatter;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CaducaRest.Controllers; 

public class ClientesController : ODataController
{
    private readonly LocService _localizer;
    private readonly CaducaContext _context;

    public ClientesController(CaducaContext context, 
                              LocService localizer)
    {
        _context = context;
        _localizer = localizer;  
    }

    [EnableQuery]
    public IActionResult Get()
    {
        var clientes = _context.Cliente;
        return Ok(clientes);
    }

    [EnableQuery]
    public IActionResult Get([FromODataUri]int key)
    {
        return Ok(_context.Cliente.Find(key));
    }
}
```

{% endcode %}

Podemos agregar directamente en nuestra base de datos algunos registros de cliente para poder realizar el filtrado con OData.

### Selecionar solamente unos campos

Probamos con postman seleccionar solamente la clave y nombre del cliente con el parámetro **$select** seguido de los campos separados por coma que deseas. Para ordenar por algún campo puedes usar el parámetro **$orderby** seguido del campo y desc si quieres ordenar en forma descendente.

```http
http://localhost:5000/odata/Clientes?$select=Clave,NombreComercial,RazonSocial&$orderBy=RazonSocial desc
```

![](https://3731331968-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LKmGSg4qhizjqeDPHJC%2F-MBfpnj1Si58WenFKOZr%2F-MBg0joxibjld7K97phE%2Fimage.png?alt=media\&token=40927d82-0370-4189-b57e-9cb51d096e39)

### Filtrar los clientes

Puedes filtrar por cualquier campo de la tabla con **$filte**r luego el nombre del campo por el cual deseas filtrar por ejemplo **eq** para igual y por último entre **'** el nombre que deseas buscar. En este ejemplo deseo buscar los clientes cuya dirección es igual a Conocido.

```http
http://localhost:50685/odata/Clientes?$filter=Direccion 
    eq 'Conocido'&$orderBy=Clave desc
```

![](https://3731331968-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LKmGSg4qhizjqeDPHJC%2F-MBfpnj1Si58WenFKOZr%2F-MBfzhXd_SHUOZdl7-KL%2Fimage.png?alt=media\&token=6d33607c-e03a-4bda-8b8e-fe53f67a8546)

La lista de opciones disponibles es:

| Condición | Descripción       | Ejemplo                                        |
| --------- | ----------------- | ---------------------------------------------- |
| eq        | Igual a           | $filter=Direccion eq 'Conocido'                |
| ne        | Diferente         | $filter=Clave ne 1                             |
| gt        | Mayor a           | $filter=Id gt 4                                |
| ge        | Mayor o igual a   | $filter=Clave ge 5                             |
| lt        | Menor que         | $filter=Id lt 10                               |
| le        | Menor o igual que | $filter=Clave le 5                             |
| and       | Y lógico          | $filter=Clave ge 5 and Activo eq true          |
| or        | O lógico          | $filter=Clave gt 5 or Activo eq true           |
| not       | No                | $filter=not startswith(RazonSocial,'Farmacia') |

Para buscar un cliente agregando entre paréntesis el id y puedes agregar los parámetros para seleccionar solo algunos campos.

```csharp
http://localhost:5000/odata/Clientes(5)?$select=Clave,NombreComercial
```

![](https://3731331968-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LKmGSg4qhizjqeDPHJC%2F-MBfpnj1Si58WenFKOZr%2F-MBg-wmsCZs2TxMudbxs%2Fimage.png?alt=media\&token=aec55efd-9202-4e2b-ae25-9d77c0023b3b)

Los servicios para agregar, modificar y borrar se realizan de la misma manera. El código final queda de la siguiente manera:

{% code title="ClientesController.cs" %}

```csharp
public class ClientesController : ODataController
{
    private readonly LocService _localizer;
    private readonly CaducaContext _context;
    private ClienteDAO clienteDAO;

    public ClientesController(CaducaContext context, 
                              LocService localizer)
    {
        _context = context;
        _localizer = localizer;
        clienteDAO = new ClienteDAO(_context, _localizer);
    }

    [EnableQuery]
    public IActionResult Get()
    {
        var clientes = _context.Cliente;
        return Ok(clientes);
    }

    [EnableQuery]
    public ActionResult<IQueryable<ClienteCategoria>> GetCliente([FromODataUri] int key)
    {
        return Ok(_context.Cliente.Where(c => c.Id == key));
    }
    
    [HttpPost]
    public async Task<IActionResult> Post([FromBody] Cliente cliente)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        List<IRegla> reglas = new List<Core.IRegla>();
            
        await clienteDAO.AgregarAsync(cliente);
        return Ok(cliente);
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete([FromRoute] int id)
    {
        if (!await clienteDAO.BorraAsync(id))
        {
            return StatusCode(clienteDAO.customError.StatusCode,
                                  clienteDAO.customError.Message);
        }
        return Ok();
    }
```

{% endcode %}
