I have an ASP.NET Core Web API end point which takes (FromBody) The Search object defined below
public class Search {
public int PageSize {get;set;}
public Expression Query{get;set;}
}
public class Expression {
public string Type {get;set;}
}
public class AndExpression {
public IList<Expression> Expressions {get;set;}
}
public class MatchesExpression {
public string FieldId {get;set;}
public string Value {get;set;}
public string Operator {get;set;}
}
So… if I post the following JSON to my endpoint
{ "pageSize":10, "query": { "fieldId": "body", "value": "cake", "operator": "matches" } }
I successfully get a Search Object, but the Query property is of type Expression, not MatchesExpression.
This is clearly a polymorphic issue.
This article (towards the end) gives a good example of a how to deal with this issue when your entire model is polymorphic.
https://learn.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-5.0
In my case, the property of my Model "Query" is polymorphic, so Im unsure how to build a ModelBinder for my Search object that will allow me to handle the Query Property
I Imagine, I need to write a model binder to construct the search object and then follow the pattern described for the property, however I cannot locate any examples of how to implement a model binder that isnt utterly trivial.
Any suggestions on how to achieve this? Good sources of information?
2
Answers
So.. I gave up with ModelBInders (because Im using the FromBody attribute which isnt compatible with my aims).
Instead I wrote a System.Text.Json JsonConvertor to handle the polymorphism (see shonky code below)
My Expression class also had the following attribue
I recently ran into the same issue, but was using Newtonsoft.Json, here is iasksillyquestions’ solution using Newtonsoft.Json:
In my case I had an enum
ConnectionType
to specify what derived type the object was.Connection.cs:
LDAPConnection.cs:
Then you can have one controller for all derived types: