I have the following Entities and DTOs:
public class Endpoint
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Port { get; set; }
public bool IsHttps { get; set; }
public int? CertificateID { get; set; }
public Certificate? Certificate { get; set; }
}
public class Certificate
{
public int ID { get; set; }
public string Name { get; set; }
public string FileName { get; set; }
}
public class EndpointDTO
{
public int Port { get; set; }
public bool IsHttps { get; set; }
public string? CertificateName { get; set; }
}
Because an Endpoint could be using HTTP, the Certificate is optional. The Certificate.Name
property has a unique index. I am now trying to make the scaffolded CRUD Razor Pages work with my EndpointDTO using Automapper. The Delete and Details page work as expected. For the create Page, my implementation looks like this:
[BindProperty]
public EndpointDTO Endpoint { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!this.ModelState.IsValid)
{
return this.Page();
}
var endpoint = this.mapper.Map<Endpoint>(this.Endpoint);
endpoint.Certificate = this.context.Certificates
.FirstOrDefault(c => c.Name.Equals(this.Endpoint.CertificateName));
this.context.Endpoints.Add(endpoint);
await this.context.SaveChangesAsync();
return this.RedirectToPage("./Index");
}
This works too, but it feels wrong that I have to manually select the Certificate. The Edit Page does not work. When I try to "unselect" a certificate (pass null
as the EndpointDTO.CertificateName
), the mapper creates a Certificate with default (null) values. Here is my implementation:
public async Task<IActionResult> OnPostAsync()
{
if (!this.ModelState.IsValid)
{
return this.Page();
}
var original = this.context.Endpoints
.Include(e => e.Certificate)
.FirstOrDefault(e => e.Port == this.Endpoint.Port);
original!.Certificate = this.context.Certificates
.FirstOrDefault(c => c.Name.Equals(this.Endpoint.CertificateName));
this.mapper.Map(this.Endpoint, original);
await this.context.SaveChangesAsync();
return this.RedirectToPage("./Index");
}
The error that i receive is
SQLite Error 19: 'NOT NULL constraint failed: Certificates.FileName'
Is this an Automapper configuration issue? I currently use ...CreateMap<Endpoint, EndpointDTO>().ReverseMap();
.
Or do I need to manually catch the case, where a Certificate was "unselected"? How would I go about doing that cleanly?
Because your map is not know your entity property. Reason of the they have different property name. You should set manual. Look ForMember in AutoMapper
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.