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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With