5

I am building a REST API with ASP.NET WebAPI. Everything worked fine, but then I came up with the great idea to use interfaces in all my method calls. After I have changed all the methods i noticed that after setting the parameter in my Controller methods as interfaces, my API calls does not work. I am using OWIN Self host and Unity dependency injection. Here is my relevant code:

Resolving my Interface:

      IUnityContainer container = new UnityContainer();

      container.RegisterType<IMyInterface, MyInterfaceImpl>(new HierarchicalLifetimeManager());
      HttpConfiguration config = new HttpConfiguration();
      config.DependencyResolver = new UnityDependencyResolver(container);  

My Controller (the part where i get the error)

    [Route("test")]
    [HttpGet]
    public HttpResponseMessage GetSomeData([FromUri]IMyInterface searchObject)
    {
         return this._searchService.SearchForData(searchObject);

    }

When calling this method i get the error that an interface cannot be created. I unterstand that, but the problem is fixing it. I looked at ASP.NET Web API Operation with interfaces instead concrete class and also at https://brettedotnet.wordpress.com/2014/07/16/web-api-and-interface-parameters/ and at ASP.NET Web API Operation with interfaces instead concrete class, but none of the suggestions worked in my case (always getting the error that an interface cannot be created).

I was wondering if someone has a working example on something like this(on github or elsewhere) just to check what I am doing wrong (or even an idea what else I could try would be nice)

Thank you

Community
  • 1
  • 1
user3466562
  • 465
  • 2
  • 10
  • 23

2 Answers2

3

Because you are passing data from the querystring a different approach is required here. In my blog post that you referenced I did not include that scenario. Since querystrings are handled via Model Binders you need to create a custom model binder.

In my situation I opted for creating a IoCModelBinder as seen below.

public class IocModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var targetObject = ServiceLocator.Current.GetInstance(bindingContext.ModelType);
        var valueProvider = GlobalConfiguration.Configuration.Services.GetValueProviderFactories().First(item => item is QueryStringValueProviderFactory).GetValueProvider(actionContext);

        foreach (var property in targetObject.GetType().GetProperties())
        {
            var valueAsString = valueProvider.GetValue(property.Name);
            var value = valueAsString == null ? null : valueAsString.ConvertTo(property.PropertyType);

            if (value == null)
                continue;

            property.SetValue(targetObject, value, null);
        }

        bindingContext.Model = targetObject;
        return true;
    }
}

And in use

    /// <summary>
    /// Searches by the criteria specified.
    /// </summary>
    /// <param name="searchCriteriaDto">The search criteria dto.</param>
    /// <returns></returns>
    [HttpGet]
    public HttpResponseMessage Search([ModelBinder(typeof(IocModelBinder))]IApplicationSearchCriteriaDto searchCriteriaDto)
    {

    }

Hope this helps.

Brette

brettenet
  • 46
  • 3
  • Since I am using an Owin for self host I don't have the GlobalConfiguration. All I have is an HttpConfiguration but when using it I get an error that there is no method GetValueProviderFactories in HttpConfiguration which accepts System.Web.Http.Controllers.ServicesContainer as an argument – user3466562 Dec 07 '14 at 00:27
0

Perhaps this helps: Parameter Binding in ASP.NET Web API
How to bind to custom objects in action signatures in MVC/WebAPI
You can't use an Formatter because you data are coming from the URI. I think you can go with the Modelbinder approch from the links.

Stefan Ossendorf
  • 696
  • 6
  • 14