0

I have following model class:

public class TrackModel
    {
        public string Field;
        public ExampleClass Value;
    }
    public class ExampleClass
    {
        public string Type { get; set; }
    }

    public class TextClass : ExampleClass
    {
        public string TextField { get; set; }
        public string ValueFiled { get; set; }
    }

I need to receive instance of TextClass with his fileds. I try do do following:

 public class DefaultController : ApiController
{
    public string Post(TrackModel model)
    {
        TextClass textTerm = model.Value as TextClass;
        return "something";
    }
}

But "textTerm" every time is null.

JSON request:

{
    "Field":"string",
    "Value": {
        "Type":"type",
        "TextField":"textfield",
        "ValueField": "valuefield"
    }
}

I need exactly this class hierarchy. How can I map it correctly? Maybe JsonConverter? C someone in this example show how it's work? Or I can hear any solutions to this problem.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
kkost
  • 3,640
  • 5
  • 41
  • 72
  • Is this just ASP.NET codebehind or is this Post method part of a ASP.NET MVC controller? IT is not really clear from the way you ask the question. – MarengoHue Feb 12 '16 at 16:43
  • @MokonaModoki of course it is a simplified part of my code. But i need to map exactly like this hierarchy of classes in model – kkost Feb 12 '16 at 16:46
  • You didn't answer the question, but I assume this is an MVC app. – MarengoHue Feb 12 '16 at 16:47
  • @MokonaModoki That's part of ASP.NET Web Api Controller. – kkost Feb 12 '16 at 16:48
  • Have you tried debugging it? Is it just the 'Value' thats is null? Or the result of casting? Try casting it properly (not with conditional cast) like that: (TextClass)(model.Value) or try checking (model.Value is TextClass) You might have to use the composition approach. – MarengoHue Feb 12 '16 at 16:51
  • Am I missing something here or are you trying to "upcast" from a base class to a super class? That doesn't work: http://stackoverflow.com/questions/12565736/convert-base-class-to-derived-class – CodingGorilla Feb 12 '16 at 16:52

2 Answers2

1

Property Value is of type ExampleClass. Deserializing process has no information to realize that it needs to create Value as a TextClass.

Deserializing process is surely creating Value as ExampleClass since it's the only thing it can do without more information, then when you try to convert it to TextClass it fails since that conversion doesn't make sense in that context.

You'll have to change Value to type TextClass or define a custom deserialization process for that (I honestly don't have the details at the top of my head of how to do that)

Claudio Redi
  • 67,454
  • 15
  • 130
  • 155
1

When the Request arrives at the server, the data of the HttpRequest is bound to the model that is used in the action method parameters. In this process, the content is deserialized into objects.

If you assume that there can be various classes that inherit from ExampleClass, how should the model binder know that the request contains exactly the data that instead of creating an instance of ExampleClass an instance of TestClass should be created?

Even though you might compose the objects on the client using these classes, only the JSON is transmitted to the server. Based on this JSON and the TrackModel parameter type of the action the out-of-the-box model binder can only create an instance of ExampleClass.

One way to solve this is to create a custom model binder that contains the logic to create the right objects for your specific requirements. See this link on details of the binding process and the customization options.

Markus
  • 20,838
  • 4
  • 31
  • 55