Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom MediaTypeFormatter, why IKeyValueModel and not my model type?

I am trying to do a custom implementation of a MediaTypeFormatter, but the method bool CanReadType(Type type) is always called with the type IKeyValueModel, instead my type MyProduct.

In my API controller I have:

[HttpPost]
public Task Save(MyProduct product)

I have seen some examples ( example 1, example 2), and I have also tried the code:

protected override bool CanReadType(Type type)
{
    if (type == typeof(IKeyValueModel))
        return false;
      return true;
}

But then I get a "MissingMethodException: No parameterless constructor defined for this object", because my model type has no parameterless constructor. So it looks like because CanReadType returns false to IKeyValueModel, the framework uses another media type formatter. Actually, the method OnReadFromStreamAsync is never hit.

I want to be able of controlling how my models are deserialized, I want to get the real type and not IKeyValueModel.

This was already working great in MVC with model binders.

Cheers.

UPDATE 2012/05/29:

If I remove the default json formatter it works:

    public static void RegisterApis(HttpConfiguration config)
    {
        config.Formatters.Clear();

But then I will like to keep both, how could I indicate which one I want to use?

Regards.

like image 452
vtortola Avatar asked May 28 '12 11:05

vtortola


1 Answers

If you need to control serialisation, it is better to use Json.NET's flexibility features (see here, here and here) to control rather than write a media type formatter just for that.

Json.NET now is the default formatter in the ASP.NET Web API.


UPDATE

My objects don't have parameterless constructors and the properties are readonly. I have also objects that inherit from DynamicObject, so let's say that my business entities are not trivial.

I probably can show you how to shoot yourself in the foot. But I would rather explain how to avoid having these problems as I believe you are having them since there are anti-patterns in you approach.

First of all, what you are looking for is not another media type formatter. You need a different serializer or just need to configure your serializer.

But more importantly, serializing your business entities straight to the client is not such a great idea. We need DTOs which here are called view models. Such classes are only state holders, no logic, no magic. Serializing them should be no issue.

You can use AutoMapper, etc to map your entities to view models with no more development cost. It is always advised to abstract away your domain models from the presentation layer.

like image 88
Aliostad Avatar answered Oct 02 '22 05:10

Aliostad