0

I have a small database that has been created by EF using a typical model class:

public class Metrics
{
    public int Id { get; set; }
    public string? MetricValue { get; set; }
    public string? MetricHost { get; set; }
    public string? MetricTime { get; set; }
}

The database is now populated with data and my Minimal API can return all the entries from:

app.MapGet("/metric", async (DataContext context) => await context.Metrics.ToListAsync());

And also, I can query by Id:

app.MapGet("/metric/{id}", async (DataContext context, int id) => 
    await context.Metrics.FindAsync(id) is Metric metric ? 
    Results.Ok(metric) :
    Results.NotFound("Metric not found"));

I've been searching the web for something that would show how to search by another property but have not found anything that works. e.g.,

app.MapGet("/hostnames/{MetricHost}"...

This article on CodeMaze is the closest I've found but none of the examples seem to work:

https://code-maze.com/aspnetcore-query-string-parameters-minimal-apis/

Any help is appreciated. Here's an example that did not work:

app.MapGet("/search", (SearchCriteria criteria) =>
{
    return $"Host: {criteria.MetricHost}, Id: {criteria.Id}";
});

With model changes:

public class Metric
{
    public int Id { get; set; }
    public string? MetricValue { get; set; }
    public string? MetricHost { get; set; }
    public string? MetricTime { get; set; }

    public static ValueTask<Metric?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        string hostname = context.Request.Query["MetricHost"];
        int.TryParse(context.Request.Query["Id"], out var id);

        var result = new Metric
        {
            MetricHost = hostname,
            Id = id
        };

        return ValueTask.FromResult<Metric?>(result);
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
TyMac
  • 783
  • 2
  • 9
  • 32

1 Answers1

0

You are binding wrong type, BindAsync should be part of SearchCriteria:

app.MapGet("/search", (SearchCriteria criteria, DataContext context) =>
{
    IQueryable<Metric> query = context.Metrics;
    if(criteria.MetricHost is not null)
    {
        query = query.Where(m => m.MetricHost == criteria.MetricHost)
    }
    // ... rest of filters
    return await query.ToListAsync();
});
public class SearchCriteria
{
    public string? MetricHost { get; set; }
    // ... rest of filters

    public static ValueTask<SearchCriteria?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        string hostname = context.Request.Query["MetricHost"];
        // ... rest of filters
        var result = new SearchCriteria
        {
            MetricHost = hostname,
        };
        return ValueTask.FromResult<SearchCriteria?>(result);
    }
}

Read more:

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • I'm looking to bring back a list of all the matches for the property MetricHost. This example only returns the values I search for. The Id should not be part of what I'm searching with. I would like to return all the properties for a given record. – TyMac Nov 29 '22 at 01:17
  • @TyMac then use approach from the answer to recieve needed filters to query the db context and return found items. – Guru Stron Nov 29 '22 at 01:26
  • Can you provide an example? I've been struggling with how to filter this. – TyMac Nov 29 '22 at 01:28
  • @TyMac See the updated code (not checked). There are a lot of examples including the docs for EF Core. Note that provided code uses "and" logic to combine filtering conditions. – Guru Stron Nov 29 '22 at 01:36
  • Nice! That looks to be close. Currently returning an empty array but certainly progress, thanks! – TyMac Nov 29 '22 at 01:43