I have the following data object.
public class Response<T> where T : MyBaseDTO
{
public bool result
{
get; set;
}
public List<Message> messages
{
get; set;
}
public List<T> data
{
get; set;
}
}
public class Message
{
public Message(MessageTypeEnum type)
{
this.typeEnum = type;
}
public string type
{
get
{
return typeEnum.ToString();
}
}
public MessageTypeEnum typeEnum
{
get; set;
}
public int index
{
get; set;
}
public string field
{
get; set;
}
public string code
{
get; set;
}
public string message
{
get; set;
}
public string messageValue
{
get; set;
}
public enum MessageTypeEnum
{
WARNING,
INFO,
ERROR
}
When I use RestSharp to call the API, the deserialized Data is null with following error(Content contains correct response in string):
" ErrorMessage "Each parameter in the deserialization constructor on type 'Response.Message' must bind to an object property or field on deserialization."
I found the following post and added empty constructor to my object.
Error: Each parameter in constructor must bind to an object property or field on deserialization
public class Message
{
public Message()
{
}
public Message(MessageTypeEnum type)
{
this.typeEnum = type;
}
public string type
{
get
{
return typeEnum.ToString();
}
}
public MessageTypeEnum typeEnum
{
get; set;
}
public int index
{
get; set;
}
public string field
{
get; set;
}
public string code
{
get; set;
}
public string message
{
get; set;
}
public string messageValue
{
get; set;
}
public enum MessageTypeEnum
{
WARNING,
INFO,
ERROR
}
Added empty constructor resolved my issue with RestSharp. However I just noticed it failed some unit tests in my other project that uses Message Object.
Here is the code
using var reader = new StreamReader(result.ResponseMessage.Content.ReadAsStream());
body = reader.ReadToEnd();
Response<Test> responseObject = JsonConvert.DeserializeObject<Response<Test>>(body);
"body" looks like something below which is expected.
body "{"result":true,"messages":[{"type":"ERROR","index":0,"field":"ID","code":"MISSING-ID","message":"The entry is incomplete.","messageValue":null}],"data":[{"....
However, after the deserialization, "Type" became WARNING instead ERROR and hence it failed the unit test.
Looks like it defaults to first one of the Enum.
public enum MessageTypeEnum
{
WARNING,
INFO,
ERROR
}
Does anyone knows what’s going on here and how to fix the issue?
2
Answers
Your code is not complete and your JSON example is malformed, so I am unable to provide an example with your exact code. That said, you should be able to suss out the details you need to fix your particular issue.
First, when you are deserializing to a class you must have an empty constructor as required by the deserializer. The deserializer will not be passing any parameters to your constructor, so you can’t depend on them.
Second, to read/write a class property it must have both a
get
andset
. The deserializer will not be able to fully work with properties that do not have bothget
andset
.One possible solution, is to create a string property that contains both
get
andset
, and then create an additional property with only theget
that is typed to the Enum.The root object is basically your Response object, but as you didn’t provide that code I made the RootObject.
since you have type as string too, you have to fix your Message costructor by adding attribute
after this everything is working properly