Error on conversion: System.InvalidCastException: Object must implement IConvertible

Aakash Bashyal 1 Reputation point
2022-07-11T04:59:10.257+00:00

I am trying to to create a custom model binder, that can parse the incoming request properly. The incoming request are in the form.

https://localhost:5001/api/hotel?filter=name~contains~'hotel'&page=1&pageSize=5  

In controller I have used the model binder as:

[HttpGet]  
public async Task<DataSourceResult> GetHotel([ModelBinder(BinderType = typeof(GridDataSourceRequestModelBinder))] DataSourceRequest request)  
{  
GridDataSourceRequestModelBinder looks like:  
  
public async Task BindModelAsync(ModelBindingContext bindingContext)  
{  
    if (bindingContext.ModelType != typeof(DataSourceRequest))  
    {  
        return;  
    }  
    var request = CreateDataSourceRequest(bindingContext.ModelMetadata, bindingContext.ValueProvider, bindingContext.ModelName);  
  
    bindingContext.Result = ModelBindingResult.Success(request);  
}  

DataSourceRequest request

public class DataSourceRequest  
{  
    public DataSourceRequest();  
  
    public int Page { get; set; }  
    public int PageSize { get; set; }  
    public IList<SortDescriptor> Sorts { get; set; }  
    public IList<IFilterDescriptor> Filters { get; set; }  
    public IList<GroupDescriptor> Groups { get; set; }  
    public IList<AggregateDescriptor> Aggregates { get; set; }  
}  

CreateDataSourceRequest method:

public static DataSourceRequest CreateDataSourceRequest(ModelMetadata modelMetadata, IValueProvider valueProvider, string modelName)  
{  
    var request = new DataSourceRequest();  
  
    TryGetValue(modelMetadata, valueProvider, modelName, DataSourceRequestUrlParameters.Page, (int currentPage) => request.Page = currentPage);  
  
    TryGetValue(modelMetadata, valueProvider, modelName, DataSourceRequestUrlParameters.PageSize, (int pageSize) => request.PageSize = pageSize);  
  
    TryGetValue(modelMetadata, valueProvider, modelName, DataSourceRequestUrlParameters.Filter, (string filter) =>  
        request.Filters = FilterDescriptorFactory.Create(filter)  
    );  
  
    return request;  
}  

In the TryGetValue method I have the following code.

private static void TryGetValue<T>(ModelMetadata modelMetadata, IValueProvider valueProvider, string modelName, string key, Action<T> action)  
{  
    if (modelMetadata.BinderModelName.HasValue())  
    {  
        key = modelName + "-" + key;  
    }  
  
    var value = valueProvider.GetValue(key);  
    if (value.FirstValue != null)  
    {  
        //Type typeParameterType = typeof(T);  
  
        var convertedValue = TypeDescriptor.GetConverter(typeof(T)).ConvertTo(value, typeof(T));  
  
        if (convertedValue != null)  
        {  
            action((T)convertedValue);  
        }  
    }  
}  

Here while converting the typeof(T) in the following code,

var convertedValue = TypeDescriptor.GetConverter(typeof(T)).ConvertTo(value, typeof(T));  

I am getting the error as:

System.InvalidCastException: Object must implement IConvertible.

What am I missing on the conversion of the value to type (T)?

Additional Class:

public static class DataSourceRequestUrlParameters  
{  
    public static string Aggregates { get; set; }  
    public static string Filter { get; set; }  
    public static string Page { get; set; }  
    public static string PageSize { get; set; }  
    public static string Sort { get; set; }  
    public static string Group { get; set; }  
    public static string Mode { get; set; }  
  
    public static IDictionary<string, string> ToDictionary(string prefix);  
}  
Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Farid Uddin Kiron MSFT 456 Reputation points Microsoft External Staff
    2022-07-11T07:09:23.623+00:00

    Are you serializing your json accordingly? Hows your json serialization looks like? Could you please have a look official document here


  2. Bruce (SqlWork.com) 78,086 Reputation points Volunteer Moderator
    2022-07-11T15:58:49.843+00:00

    value is a ValueProviderResult and does not implement IConvertable. try:

        var convertedValue = TypeDescriptor.GetConverter(typeof(T)).ConvertTo(value.FirstValue, typeof(T));
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.