ひでぼ~blog

C#ときどきゲーム

ASP.NET Core 7のIParsableを試す

ASP.NET Core 7から使えるようになったIParsableを使ってモデルバインドをしてみます。

やること

コントローラのアクションで、"2022/12/31,2023/01/01"のような文字列をDateRangeという日付の区間を表すクラスにバインドして受け取れるようにしてみます。

// string => DateRangeにバインドする
[HttpGet("DateRange")]
public IActionResult GetDateRange([FromQuery] DateRange dateRange)
{
    var from = dateRange.From;
    var to = dateRange.To;

    return Ok();
}

モデルの準備

次のようなIParsable<T>を実装したDateRangeというクラスを作ります。IParsable<T>はParseとTryParseの実装が必要になり、リクエストパラメータの文字列をアクションの引数にバインドする際にこのParseが呼ばれるようになります。 Parseの中で呼ばれるTryParseでは、"2022/12/31,2023/01/01"のようなカンマ区切りの文字列を分割して、それぞれ文字列からDateOnlyにParseしてToとFromに代入するするものになっています。

public class DateRange : IParsable<DateRange>
{
    public DateOnly? From { get; init; }
    public DateOnly? To { get; init; }

    public static DateRange Parse(string value, IFormatProvider? provider)
    {
        if (!TryParse(value, provider, out var result))
        {
            throw new ArgumentException("Could not parse supplied value.", nameof(value));
        }

        return result;
    }

    public static bool TryParse(string? value, IFormatProvider? provider, out DateRange dateRange)
    {
        var segments = value?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

        if (segments?.Length == 2
            && DateOnly.TryParse(segments[0], provider, out var fromDate)
            && DateOnly.TryParse(segments[1], provider, out var toDate))
        {
            dateRange = new DateRange { From = fromDate, To = toDate };
            return true;
        }

        dateRange = new DateRange { From = default, To = default };
        return false;
    }
}

デバッグ実行してみる

エンドポイントのURL(https://localhost:7014/sample/daterange?daterange=2022/12/31,2023/01/01)を叩いてみるとばっちりバインドされていました。

参考

learn.microsoft.com