MVC操作方法中通用类型参数的点网核心自定义模型绑定 [英] dot net core custom model binding for generic type parameters in mvc action methods

查看:84
本文介绍了MVC操作方法中通用类型参数的点网核心自定义模型绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am building a simple search, sort, page feature. I have attached the code below. Below are the usecases:


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

  1. My goal is to pass the "current filters" via each request to persist them particularly while sorting and paging.

我正在考虑使用保存当前过滤器的通用类型参数,而不是使用许多(如果不是太多)参数来污染我的操作方法。

Instead of polluting my action method with many (if not too many) parameters, I am thinking to use a generic type parameter that holds the current filters.

我需要一个能够实现此目的的自定义模型绑定程序。

I need a custom model binder that can be able to achieve this.

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

Could someone please post an example implementation?

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

PS: I am also exploring alternatives as opposed to passing back and forth the complex objects. But i would need to take this route as a last resort and i could not find a good example of custom model binding generic type parameters. Any pointers to such examples can also help. Thanks!.

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; }
}


推荐答案

首先创建Model Binder应该实现接口IModelBinder

First create the Model Binder which should be implementing the interface IModelBinder

SearchSortPageModelBinder.cs

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;
    }
}

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

And then create the Model Binder Provider which should be implementing the interface IModelBinderProvider

SearchSortPageModelBinderProvider.cs

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

And the last thing is register the Model Binder Provider, it should be done in your Startup.cs

public void ConfigureServices(IServiceCollection services)
{
        .
        .

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

这篇关于MVC操作方法中通用类型参数的点网核心自定义模型绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆