# 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
```

![](/files/-MBg0joxibjld7K97phE)

### 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
```

![](/files/-MBfzhXd_SHUOZdl7-KL)

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
```

![](/files/-MBg-wmsCZs2TxMudbxs)

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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abi.gitbook.io/net-core/6.2-configurar-tus-servicios-con-odata/6.2.7-creando-el-controller-para-clientes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
