سؤال

In this post, Mike Wasson states:

"Besides ParameterBindingAttribute, there is another hook for adding a custom HttpParameterBinding. On the HttpConfiguration object"

But I have three HttpConfiguration objects in my Web API app, namely:

public static void Register(HttpConfiguration config, IWindsorContainer container) <-- in WebApiConfig.cs
private static void MapRoutes(HttpConfiguration config) <-- ""
public static void ConfigureWindsor(HttpConfiguration configuration) <-- in Global.asax.cs

Which of these (config, config, or configuration) should I use (if any)?

UPDATE

I tried this, with a breakpoint on the "if" line:

public static void ConfigureWindsor(HttpConfiguration configuration)
{
    _container = new WindsorContainer();
    _container.Install(FromAssembly.This());
    _container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
    var dependencyResolver = new WindsorDependencyResolver(_container);
    configuration.DependencyResolver = dependencyResolver;

    if (configuration.Properties.Values.Count > 0) // <-- I put a Casey Jones here
    {
        object o = configuration.Properties.Values.ElementAt(configuration.Properties.Values.Count - 1);
        string s = o.ToString();
    }
}

...but I only hit that spot once, on the server starting up, but not when the client sent a request to it...there must be some event that gets fired when a server passes a request where the incoming URL can be examined...no?

هل كانت مفيدة؟

المحلول

Usually you do have only one instance of HttpConfiguration which is the one you get from GlobalConfiguration.Configuration.

Said so, that's how I plugged custom binders

In global.asax

var binderMappings = new Dictionary<Type, Type>
    {
        {typeof(YourModelType), typeof(YourModelTypeBinder)},
        //....
    };

config.Services.Add(
    typeof(ModelBinderProvider),
    new WindsorModelBinderProvider(container, binderMappings));

WindsorModelBinderProvider

public class WindsorModelBinderProvider : ModelBinderProvider
{
    private readonly IWindsorContainer _container;
    private readonly IDictionary<Type, Type> _binderMappings;

    public WindsorModelBinderProvider(IWindsorContainer container, IDictionary<Type, Type> binderMappings)
    {
        _container = container;
        _binderMappings = binderMappings;
    }

    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
    {
        IModelBinder binder = null;
        if (_binderMappings.ContainsKey(modelType))
        {
            binder = _container.Resolve(_binderMappings[modelType]) as IModelBinder;

            if (binder == null)
            {
                throw new ComponentNotFoundException(modelType);
            }
        }

        return binder;
    }
}   

YourModelTypeBinder

public class YourModelTypeBinder : IModelBinder
{
    public YourModelTypeBinder(IYourServiceToLoadYourModelType service)
    {
        //...
    }

    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        bindingContext.Model = YourCustomCodeToLoadYourModelTypeUsingTheConstructorDependecies(actionContext.Request);
        return true;
    }

    private YourModelType YourCustomCodeToLoadYourModelTypeUsingTheConstructorDependecies(HttpRequestMessage requestMessage)
    {
        ...
    }
}

YourModelTypeBinder will be resolved by the container(see WindsorModelBinderProvider), so you need to registered it first.

After all that plumbing, your controller may have a parameter, among others, as following

[ModelBinder]YourModelType user
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top