From 1565531a2bfcfdd6051706a3fb05d051470b75b2 Mon Sep 17 00:00:00 2001 From: Dmytro Nikitin Date: Wed, 5 Aug 2026 20:46:48 +0200 Subject: [PATCH] Fix #2400: AddObjectStatic throwing on null property values --- .../Request/PropertyCache.Populator.cs | 10 ++- .../ObjectParameterTests.NullData.cs | 61 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 test/RestSharp.Tests/Parameters/ObjectParameterTests.NullData.cs diff --git a/src/RestSharp/Request/PropertyCache.Populator.cs b/src/RestSharp/Request/PropertyCache.Populator.cs index 4057ac999..d60885320 100644 --- a/src/RestSharp/Request/PropertyCache.Populator.cs +++ b/src/RestSharp/Request/PropertyCache.Populator.cs @@ -74,7 +74,15 @@ internal static Populator From(PropertyInfo property) { var populate = GetPopulate(getObject, property); - return new(property.Name, populate); + // Skip null property values so a DTO with unset optional properties doesn't throw. + // This matches the reflection-based AddObject. + return new( + property.Name, + (model, parameters) => { + if (getObject(model) is null) return; + populate(model, parameters); + } + ); } static Action> GetPopulate(Func getFormattable, RequestProperty requestProperty) diff --git a/test/RestSharp.Tests/Parameters/ObjectParameterTests.NullData.cs b/test/RestSharp.Tests/Parameters/ObjectParameterTests.NullData.cs new file mode 100644 index 000000000..8cc0f4d61 --- /dev/null +++ b/test/RestSharp.Tests/Parameters/ObjectParameterTests.NullData.cs @@ -0,0 +1,61 @@ +namespace RestSharp.Tests.Parameters; + +public partial class ObjectParameterTests { + [Fact] + public void AddObjectStatic_skips_null_properties() { + var data = new NullableData { Kind = "set" }; + + var request = new RestRequest().AddObjectStatic(data); + + request + .Parameters + .Should() + .ContainSingle() + .Which + .Should() + .BeEquivalentTo(new GetOrPostParameter(nameof(NullableData.Kind), "set")); + } + + [Fact] + public void AddObjectStatic_keeps_non_null_properties_and_skips_null_ones() { + var data = new NullableData { Name = "Bob", Age = 30, Link = null, Values = null, Kind = "set" }; + + var request = new RestRequest().AddObjectStatic(data); + + request + .Parameters + .Should() + .BeEquivalentTo(new[] { + new GetOrPostParameter(nameof(NullableData.Name), "Bob"), + new GetOrPostParameter(nameof(NullableData.Age), "30"), + new GetOrPostParameter(nameof(NullableData.Kind), "set") + }); + } + + [Fact] + public void AddObjectStatic_with_all_null_properties_yields_no_parameters() { + var data = new NullableData { Kind = null }; + + var request = new RestRequest().AddObjectStatic(data); + + request.Parameters.Should().BeEmpty(); + } + + [Fact] + public void AddObjectStatic_null_property_handling_matches_AddObject() { + var data = new NullableData { Name = null, Age = null, Link = null, Values = null, Kind = "set" }; + + var objStatic = new RestRequest().AddObjectStatic(data); + var reflection = new RestRequest().AddObject(data); + + objStatic.Parameters.Should().BeEquivalentTo(reflection.Parameters); + } + + class NullableData { + public string Name { get; set; } + public int? Age { get; set; } + public Uri Link { get; set; } + public List Values { get; set; } + public string Kind { get; set; } = "set"; + } +}