1

I have these two classes and an action method

public class A
{
    public int AProp { get; set; }
}

public class B : A
{
    public int BProp { get; set; }
}

public void TestAction(A a)
{
    if (!(a is B)) 
    {
        throw new Exception("Should be B!");
    }
}

In my Global.asax's Application_Start I have below line.

var setting = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
setting.TypeNameHandling = TypeNameHandling.All;

And the json data I am posting is like below.

{$type: 'MyNamespace.B, MyAssembly', AProp: 1, BProp: 2}

When action is invoked I expect type of a param is MyNamespace.B but it is MyNamespace.A so the exception gets thrown.

I wrote below code and tested if $type and TypeNameHandling thing work fine, they work. Type of objA is MyNamespace.A and type of objB is MyNamespace.B

var json = @"{$type: 'MyNamespace.B, MyAssembly', AProp: 1, BProp: 2}";

var objA = JsonConvert.DeserializeObject(json, typeof(A), new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None
});

var objB = JsonConvert.DeserializeObject(json, typeof(A), new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
});

What's the proper way to handle inheritance with ASP.NET MVC Controllers' Action parameters?

Mehmet Ataş
  • 11,081
  • 6
  • 51
  • 78

1 Answers1

2

You seem to have set the TypeNameHandling setting on the ASP.NET Web API infrastructure, not ASP.NET MVC. So this will work for your Web API controllers.

ASP.NET MVC's default value provider factory doesn't use Json.NET. it uses the built-in JavaScriptSerializer. If you want it to use Json.NET you may check the following answer in which a custom factory is implemented:

ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().Single());
ValueProviderFactories.Factories.Add(new MyJsonValueProviderFactory());
Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928