Reputation: 51
I have a situation where I have a core webApi endpoint. I would like to be able to serialize the incoming Json to a Dto. The Dto would contain the necessary fields, but the incoming request may contain additional properties (different for some clients). I need to be able to capture the additional properties as well, but they will only be known at runtime (the records are to be stored in a DocumentDB (Mongo)). I was deserializing to a dynamic object:
[Route("api/Chapter/CreateNewChapter")]
[HttpPost]
public IActionResult CreateNewChapter([FromBody]dynamic incomingJson)
{
dynamic incomingObject = JsonConvert.DeserializeObject<ExpandoObject>(incomingJson.ToString(), new ExpandoObjectConverter());
if (!IsAuthenticated(incomingObject))
return Unauthorized();
var createNewChapter = new CreateNewChapter();
var outgoingJson = createNewChapter.Process(incomingObject);
var resultJson = JsonConvert.SerializeObject(outgoingJson, Formatting.Indented);
return Ok(resultJson);
}
This worked just fine, the problem is that there is no schema or concrete object to use for Swagger, as well as validation on all of the fields was a nightmare.
So ultimately I would like to do something like this:
public class ChapterDto
{
public int ChapterId {get; set};
public string ChapterName {get; set};
)
Then if there are additional properties sent in the request (Json), The properties can be added dynamically at runtime. In addition, I would be adding metadata properties "ParentChapterId" etc.
Should I try to map the incoming json to the dto so I know we have the valid incoming properties, then if that passes map the entire Json object to the dynamic object like I'm doing above? Or is there a better way to achieve this?
Upvotes: 0
Views: 939
Reputation: 8325
You can use JSON extension data. When deserializing, it will map additional properties not found in the DTO to a suitably-attributed dictionary property that you add to the DTO.
Example usage:
public class ChapterDto
{
public int ChapterId { get; set; }
public string ChapterName { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> AdditionalData { get; set; }
}
Upvotes: 1