2

I have a model with a class called "Animal".
The "Animal" class has several properties but let's focus on the following properties:

  1. CreateDate
  2. CreateUser

In the "Animal" class I can get the CreateDate to work by doing the following:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreateDate { get; set; }

This lets me generate the CreateDate in the database by setting the default value in the database as "GetDate()".
When an outside caller tries to "set" the CreateDate field on the OData service, it ignores the data being passed.
This makes it a "read only" property for outside callers.

I need to do something similar to the CreateUser except I need to set the CreateUser = System.Threading.Thread.CurrentPrincipal.Identity.Name on the OData server.

If I try a private set then the OData service does not expose the property at all.
If I try a public set then the outside caller can change the property.
In the "Animal" constructor I have set the internal _CreateUser = System.Threading.Thread.CurrentPrincipal.Identity.Name

I'm not sure how to set it on the server side.

goroth
  • 2,510
  • 5
  • 35
  • 66

2 Answers2

2

Here is what I got to work.

In the model I have the following:

public string CreateUser { get; set; }

[NotMapped]
public string CreateUserName
{
    get
    {
        return CreateUser;
    }
    set
    {
        CreateUser = CreateUser ?? System.Threading.Thread.CurrentPrincipal.Identity.Name;
    }
}

And then in the WebApiConfig I had the following:

builder.EntitySet<Animal>("Animals"));
builder.EntityType<Animal>().Ignore(p => p.CreateUser); // hide CreateUser
builder.StructuralTypes.First(t => t.ClrType == typeof(Animal))
    .AddProperty(typeof(Animal).GetProperty(nameof(Animal.CreateUserName))); // show CreateUserName
goroth
  • 2,510
  • 5
  • 35
  • 66
  • Found another way that is a little cleaner by using an interface and the context saving changes event. http://stackoverflow.com/questions/24590911/entity-framework-code-first-datetime-field-update-on-modification – goroth Apr 14 '17 at 16:28
0

You could fake it out with an empty setter. It will see the public set and generate the property in the OData entity. Not the cleanest solution but it should work.

public class Animal
{
     private string _createUser;

     public string CreateUser
     {
         get { return _createUser; }
         set { }
     }

     internal SetCreateUser(string user)
     {
         _createUser = user;
     }
}
TGRA
  • 194
  • 1
  • 5
  • Unfortunately this is does work because on the server I need to set the _createUser when the database "CreateUser" is null or the first time the model is created. – goroth Apr 01 '17 at 00:08
  • Again, not the best but you can use the internal setter method and grant InternalsVisible to the assemblies that need to set it. – TGRA Apr 13 '17 at 00:02