0

I have a problem with received model. I have a few class, and all extends from base class of 'Record', simple example is below.

class Record{
...
}

class Language : Record{
...
}

and when i posting 'form' using ajax.beginform i recive 500 internal server error.
I used debugger to find issue. Problem occurs when i casted object of Record to Language. Example is below.

public PartialViewResult Test(Record rec)
{
Language l = (Language)rec; // error in here??
...
}

and if i modify parameter type to Language like below

public PartialViewResult Test(Language rec)
{
...
}

evrything is ok, works correctly, all of fields 'rec' have been filled.
Where i do mistake? Casting is not allowed?

Sorry for my bad English :c

neuser
  • 107
  • 13
  • take a look at this.. https://stackoverflow.com/questions/988658/unable-to-cast-from-parent-class-to-child-class, the second ranked answer has a workaround! – JuanDM Oct 07 '17 at 22:18
  • 2
    You cannot cast `Record` to `Language` since not every `Record` is a `Language`. Similar to how every `Man` is a `Person`, but not every `Person` is a `Man`. – mjwills Oct 07 '17 at 22:18
  • Record is not a Language, you can't cast in that direction in the inheritance. compared to Language is a Record so you can cast from Language to Record – Royi Mindel Oct 07 '17 at 22:19
  • `Language` is a `Record` but a `Record` is not a `Language` –  Oct 07 '17 at 22:19
  • you have right :) i try to use generic type – neuser Oct 07 '17 at 22:25
  • @mjwills, nope, in C# it's perfectly fine to cast a superclass as a subclass as long the underlying type is a subclass. In other words, passing a Record that contains a Language is not a problem when casting as Language. It only will crash if the record is not a language. Perhaps it's raising internal server error before the code posted by OP runs, because there's a type mismatch. Json object matches a language but not a record. – derloopkat Oct 07 '17 at 22:49
  • 2
    The model binder creates the type that you pass as the parameter. Thus, it creates a Record and not a Language. You can't cast it to a language because it's NOT one. You have to use the Language type as the parameter to get the model binder to create the Language, unless you create a custom model binder that will create Languages instead of Records for this type. – Erik Funkenbusch Oct 08 '17 at 01:33
  • @derloopkat - no, it wouldn't crash. The Language object contains all the properties of a Record, and the model binder will simply ignore any additional values. The problem is that the model binder only instantiates a Record and not a Language, thus the cast is invalid and crashes. – Erik Funkenbusch Oct 08 '17 at 20:06
  • @derloopkat - if you know, why do you keep insisting otherwise? The error in this code *IS* the line you mention, the model binder does not crash on this. The thing that causes the crash is entirely in the cast. – Erik Funkenbusch Oct 08 '17 at 21:59
  • @ErikFunkenbusch, have you ran this code? please run the code and then comment – derloopkat Oct 08 '17 at 22:38
  • @derloopkat - what code did you run? There's not enough code here to run without seriously diverging from whatever the posters real code is. – Erik Funkenbusch Oct 08 '17 at 22:42
  • @ErikFunkenbusch, I see. In my case this line didn't run because Record has a constructor that takes one argument and doesn't have parameterless constructor. This situation alone produces internal server error for record but not for language. But it is a particular case. – derloopkat Oct 08 '17 at 23:39
  • @derloopkat - MVC requires all model bound parameters to have parameterless constructors (unless you are using a custom model binder that supplies the constructor arguments, even then it's often dicey) or no constructor at all (which uses the default parameterless constructor). The default model binder will not supply any parameters. So the problem you experienced is different from the one the original poster was posting about. – Erik Funkenbusch Oct 09 '17 at 00:04

0 Answers0