Daily Knowledge Drop
In a previous post we had a look at the IParseable interface
which allows for a string to be parsed into a type
.
This functionality can be leveraged with minimal API's to automatically parse a query string to a complex type.
IParseable request
In this example, the Song entity implements the IParsable<Song> interface (more details in the previous post about IParseable):
public class Song : IParsable<Song>
{
public string Name { get; set; }
public string Artist { get; set; }
public int LengthInSeconds { get; set; }
private Song(string name, string artist, int lengthInSeconds)
{
Name = name;
Artist = artist;
LengthInSeconds = lengthInSeconds;
}
public static Song Parse(string s, IFormatProvider? provider)
{
string[] songPortions = s.Split(new[] { '|' });
if (songPortions.Length != 3)
{
throw new OverflowException("Expect format: Name|Artist|LengthInSeconds");
}
return new Song(songPortions[0], songPortions[1], Int32.Parse(songPortions[2]));
}
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out Song result)
{
result = null;
if (s == null)
{
return false;
}
try
{
result = Parse(s, provider);
return true;
}
catch { return false; }
}
}
This interface implementation allows for a string value (in a specific format), to be converted to a Song instance
:
Song song = "Everlong|Foo Fighters|326".Parse<Song>();
Minimal endpoint
Manual parsing
If we want an endpoint which accepts a Song as a parameter, one option is to have the request entity as a string
and perform the conversion to Song manually:
app.MapGet("/song", ([FromQuery]string song) =>
{
// perform the conversion from string
// to Song manually, using the IParsable
// interface
return details.Parse<Song>();
});
Calling the endpoint with a song query string /song?song=Everlong|Foo Fighters|326
, results in the following response:
{"name":"Everlong","artist":"Foo Fighters","lengthInSeconds":326}
This is a valid approach, but because the Song class implements IParseable, the conversion can be done automatically!
Automatic parsing
A slightly easier approach that manually doing the conversions, is allowing it to happen automatically. Changing the parameter type from string to Song:
// parameter is Song instead of string
app.MapGet("/song", ([FromQuery] Song song) =>
{
return song;
});
Calling the same endpoint with a song query string /song?song=Everlong|Foo Fighters|326
, results in the same response:
{"name":"Everlong","artist":"Foo Fighters","lengthInSeconds":326}
As Song implement IParsable, the string parameter is automatically parsed to a Song instance
.
Notes
This is a small quality of life feature which makes working with the IParsable interface and minimal endpoints easier and more streamline.
References
Daily Drop 233: 12-01-2023
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.