C# Model with EF Code First
Hello everyone, I need your knowledge to analyze the following problem.
I have a model called Test which is derived from Model Base.
As soon as I perform a PUT action on the WebApi, Created and CreatedBy are also provided with new data. However, these should only be written in the POST method.
The fields are defined in the base model and are as follows
public class BaseModel
{
[Column(Order = 0)]
[DefaultValueSql("NEWID()")]
public Guid Id { get; set; }
[Column(Order = 50)]
[DefaultValueSql("GETDATE()")]
public DateTime Modified { get; set; } = DateTime.Now;
[Column(Order = 51)]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string ModifiedBy { get; set; } = new HttpContextAccessor().HttpContext.User.Identity.Name;
[Column(Order = 52)]
[DefaultValueSql("GETDATE()")]
public DateTime Created { get; set; } = DateTime.Now;
[Column(Order = 53)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string CreatedBy { get; set; } = new HttpContextAccessor().HttpContext.User.Identity.Name;
}
9 Replies
The Test Model is looking like this
public class TestModel : BaseModel
{
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid TemplateId { get; set; }
[Column(Order = 3)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid VirtualMachineId { get; set; }
[Column(Order = 4)]
public string Status { get; set; }
[Column(Order = 5)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string JSONData { get; set; }
public TemplateModel Template { get; set; }
public VirtualMachineModel VirtualMachine { get; set; }
}
you should absolutely not be having anything related to HttpContextAccessor inside your model
EF models should not have logic in general, certainly not web related logic
we'll need to see your controller action to actually solve the problem, but i would bet you're mixing EF models and API models together so your defaults are being used when the request doesn't provide a value
ok the Controller Action für PUT is this one
[HttpPut("{Id}")]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
public IActionResult Update(Guid Id, [FromBody] EditDeploymentDataDto body)
{
if (body == null)
return BadRequest(ModelState);
if (!_deploymentInterface.CheckDeploymentById(Id))
return NotFound();
var deploymentMap = _mapper.Map<DeploymentModel>(body);
if (!ModelState.IsValid)
return BadRequest(ModelState);
if (!_deploymentInterface.UpdateDeployment(deploymentMap))
{
ModelState.AddModelError("", "Something went wrong");
return StatusCode(500, ModelState);
}
return Ok("Deployment wurde geändert");
}
This is the Repository
public bool UpdateDeployment(DeploymentModel deployment)
{
_context.Update(deployment);
return SaveChanges();
}
And this is the Interface
bool UpdateDeployment(DeploymentModel deployment);
then your mapper configuration is probably wrong
also, you shouldn't be writing repositories over EF core
and you should be using the async APIs
i'm not even sure
.Update
can be used to do a partial update of an entityI think i have to use PATCH for this
but what would be the right approach to give default values, just setting the default values on the SQL server?
When it comes to the user/owner/whatever, at the time of creation
Setting properties with simple, primitive constant default values like
2
or "hello"
is fine
Using a HTTP accessor and all that jazz, too much
Just make the property required
and set it when creating the objectI read something about interceptors would that be the right approach?
https://khalidabuhakmeh.com/entity-framework-core-5-interceptors
Khalid Abuhakmeh’s Blog
Entity Framework Core 5 Interceptors
Learn to use Entity Framework Core 5 interceptors to inspect and alter the behavior of LINQ queries. Useful for logging scenarios. C# code included.
These columns should be filled automatically so that they cannot be manipulated during PUT or POST.
So they can't be manipulated by the user or by the developer?
Because if the former, then the solution is using a DTO, as always
If the latter, then it makes no sense