// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Threading.Tasks; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding { /// /// An which provides data from a specific . /// /// /// /// A is an base-implementation which /// can provide data for all parameters and model properties which specify the corresponding /// . /// /// /// is greedy, meaning that a given instance expects to handle all /// parameters and properties annotated with the corresponding and /// will short-circuit the model binding process to prevent other binders from running. /// of must be set to true. /// /// public abstract class BindingSourceModelBinder : IModelBinder { /// /// Creates a new . /// /// /// The . Must be a single-source (non-composite) with /// equal to true. /// protected BindingSourceModelBinder([NotNull] BindingSource bindingSource) { // This class implements a pattern that's only useful for greedy model binders. If you need // to implement something non-greedy then don't use the base class. if (!bindingSource.IsGreedy) { var message = Resources.FormatBindingSource_MustBeGreedy( bindingSource.DisplayName, nameof(BindingSourceModelBinder)); throw new ArgumentException(message, nameof(bindingSource)); } BindingSource = bindingSource; } /// /// Gets the corresponding . /// protected BindingSource BindingSource { get; } /// /// Binds the model. Called when the model's supported binding-source matches . /// /// The . /// /// A which will complete when model binding has completed. /// protected abstract Task BindModelCoreAsync([NotNull] ModelBindingContext bindingContext); /// public async Task BindModelAsync(ModelBindingContext context) { var allowedBindingSource = context.ModelMetadata.BindingSource; if (allowedBindingSource == null || !allowedBindingSource.CanAcceptDataFrom(BindingSource)) { // Binding Sources are opt-in. This model either didn't specify one or specified something // incompatible so let other binders run. return null; } var result = await BindModelCoreAsync(context); var modelBindingResult = result != null ? new ModelBindingResult(result.Model, result.Key, result.IsModelSet) : new ModelBindingResult(null, context.ModelName, false); // Prevent other model binders from running because this model binder is the only handler for // its binding source. return modelBindingResult; } } }