1

I have this model:

namespace SomeApp.Models
{
    public class FirstModel
    {
        public int uid { get; set; }
        public string? id { get; set; }
        public string? firstname { get; set; }
        public string? lastname { get; set; }
     }
}

whose fields I need to convert to a dictionary or JSON object in another model. I'm using the GetFields Method.

namespace SomeApp.Models
{
    public class SecondModel
    {
        // other fields


        public Dictionary<string, string> FirstModelTransfer { get; set; }

        public void SetFirstModelTransfer(FirstModel firstModel)
        {
            FieldInfo[] firstModelFields = typeof(FirstModel).GetFields();

            Dictionary<string, string> dict = new();

            foreach (var firstModelField in firstModelFields)
            {
                string fieldName = firstModelField.Name;
                string fieldValue = firstModelField.GetValue(fieldName).ToString();

                dict[fieldName] = fieldValue;
            }

            FirstModelTransfer = dict;
        }
    }
}

I want the result to look like

{
  // other fields
  "FirstModelTransfer": {
    "firstname": "Sample firstname",
    "lastname": "Sample lastname"
  }
}

But currently, it looks like this,

{
  // other fields
  "FirstModelTransfer": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}

I don't know if this matters but:

services.AddDbContext<SecondModelsContext>();
services.AddDbContext<FirsModelsContext>();

This is the ordering of the dbContexts in which each model was registered.

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
Prosy Arceno
  • 2,616
  • 1
  • 8
  • 32

1 Answers1

1

From your code, you are trying to get the properties but not fields in FirstModel class.

Thus, you should get the properties as PropertyInfo[] via GetProperties().

PropertyInfo[] firstModelFields = typeof(FirstModel).GetProperties();

To get the property value via Reflection, you have to pass the object instance as mentioned in PropertyInfo.GetValue(Object) method.

string fieldValue = firstModelField.GetValue(firstModel)?.ToString();

Alternatively, you may use the Newtonsoft.Json library to convert an object into a Dictionary<string, string> instance without Reflection.

using Newtonsoft.Json.Linq;

dict = JObject.FromObject(firstModel)
    .ToObject<Dictionary<string, string>>();
Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • [Demo @ .NET Fiddle](https://dotnetfiddle.net/diXiyO) – Yong Shun May 22 '23 at 02:50
  • It still is outputting the same. Could it be because the firstModel is from a different dbContext? and the dbContext in which the firstModel was used was added later than the dbContext the secondModel was used? – Prosy Arceno May 22 '23 at 03:20
  • I don't think the issue is due to DbContext. DbContext is which you use to perform data operation (fetch, insert, update, delete) the data in DB. It's likely that the issue came from how you assign, or serialization issue. Have you tried to print out and check the value in your minimal API that you will return as the response? – Yong Shun May 22 '23 at 03:33
  • I'm getting this one when I tried it `The entity type 'Dictionary' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'.` – Prosy Arceno May 22 '23 at 03:40
  • Okay, seems your `SecondModel` is a DbContext entity model. As this `FirstModelTransfer` is not a column in the DB table, you should apply the [`[NotMapped]`](https://www.learnentityframeworkcore.com/configuration/data-annotation-attributes/notmapped-attribute) attribute on this property. – Yong Shun May 22 '23 at 03:45
  • Ah got it. So since my `FirstModelTransfer` is actually mapped to a table, I should then create a base model and have `FirstModelTransfer` and another Model named `NotMappedFirstModelTransfer` so that I can use `NotMappedFirstModelTransfer` to apply the dictionary on my `SecondModel`. Correct? – Prosy Arceno May 22 '23 at 03:54
  • 1
    Yes, you can do like that, usually either create another model class for customization if particular class is not part of DbContext entity, otherwise you should use the `NotMapped` attribute. – Yong Shun May 22 '23 at 04:19