user1624372
user1624372

Reputation:

MediaTypeFormatter issue in Self-Hosted ASPNET WebAPI

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:

  1. What could be the possible issue?
  2. Do I need to tell the unity container for mapping of interfaces to model classes?
  3. 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.

Upvotes: 1

Views: 1414

Answers (1)

Darrel Miller
Darrel Miller

Reputation: 142014

Looks to me like one of the existing formatters is taking priority over yours. Either clear the existing formatter collection before adding yours, or insert yours at position 0.

Upvotes: 1

Related Questions