Asp Net Core RC2. Связывание абстрактной модели класса

В RC1 я использую следующий код для привязки абстрактных классов или интерфейсов:

public class MessageModelBinder : IModelBinder {

    public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext) {
        if(bindingContext.ModelType == typeof(ICommand)) {
            var msgTypeResult = bindingContext.ValueProvider.GetValue("messageType");
            if(msgTypeResult == ValueProviderResult.None) {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }
            var type = Assembly.GetAssembly(typeof(MessageModelBinder )).GetTypes().SingleOrDefault(t => t.FullName == msgTypeResult.FirstValue);
            if(type == null) {
                return ModelBindingResult.FailedAsync(bindingContext.ModelName);
            }
            var metadataProvider = (IModelMetadataProvider)bindingContext.OperationBindingContext.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider));
            bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(type);
        }
        return ModelBindingResult.NoResultAsync;
    }
}

Это связующее читает только тип модели (messageType параметр) из строки запроса и переопределяет тип метаданных. А остальная часть работы выполняется стандартными связующими, такими какBodyModelBinder.

В Startup.cs я просто добавляю первый компоновщик:

services.AddMvc().Services.Configure<MvcOptions>(options => {
    options.ModelBinders.Insert(0, new MessageModelBinder());
});

контроллер:

[Route("api/[controller]")]
public class MessageController : Controller {
    [HttpPost("{messageType}")]
    public ActionResult Post(string messageType, [FromBody]ICommand message) {
    } 
}

Как я могу выполнить это в RC2?

Насколько я понимаю, теперь я должен использоватьIModelBinderProvider, Хорошо, я попробовал Startup.cs:

services.AddMvc().Services.Configure<MvcOptions>(options => {
    options.ModelBinderProviders.Insert(0, new MessageModelBinderProvider());
});

ModelBinderProvider:

public class MessageModelBinderProvider : IModelBinderProvider {
    public IModelBinder GetBinder(ModelBinderProviderContext context) {
        if(context == null) {
            throw new ArgumentNullException(nameof(context));
        }
        return context.Metadata.ModelType == typeof(ICommand) ? new MessageModelBinder() : null;
    }
}

ModelBinder:

public class MessageModelBinder : IModelBinder {
    public Task BindModelAsync(ModelBindingContext bindingContext) {
        if(bindingContext.ModelType == typeof(ICommand)) {
            var msgTypeResult = bindingContext.ValueProvider.GetValue("messageType");
            if(msgTypeResult == ValueProviderResult.None) {
                bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
                return Task.FromResult(0);
            }
            var type = typeof(MessageModelBinder).GetTypeInfo().Assembly.GetTypes().SingleOrDefault(t => t.FullName == msgTypeResult.FirstValue);
            if(type == null) {
                bindingContext.Result = ModelBindingResult.Failed(bindingContext.ModelName);
                return Task.FromResult(0);
            }
            var metadataProvider = (IModelMetadataProvider)bindingContext.OperationBindingContext.HttpContext.RequestServices.GetService(typeof(IModelMetadataProvider));
            bindingContext.ModelMetadata = metadataProvider.GetMetadataForType(type);
            bindingContext.Result = ModelBindingResult.Success(bindingContext.ModelName, Activator.CreateInstance(type));
        }
        return Task.FromResult(0);
    }
}

Но я не могу указатьNoResult, Если я не укажуbindingContext.ResultЯ получаю нулевую модель в контроллере. Если я укажуbindingContext.Result, Я получаю пустую модель без установки полей модели.

Ответы на вопрос(1)

Ваш ответ на вопрос