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.