2016-05-12 4 views
2

У меня возникла ситуация, когда я хотел бы выполнить привязку специальных параметров для контроллера api в ядре ASP.NET. В WebAPI 2.0 можно было выполнить пользовательскую привязку к примитивным типам, внедряя различные интерфейсы, такие как IValueProvider и предоставляющие ValueProviderFactory. Это не похоже на ядро ​​ASP.NET, насколько я понимаю из the documentation I found here.Связывание пользовательских параметров ASP.NET Core

Я заметил this SO post, который привел меня к this article, который переопределяет поведение для MutableObjectModelBinder. Казалось бы, я мог бы сделать что-то вдоль этих линий, таких как:

[HttpGet] 
    [Route("api/{domain}/[controller]")] 
    public IEnumerable<string> Get([ModelBinder(BinderType = typeof(MyCustomBinder))]string orderby) 
    { 
     //Do stuff here 
    } 

Это не обязательно, кажется мне правильным, так как я просто имеем дело с примитивным типом, однако я не могу найти какую-либо документацию на другой путь делая это. Любая помощь будет оценена по достоинству.

EDIT: В случае, если кто-то наткнулся на это, я решил пойти со вспомогательным классом, чтобы проанализировать параметр из-за того, что он должен соответствовать срокам. Как только я получу шанс понять это, я вернусь и отправлю решение, касающееся этой проблемы.

ответ

1

Создание класса поставщика связующего для пользовательского типа

public class MyCustomBinderProvider : IModelBinderProvider 
{ 
    public IModelBinder GetBinder(ModelBinderProviderContext context) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException(nameof(context)); 
     } 

     if (context.Metadata.ModelType == typeof(MyCustom)) 
     { 
      return new BinderTypeModelBinder(typeof(MyCustomBinder)); 
     } 

     return null; 
    } 
} 

и зарегистрировать его в службах

services.AddMvc(c => 
{ 
     c.ModelBinderProviders.Insert(0, new MyCustomBinderProvider()); 
}); 

И обычай Связующее может идти как

public class MyCustomBinder : IModelBinder 
{ 
    public Task BindModelAsync(ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType != typeof(MyCustom)) 
     { 
      return TaskCache.CompletedTask; 
     } 

     var parameters = new Dictionary<string, string>(); 
     foreach (var parameter in bindingContext.ModelType.GetProperties()) 
     { 
      var valueProviderResult = bindingContext.ValueProvider.GetValue(parameter.Name); 
      if (valueProviderResult.FirstValue != null) 
      { 
       parameters.Add(parameter.Name, valueProviderResult.FirstValue); 
      } 
     } 

     var result = Activator.CreateInstance(bindingContext.ModelType); 

     //write your custom code to map the result with the parameters 

     bindingContext.Result = ModelBindingResult.Success(result); 

     return TaskCache.CompletedTask; 
    } 
} 

Вашего пользовательского типа класс

[ModelBinder(BinderType = typeof(MyCustomBinder))] 
public class MyCustom 
{ 
    public int Page { get; set; } 
    public int Rows { get; set; } 
} 

и контроллер может принимать пользовательский класс в качестве параметра строки запроса

[HttpGet("data")] 
public DataTransferObject GetData(MyCustom query) 
{ 
} 
+0

Этот ответ работает, но стоит отметить, вам не нужен '[ModelBinder (BinderType = TypeOf (MyCustomBinder))]' атрибут ваш пользовательский тип класса. Просто наличие ModelBinderProvider в коллекции ModelBinderProviders достаточно. – Pondidum

Смежные вопросы