1

Je construis une simple recherche, trier, fonction de la page. J'ai joint le code ci-dessous. Voici les usecases:dot net core modèle personnalisé de liaison pour les paramètres de type générique dans les méthodes d'action mvc

  1. Mon objectif est de passer les « filtres actuels » par chaque demande de les persister en particulier pendant le tri et la pagination. Au lieu de polluer ma méthode d'action avec beaucoup de paramètres (si pas trop), je pense à utiliser un paramètre de type générique qui contient les filtres actuels.

  2. J'ai besoin d'un modèle de reliure personnalisé qui peut être capable d'y parvenir.

Quelqu'un pourrait-il publier un exemple de mise en œuvre? PS: J'explore aussi des alternatives plutôt que de passer d'un objet complexe à l'autre. Mais je devrais prendre cette route en dernier recours et je ne pourrais pas trouver un bon exemple de paramètre de type générique de liaison de modèle personnalisé. Tous les pointeurs vers de tels exemples peuvent également aider. Merci!.

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

Répondre

2

d'abord créer le classeur modèle qui devrait être implémentant l'interface 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; 
    } 
} 

Et puis créer le fournisseur Binder modèle qui devrait être implémentant l'interface IModelBinderProvider

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

Et la dernière chose est enregistrer le fournisseur Binder modèle, il doit être fait dans votre Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
     . 
     . 

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

merci. Je vais vérifier cela. – blogs4t