lundi 21 novembre 2022

How to reflect/map models received from frontend into models at backend?

I want to make universal JSON generator for any ViewModel received from frontend. I found here that I can get type from string, but I do not know how to implement this in my case. My idea was to send from Angular array with 2 values, first would be string that say what type is my ViewModel, and second value would be ViewModel, which I need to convert to JSON. (I need this JSONon backend for converting to other file formats, and I have some special requirements, like change of name property, etc.) I am using MediatR, and here are my classes: GenerateJSONQuery is input object, the one I will get from frontend.

 public class GenerateJSONQuery<T> : IRequest<string>
    {
      public string TypeOfList { get; set; }
      public List<T> Data { get; set; }
    }

GenerateJSONQueryHandler is MediatR handler that will do reflection to ViewModel and generate JSON.

public class GenerateJSONQueryHandler<T> : IRequestHandler<GenerateJSONQuery<T>, string>
    {
        private readonly IddeeaODPDbContext _context;
        private readonly IMapper _mapper;
       

        public GenerateJSONQueryHandler(IddeeaODPDbContext context, IMapper mapper)
        {
            _context = context;
            _mapper = mapper;
        }

        public async Task<string> Handle(GenerateJSONQuery<T> request, CancellationToken cancellationToken)
        {
           // logic for generating files, in this part I need to somehow convert 
           // `request.Data` to specific List<T> where
           //  T can be e.g. `NewbornByBirthDateViewModel`, 
           //`IssuedDocumentsViewModel`, `RegisteredVehiclesViewModel`, etc. etc.
        }

Controller that connect IRequest and IRequestHandler is:

public class GenerateFilesController : ApiBaseController
    {
        public GenerateFilesController(IOptions<AppSettings> appSettings) : base(appSettings)
        {

        }

        [HttpPost]
        [SwaggerOperation(Tags = new[] { "Administration/Document" })]
        public async Task<string> List<T>([FromBody] GenerateJSONQuery<T> data, [FromHeader] string Authorization)
        {
            return await Mediator.Send(data);
            
        }

    }

and NewbornByBirthDateViewModel is example VieWModel that I need to serialize into JSON.

public class ClientNewbornByBirthDateViewModel 
    {
    
       [TranslatedFieldName("Identifier", LanguageEnum.EN)]
        public int Id { get; set; }
        public string Institution { get; set; }
       [TranslatedFieldName("Men", LanguageEnum.EN)]
        public int MaleTotal { get; set; }
       [TranslatedFieldName("Women", LanguageEnum.EN)]
        public int FemaleTotal { get; set; }
        public int Year { get; set; }
        public int Month { get; set; }
   }

I am pretty sure that my thinking way is bad, and that I need to do some kind of reflection, but I do not know how. I can not send only type of ViewModel from frontend, and then select all from db with context.Set<T>() because there can be filters, and those filters depends on which ViewModel is selected, so I must pass object with data from frontend to JSONGenerate logic and then reflect it to specific ViewModel on backend.





Aucun commentaire:

Enregistrer un commentaire