[英]Model Binder for a custom property type
On an ASP.NET Core project I have the following action: 在ASP.NET Core项目上,我有以下操作:
public async Task<IActionResult> Get(ProductModel model) {
}
public class ProductModel {
public Filter<Double> Price { get; set; }
}
I have a Filter base class and a RangeFilter as follows: 我有一个Filter基类和一个RangeFilter,如下所示:
public class Filter<T> { }
public class RangeFilter<T> : Filter<T> {
public abstract Boolean TryParse(String value, out Filter<T> filter);
}
I am passing a String ( "[3.34;18.75]"
) to the Action as Price. 我正在将String( "[3.34;18.75]"
)作为价格传递给Action。
I need to create a ModelBinder
where I use the TryParse
method to try to convert that String
into a RangeFilter<Double>
to define the ProductModel.Price
property. 我需要创建一个ModelBinder
,在其中使用TryParse
方法尝试将该String
转换为RangeFilter<Double>
以定义ProductModel.Price
属性。
If TryParse
fails, eg, returns false
then the ProductModel.Price
property becomes null. 如果TryParse
失败,例如返回false
则ProductModel.Price
属性将为null。
How can this be done? 如何才能做到这一点?
If you're willing to move the parsing method into a static class, this would become a bit more feasible. 如果您愿意将解析方法移到静态类中,这将变得更加可行。
public static class RangeFilterParse
{
public static Filter<T> Parse<T>(string value)
{
// parse the stuff!
return new RangeFilter<T>();
}
}
public abstract class Filter<T> { }
public class RangeFilter<T> : Filter<T> { }
public class ProductModel
{
[ModelBinder(BinderType = typeof(RangeModelBinder))]
public Filter<double> Price { get; set; }
}
public class RangeModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
try
{
var input = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString();
var inputType = bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0];
// invoke generic method with proper type
var method = typeof(RangeFilterParse).GetMethod(nameof(RangeFilterParse.Parse), BindingFlags.Static);
var generic = method.MakeGenericMethod(inputType);
var result = generic.Invoke(this, new object[] { input });
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
catch(Exception) // or catch a more specific error related to parsing
{
bindingContext.Result = ModelBindingResult.Success(null);
return Task.CompletedTask;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.