Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WriteJson: Object reference not set to an instance of an object. #35530

Open
douglasg14b opened this issue Jan 25, 2025 · 0 comments
Open

WriteJson: Object reference not set to an instance of an object. #35530

douglasg14b opened this issue Jan 25, 2025 · 0 comments

Comments

@douglasg14b
Copy link

douglasg14b commented Jan 25, 2025

Bug description

Small model, trying to add a new entity. EF Core odly enough throws a null ref exception.

The last stack frame is at:

            if (value is not null)
            {
                var jsonValueReaderWriter = property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter;
                Check.DebugAssert(jsonValueReaderWriter is not null, "Missing JsonValueReaderWriter on JSON property");
                jsonValueReaderWriter.ToJson(writer, value);
            }

The result of property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter; is null for a dictionary?

Image

Your code

builder.Services.AddDbContext<AppDbContext>(options =>
            options.UseNpgsql(appConfig.ConnectionString)
        );



var entity = new ReqResEntity(enrichedData);
db.ReqResData.Add(entity);
await db.SaveChangesAsync();





public class AppDbContext : DbContext
{
    public DbSet<ReqResEntity> ReqResData { get; set; }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ReqResEntity>()
            .OwnsOne(x => x.RequestUrl, model => model.ToJson())
            .OwnsOne(x => x.SourceUrl, model => model.ToJson())
            .OwnsOne(x => x.Response, model => model.ToJson())
            .OwnsOne(x => x.Request, model => model.ToJson());
    }
}




public class ReqResEntity
{
    public int Id { get; set; }

    public DateTimeOffset TimeStamp { get; set; }

    public UrlDetailsEntity SourceUrl { get; set; }
    public UrlDetailsEntity RequestUrl { get; set; }
    public RequestEntity? Request { get; set; }
    public ResponseEntity? Response { get; set; }

    public string Agent { get; set; }
    public string Protocol { get; set; }
    public string HttpMethod { get; set; }
    public string? StatusCode { get; set; }


    private ReqResEntity() { }

    public ReqResEntity(EnrichedReqResData data)
    {
        TimeStamp = data.TimeStamp;
        SourceUrl = new UrlDetailsEntity(data.SourceUrl);
        RequestUrl = new UrlDetailsEntity(data.RequestUrl);
        Request = new RequestEntity(data.Request);
        Response = data.Response != null ? new ResponseEntity(data.Response) : null;
        Agent = data.Agent;
        Protocol = data.Protocol;
        HttpMethod = data.Request.HttpMethod;
        StatusCode = data.Response?.StatusCode.ToString() ?? null;
    }
}

public class UrlDetailsEntity
{
    public string Url { get; set; }
    public string Fqdn { get; set; }
    public string Tld { get; set; }
    public string Domain { get; set; }
    public string SubDomain { get; set; }

    public string Path { get; set; }
    public string Query { get; set; }

    private UrlDetailsEntity() { }

    public UrlDetailsEntity(UrlDetails urlDetails)
    {
        Url = urlDetails.Url;
        Fqdn = urlDetails.Fqdn;
        Tld = urlDetails.Tld;
        Domain = urlDetails.Domain;
        SubDomain = urlDetails.SubDomain;
        Path = urlDetails.Path;
        Query = urlDetails.Query;
    }
}

public class RequestEntity
{
    public DateTimeOffset TimeStamp { get; set; }
    public Dictionary<string, string> Headers { get; set; }
    public bool IsComplete { get; set; }
    public string? ContentType { get; set; }

    public int BodySize { get; set; }

    private RequestEntity() { }

    public RequestEntity(EnrichedRequest request)
    {
        TimeStamp = request.TimeStamp;
        Headers = request.Headers;
        IsComplete = request.IsComplete;
        ContentType = request.ContentType;

        BodySize = Encoding.Unicode.GetByteCount(request.Body);
    }
}

public class ResponseEntity
{
    public DateTimeOffset TimeStamp { get; set; }
    public string Reason { get; set; }
    public Dictionary<string, string> Headers { get; set; }
    public bool IsComplete { get; set; }
    public string? ContentType { get; set; }

    public int BodySize { get; set; }

    private ResponseEntity() { }

    public ResponseEntity(EnrichedResponse response)
    {
        TimeStamp = response.TimeStamp;
        Reason = response.Reason;
        Headers = response.Headers;
        IsComplete = response.IsComplete;
        ContentType = response.ContentType;

        BodySize = Encoding.Unicode.GetByteCount(response.Body);
    }
}

Stack traces

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.WriteJson(Utf8JsonWriter writer, Object navigationValue, IUpdateEntry parentEntry, IEntityType entityType, Nullable`1 ordinal, Boolean isCollection, Boolean isTopLevel)
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.<GenerateColumnModifications>g__HandleJson|41_4(List`1 columnModifications, <>c__DisplayClass41_0&)
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.GenerateColumnModifications()
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.<>c.<get_ColumnModifications>b__33_0(ModificationCommand command)
   at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Update.ModificationCommand.get_ColumnModifications()
   at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlUpdateSqlGenerator.AppendInsertOperation(StringBuilder commandStringBuilder, IReadOnlyModificationCommand command, Int32 commandPosition, Boolean overridingSystemValue, Boolean& requiresTransaction)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlUpdateSqlGenerator.AppendInsertOperation(StringBuilder commandStringBuilder, IReadOnlyModificationCommand command, Int32 commandPosition, Boolean& requiresTransaction)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.AddCommand(IReadOnlyModificationCommand modificationCommand)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.TryAddCommand(IReadOnlyModificationCommand modificationCommand)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateCommandBatches(IEnumerable`1 commandSet, Boolean moreCommandSets, Boolean assertColumnModification, ParameterNameGenerator parameterNameGenerator)+MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList`1 entries, IUpdateAdapter updateAdapter)+MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChangesAsync(IList`1 entries, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Webbler.Web.WebApp.<>c.<<Build>b__0_1>d.MoveNext()

Verbose output


EF Core version

9.0.1

Database provider

Npgsql.EntityFrameworkCore.PostgreSQL

Target framework

.NET 9

Operating system

Windows 10

IDE

Rider

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant