【问题标题】:dot net core custom model binding for generic type parameters in mvc action methodsdot net core 自定义模型绑定,用于 mvc 操作方法中的泛型类型参数
【发布时间】:2017-12-27 14:32:44
【问题描述】:

我正在构建一个简单的搜索、排序、页面功能。我附上了下面的代码。 以下是用例:

  1. 我的目标是通过每个请求传递“当前过滤器”以保持它们,特别是在排序和分页时。

  2. 与其用许多(如果不是太多)参数污染我的操作方法,我正在考虑使用一个包含当前过滤器的泛型类型参数。

  3. 我需要一个能够实现此目的的自定义模型绑定器。

有人可以发布一个示例实现吗?

PS:我也在探索替代方案,而不是来回传递复杂的对象。但是我需要将这条路线作为最后的手段,而且我找不到自定义模型绑定泛型类型参数的好例子。任何指向此类示例的指针也可以提供帮助。谢谢!

public async Task<IActionResult> Index(SearchSortPage<ProductSearchParamsVm> currentFilters, string sortField, int? page)
{
    var currentSort = currentFilters.Sort;
    // pass the current sort and sortField to determine the new sort & direction
    currentFilters.Sort = SortUtility.DetermineSortAndDirection(sortField, currentSort);
    currentFilters.Page = page ?? 1;

    ViewData["CurrentFilters"] = currentFilters;

    var bm = await ProductsProcessor.GetPaginatedAsync(currentFilters);

    var vm = AutoMapper.Map<PaginatedResult<ProductBm>, PaginatedResult<ProductVm>>(bm);

    return View(vm);
}

public class SearchSortPage<T> where T : class
{
    public T Search { get; set; }
    public Sort Sort { get; set; }
    public Nullable<int> Page { get; set; }
}

public class Sort
{
    public string Field { get; set; }
    public string Direction { get; set; }
}

public class ProductSearchParamsVm
{
    public string ProductTitle { get; set; }
    public string ProductCategory { get; set; }
    public Nullable<DateTime> DateSent { get; set; }
}

【问题讨论】:

    标签: asp.net-mvc asp.net-core custom-model-binder actionmethod generic-type-argument


    【解决方案1】:

    首先创建应该实现接口 IModelBinder 的模型绑定器

    SearchSortPageModelBinder.cs

    public class SearchSortPageModelBinder<T> : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }   
    
            SearchSortPage<T> ssp = new SearchSortPage<T>();
    
            //TODO: Setup the SearchSortPage<T> model 
    
            bindingContext.Result = ModelBindingResult.Success(ssp);
    
            return TaskCache.CompletedTask;
        }
    }
    

    然后创建应该实现接口 IModelBinderProvider 的 Model Binder Provider

    SearchSortPageModelBinderProvider.cs

    public class SearchSortPageModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
    
            if (context.Metadata.ModelType.GetTypeInfo().IsGenericType && 
                context.Metadata.ModelType.GetGenericTypeDefinition() == typeof(SearchSortPage<>))
            {
                Type[] types = context.Metadata.ModelType.GetGenericArguments();
                Type o = typeof(SearchSortPageModelBinder<>).MakeGenericType(types);
    
                return (IModelBinder)Activator.CreateInstance(o);
            }
    
            return null;
        }
    }
    

    最后一件事是注册 Model Binder Provider,它应该在你的 Startup.cs 中完成

    public void ConfigureServices(IServiceCollection services)
    {
            .
            .
    
            services.AddMvc(options=>
            {
                options.ModelBinderProviders.Insert(0, new SearchSortPageModelBinderProvider());
            });
            .
            .
    }
    

    【讨论】:

      猜你喜欢
      • 2019-12-07
      • 2021-09-17
      • 2010-12-02
      • 1970-01-01
      • 2018-08-22
      • 2015-11-10
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多