0

I have an incoming json object that represents the data pulled from a database structure.

I would like to map it to the Entity Framework model which has the definitions either from attributes or from model builder in the DB context.

When running Entity Framework, this data maps correctly so I know the models are correct.

So using the same structure, instead of calling the database through EF, I am pulling from an API that has the same incoming data structure as the entity.Property column names.

How do I map the incoming json structure to the model object?

Attributes

[Table("model_example")]
public class ModelExample
{
   [Column("property_to_map")] // <-- db column name
   public int PropertyToMap { get; set; }
}

Or ModelBuilder:

modelBuilder.Entity<ModelExample>(entity =>
{
    entity.ToTable("model_example");
    entity.Property(e => e.PropertyToMap).HasColumnName("property_to_map");
}

Incoming JSON example:

 { "property_to_map":1 }   

So if this data was pulled from the db it would automatically be mapped to `ModelExample.PropertyToMap' and the ModelExample code model.

How do I map it? Is there a way to use the Entity Framework process?

Update

I know how to map from json to object using Newtonsoft. I'm trying to map to the entity without having to use a mapper. Entity Framework already has these values, I was hoping to just use entity framework tie in.

Demodave
  • 6,242
  • 6
  • 43
  • 58
  • perhaps add an example of a method call where you'd like this to happen and an example of what you've tried or where you'd like this conversion to have been picked up. If this is a case of receiving a JSON data from a client that you want to automatically be interpreted as an entity, I strongly advise against this, Data coming from a client can easily be tampered with and should not be trusted as an entity that could be attached to a context and committed to the database. – Steve Py Mar 21 '19 at 23:36

2 Answers2

0

I've used JsonConvert.DeserializeObject from Newtonsoft to do this in the past. Hopefully this helps.

class Example {
  public int property_to_map {get; set;}
}

class ApiCalls{

  public void MakeApiCall() {
     var response = ApiCall();
     var MappedObject = JsonConvert.Deserialize<Example>(response);
     //Do whatever you need now with the mapped object.
  }
}
Moh. Anwer
  • 41
  • 4
  • This is not what I'm referring too, I know how to convert from json. I'm hoping to get the Example.PropertyToMap value already used. Maybe I didn't want to have to use a mapper. – Demodave Mar 21 '19 at 22:06
  • Oh okay, I believe you can still use newtonsoft. It has an attribute you can assign the snake case name too so it assigns to PropertyToMap instead of property_to_map: https://stackoverflow.com/questions/15915503/net-newtonsoft-json-deserialize-map-to-a-different-property-name – Moh. Anwer Mar 22 '19 at 02:56
0

Ok, instead of forcing the json to the model, I decided to alter The Json string instead.

I do this by Creating a custom JsonConverter and inside there rename the JProperty.

  1. Build A Generic JsonConverter Base Class

    public abstract class JsonCreationConverter<T> : JsonConverter
    {            
        protected abstract T CreateArray<TJsonType>(Type objectType, TJsonType jObject);
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException("Unnecessary because CanWrite is " +
                                          "false. The type will skip the converter.");
        }
    
        public override object ReadJson(JsonReader reader, Type objectType,
            object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
                return null;
    
            JArray jArray;
            var target = default(T);
            try
            {
                jArray = JArray.Load(reader);
                target = CreateArray<JArray>(objectType, jArray);
            }
            catch (Exception ex)
            {                    
                return null;
            }
            return target;
        }
    
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }
    
        public override bool CanWrite
        {
            get { return false; }
        }
    
    }
    
  2. Build a Custom JSON Converter.

    public class JsonEntityConverter<TObject> : JsonCreationConverter<TObject>       
    {
        protected override TObject CreateArray<TJsonType>(Type objectType, TJsonType tArray)
        {
            var deserializedObj = default(TObject);
    
            var jArray = (JArray)Convert.ChangeType(tArray, typeof(JArray));
    
            var newjArray = new JArray();
    
            foreach (var item in jArray.Children())
            {
                var itemProperties = item.Children<JProperty>();
    
                var jObj = new JObject();
                foreach (var itemProperty in itemProperties)
                {                    
                    var name = itemProperty.Name.ToModelName();  // <-- Code Below #3                                     
    
                    var newJproperty = new JProperty(name, itemProperty.Value);
                jObj.Add(newJproperty);
                }
    
                 newjArray.Add(jObj);
    
            }
    
            var sObject = Newtonsoft.Json.JsonConvert.SerializeObject(newjArray);
    
            deserializedObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TObject>(sObject);
    
            return deserializedObj;
        }
    }
    
  3. Convert the JSON Property Name property_to_map To Entity Property Names PropertyToEmpty

    public static partial class StringsExtensions
    {        
        // Changes example_id to exampleId for mapping
        public static string ToModelName(this string text)
        {
            // First we make a space
            text = text.Replace("_", " ");
    
            // Capitalize every word
            text = text.ToUpperEveryWord(); // <-- Code Below #4                    
    
            // remove the extra space
            text = text.Replace(" ", "");
    
            return text;
        }
    }
    
  4. Capitalize Every Word

    public static string ToUpperEveryWord(this string s)
    {
        // Check for empty string.  
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
    
        var words = s.Split(' ');
    
        var t = "";
        foreach (var word in words)
        {
            t += char.ToUpper(word[0]) + word.Substring(1) + ' ';
        }
    
        return t.Trim();
    }
    
  5. How I call it

    var data = Newtonsoft.Json.JsonConvert.DeserializeObject<TType>(item.ToString(), new JsonEntityConverter<TType>());
    
Demodave
  • 6,242
  • 6
  • 43
  • 58