// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Diagnostics.Contracts; using System.Web.Http.Controllers; namespace System.Web.Http.ModelBinding.Binders { // Returns a user-specified binder for a given type. public sealed class SimpleModelBinderProvider : ModelBinderProvider { private readonly Func _modelBinderFactory; private readonly Type _modelType; public SimpleModelBinderProvider(Type modelType, IModelBinder modelBinder) { if (modelType == null) { throw Error.ArgumentNull("modelType"); } if (modelBinder == null) { throw Error.ArgumentNull("modelBinder"); } _modelType = modelType; _modelBinderFactory = () => modelBinder; } public SimpleModelBinderProvider(Type modelType, Func modelBinderFactory) { if (modelType == null) { throw Error.ArgumentNull("modelType"); } if (modelBinderFactory == null) { throw Error.ArgumentNull("modelBinderFactory"); } _modelType = modelType; _modelBinderFactory = modelBinderFactory; } public Type ModelType { get { return _modelType; } } public bool SuppressPrefixCheck { get; set; } public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType) { if (modelType == null) { throw Error.ArgumentNull("modelType"); } if (modelType == ModelType) { if (SuppressPrefixCheck) { // If we're suppressing a prefix check, then we don't need any further info from the ActionContext // to know that we're using this binder. return _modelBinderFactory(); } else { return new SimpleModelBinder(this); } } return null; } // Helper binder to do the prefix check before invoking into the user's binder. private class SimpleModelBinder : IModelBinder { private readonly SimpleModelBinderProvider _parent; public SimpleModelBinder(SimpleModelBinderProvider parent) { _parent = parent; } public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { Contract.Assert(!_parent.SuppressPrefixCheck); // wouldn't have even created this binder if (bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { IModelBinder binder = _parent._modelBinderFactory(); return binder.BindModel(actionContext, bindingContext); } return false; } } } }