Search code examples
c#asp.net-web-apientity-framework-6dbgeography

Can you read additional data strings from Web API POST which are not in the data model?


In Entity Framework I have a DBGeography object:

using System.Data.Entity.Spatial;
...
public DbGeography Location { get; set; }

As I haven't discovered a better way to send a POINT object over JSON, I'm intending to send 'lat' and 'lng' string values from my Javascript code and use them on the server during the POST method:

Screenshot from POSTMan REST client

public async Task<IHttpActionResult> PostI4Item(myEntity item)
        {
          var lat = (VALUE TO BE SOURCED);
          var lng = (VALUE TO BE SOURCED);
          string Point = String.Format("POINT({0} {1})", lat, lng);
          item.Location = DbGeography.PointFromText(Point, 4326);
          myEntity current = await InsertAsync(item);
          return CreatedAtRoute("Tables", new { id = current.Id }, current);
        }

The problem is I don't know how to retrieve values sent to POST that are not expected within the data model. item.Location is accessible because it has been declared. But, even if I am sending extra key/value pairs in the body of 'lat' and 'lng', how can I discover those values in code? I can't use item.lat and item.lng as they are not declared, and I don't want extra DB columns for those values... I only want them accepted as input, but not saved.

Is there a method in the data model where I can declare a value (perhaps something read-only or internal) which is expected on the request and available for use within the POST method, but is not actually being saved to my database?


Solution

  • This post https://stackoverflow.com/a/35982194/3026149 from Mohamed Badr & Niels R, and this post https://stackoverflow.com/a/18215561/3026149 from haim770 are what have solved my problem.

    I was unaware that there was a [NotMapped] attribute available for my data model, meaning I could expect values of lat & lng without having them create database columns in Entity Framework.

    So my class becomes:

    using System.Data.Entity.Spatial;
    using System.ComponentModel.DataAnnotations.Schema;
    ...
    public DbGeography Location { get; set; }
    [NotMapped]
    public double lng { get; set; }
    [NotMapped]
    public double lat { get; set; }
    

    And my code becomes:

    public async Task<IHttpActionResult> PostI4Item(myEntity item)
            {
              var Point = DbGeography.FromText($"POINT({item.lng} {item.lat})");
              item.Location = Point;
              myEntity current = await InsertAsync(item);
              return CreatedAtRoute("Tables", new { id = current.Id }, current);
            }