Possible incorrect way of getting property value from expression #1035

Open
opened 2026-01-29 17:48:08 +00:00 by claunia · 0 comments
Owner

Originally created by @ns6000 on GitHub (Nov 15, 2023).

Describe the bug
I believe there is a bug in method PropertyAccess.GetValue(object value, string path) if you are working with interfaces.

public static object GetValue(object value, string path)
{
    Type currentType = value.GetType();

    foreach (string propertyName in path.Split('.'))
    {
        var property = currentType.GetProperty(propertyName);
        if (property != null)
        {
            if (value != null)
            {
                value = property.GetValue(value, null);
            }

            currentType = property.PropertyType;
        }
    }
    return value;
}

Error seems to be at the line with currentType = property.PropertyType;, i believe it should be currentType = value.GetType();.

To Reproduce
Consider following example:

public interface ISubInterface
{
}

public class SubModel : ISubInterface
{
    public bool SubModelProperty { get; set; }
}

public class Model
{
    public int ModelProperty { get; set; }
    public ISubInterface SubModelInstance { get; set; }
}

var data = new List<Model>() {
    new Model() {
        ModelProperty = 10,
        SubModelInstance = new SubModel() {
            SubModelProperty = true
        }
    }
};
IEnumerable<int> values;

<RadzenCheckBoxList
    Data="@data"
    @bind-Value="@values"
    TValue="int"
    TextProperty="ModelProperty"
    ValueProperty="ModelProperty"
    DisabledProperty="SubModelInstance.SubModelProperty"
/>

Usage like this will throw:

Unhandled exception rendering component:  Specified cast is not valid. 
 System.InvalidCastException: Specified cast is not valid.
   at Radzen.PropertyAccess.TryGetItemOrValueFromProperty[Boolean](Object item, String property, Boolean& result)
   at Radzen.Blazor.RadzenCheckBoxList`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<get_allItems>b__19_0(Object i)
   at System.Linq.Enumerable.SelectEnumerableIterator`2[[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Linq.Enumerable.ConcatIterator`1[[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1[[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at Radzen.Blazor.RadzenCheckBoxList`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].BuildRenderTree(RenderTreeBuilder __builder)
   at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

I believe it's because when the method GetValue tries to get value from SubModelInstance the row currentType = property.PropertyType; will set the currentType to ISubInterface and not SubModel. Interface itself does not define the property and hence the crash. I may be wrong though, i didn't debug your code, it's just what i'm reading from the sources.

Originally created by @ns6000 on GitHub (Nov 15, 2023). **Describe the bug** I believe there is a bug in method `PropertyAccess.GetValue(object value, string path)` if you are working with interfaces. ``` public static object GetValue(object value, string path) { Type currentType = value.GetType(); foreach (string propertyName in path.Split('.')) { var property = currentType.GetProperty(propertyName); if (property != null) { if (value != null) { value = property.GetValue(value, null); } currentType = property.PropertyType; } } return value; } ``` Error seems to be at the line with `currentType = property.PropertyType;`, i believe it should be `currentType = value.GetType();`. **To Reproduce** Consider following example: ``` public interface ISubInterface { } public class SubModel : ISubInterface { public bool SubModelProperty { get; set; } } public class Model { public int ModelProperty { get; set; } public ISubInterface SubModelInstance { get; set; } } var data = new List<Model>() { new Model() { ModelProperty = 10, SubModelInstance = new SubModel() { SubModelProperty = true } } }; IEnumerable<int> values; <RadzenCheckBoxList Data="@data" @bind-Value="@values" TValue="int" TextProperty="ModelProperty" ValueProperty="ModelProperty" DisabledProperty="SubModelInstance.SubModelProperty" /> ``` Usage like this will throw: ``` Unhandled exception rendering component: Specified cast is not valid. System.InvalidCastException: Specified cast is not valid. at Radzen.PropertyAccess.TryGetItemOrValueFromProperty[Boolean](Object item, String property, Boolean& result) at Radzen.Blazor.RadzenCheckBoxList`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<get_allItems>b__19_0(Object i) at System.Linq.Enumerable.SelectEnumerableIterator`2[[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext() at System.Linq.Enumerable.ConcatIterator`1[[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator`1[[Radzen.Blazor.RadzenCheckBoxListItem`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Radzen.Blazor, Version=4.15.8.0, Culture=neutral, PublicKeyToken=null]].MoveNext() at Radzen.Blazor.RadzenCheckBoxList`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].BuildRenderTree(RenderTreeBuilder __builder) at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder) at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException) ``` I believe it's because when the method `GetValue` tries to get value from `SubModelInstance` the row `currentType = property.PropertyType;` will set the currentType to `ISubInterface` and not `SubModel`. Interface itself does not define the property and hence the crash. I may be wrong though, i didn't debug your code, it's just what i'm reading from the sources.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#1035