I wrote an endpoint which accepts MediaParams object which extends another param class and together they act like a wrapper for parameters and look like this:
public class MediaParams : PaginationParams
{
public string OrderBy { get; set; } = "title";
public string SearchTerm { get; set; } = string.Empty;
public string Genres { get; set; } = string.Empty;
}
public class PaginationParams
{
private const int MaxPageSize = 50;
public int PageNumber { get; set; } = 1;
private int _pageSize = 6;
public int PageSize
{
get => _pageSize;
set => _pageSize = value > MaxPageSize ? MaxPageSize : value;
}
}
As you may notice I also assigned a default values for each property as I want to make them optional, my endpoint
app.MapGet("/media/getby", async (
[AsParameters] MediaParams pa,
IMediator mediator,
HttpContext context) =>
{
var mediaListDto = await mediator.Send(new GetMediaByParamsQuery(pa));
if (mediaListDto is not { Count: > 0 })
{
return Results.NotFound("No media was found by these params.");
}
context.Response.Headers.Add("Pagination", JsonSerializer.Serialize(mediaListDto.MetaData));
return Results.Ok(mediaListDto);
});
Now it works ok, but only if I specify every single property in my uri like this:
serveraddress/media/getby?OrderBy=rating&SearchTerm=pal&Genres=Drama&PageNumber=1&PageSize=10
Could someone help me to rewrite the logic so I could use these params individually to override default values, or not use at all to keep default values? Thanks.
2
Answers
I've created a class that reads the request and "assembles" a parameters object or keeps default values, I also removed default values from Parameter classes like MediaParams and PaginationParams, and also removed the nullability from properties of these classes
In endpoint I am calling this class like this
It seems that
AsParameter
by default requires all properties and when it deserialises it skips the default values because it usesFormatterServices.GetUninitializedObject
that instantiates an object but without invocation of its constructor and field initializers (because of performance purposes as this class & method should be used for serialisation/deserialisation).When I changed your models to the following code, it started doing its job:
Sadly, when
DefaultValue
has a value of"" (string.Empty)
passed, it converts it tonull
. If you play around with setters and logic there to prevent assigning nulls, this should do the work for you.