I have implemented a custom MediaTypeFormatter in a SelfHosted AspNet WebAPI. I've used Unity.WebApi for dependency resolution. The controller classes only know about the interfaces implemented by the model classes, whereas, repositories give the concrete models as a result of actions.
The custom MediaTypeFormatter is inherited from BufferedMediaTypeFormatter as discussed here: http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters.
The problem is this media type formatter is not working. Even when I use to debug the code, the ReadFormStream method is never hit. Does someone know:
- What could be the possible issue?
- Do I need to tell the unity container for mapping of interfaces to model classes?
- How would I get the reference to the dependency resolver inside the custom media type formatter?
Below is the code to add formatter:
var config = new SelfHostConfiguration("https://xxx.xxx.xxx.xxx:xxxx/");
config.Formatters.Add(new EntityTypeFormatter());
Below is the code for the EntityController:
public class EntityController : ApiController
{
private readonly IEntitiesRepository repository = null;
public EntityController(IEntitiesRepository repository)
{
if (repository == null)
{
throw new ArgumentNullException("repository");
}
this.repository = repository;
}
public IEnumerable<IEntity> Get()
{
return (IEnumerable<IEntity>)repository.Get();
}
}
Below is the code for the EntityRepository:
public class EntitiesRepository : IEntitiesRepository
{
public IEnumerable<IEntity> Get()
{
return new Entities[]
{
new Entity
{
Prop1 = "value for property 1",
Prop2 = "value for property 2",
Prop3 = "value for property 3"
},
new Entity
{
Prop1 = "value for property 1",
Prop2 = "value for property 2",
Prop3 = "value for property 3"
}
};
}
public IEntity Get(long id)
{
return new Entity
{
Prop1 = Convert.ToString(id),
Prop2 = "value for property 2",
Prop3 = "value for property 3"
};
}
}
Below is the implementation of the EntityMediaTypeFormatter class:
public class EntityMediaTypeFormatter : BufferedMediaTypeFormatter
{
public EntityMediaTypeFormatter()
: base()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
public override bool CanReadType(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (type is IEntity)
{
return true;
}
else if (type.IsGenericType)
{
return type.GenericTypeArguments.Single(a => a.GetType().Equals(typeof(IEntity))) != null;
}
return false;
}
public override bool CanWriteType(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (type is IEntity)
{
return true;
}
return false;
}
public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
if (type.IsInterface)
{
type = GetConcreteType(type);
}
return base.ReadFromStream(type, readStream, content, formatterLogger);
}
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
//nothing special for now...
base.WriteToStream(type, value, writeStream, content);
}
private Type GetConcreteType(Type type)
{
//TODO: Need to find a way to DependencyResolver to get the concrete type
return typeof(Entity);
}
}
Thanking in advance for any help.