Решение 1
Вызов TryParse
с использованием отражения
public class FilterModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
//same binder code
//get filter generic type
Type filterType = bindingContext.ModelType.GenericTypeArguments.Single();
if (!TryGetFilter(value, filterType, out object filter))
{
bindingContext.ModelState.TryAddModelError(modelName, "Value is not of type Filter");
return Task.CompletedTask;
}
bindingContext.Result = ModelBindingResult.Success(filter);
return Task.CompletedTask;
}
private bool TryGetFilter(string value, Type filterType, out object filter)
{
var parameters = new object[] { value, null };
bool result = (bool)typeof(Filter)
.GetMethod(nameof(Filter.TryParse))
.MakeGenericMethod(filterType)
.Invoke(null, parameters);
filter = parameters[1]; //out parameter is placed here
return result;
}
}
Решение 2
Ввод неуниверсальноговерсия TryParse
, принимающая тип фильтра
public static class Filter
{
public static bool TryParse<T>(string value, out Filter<T> filter)
{
bool result = TryParse(value, typeof(T), out object innerFilter);
filter = (Filter<T>)innerFilter;
return result;
}
public static bool TryParse(string value, Type type, out object filter)
{
//parse logic here
}
}
И назовите ее в связывателе модели
//same binder code
//get filter generic type
Type filterType = bindingContext.ModelType.GenericTypeArguments.Single();
if (!Filter.TryParse(value, filterType, out object filter))
{
bindingContext.ModelState.TryAddModelError(modelName, "Value is not of type Filter");
return Task.CompletedTask;
}
//same binder code