Home > Software design >  System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' insta
System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' insta

Time:10-30

I am using .NET 6, ASP.NET Core Web API 6.

enter image description here

db PostgreSQL 15.

DROP TABLE IF EXISTS account_object;
CREATE TABLE account_object
(
    id                             uuid DEFAULT uuid_generate_v4 () primary key,
    account_object_code            character varying(64) unique not null,
    account_object_name            character varying(512),
    gender                         smallint,
    birth_date                     date,
    birth_place                    character varying(256),
    agreement_salary               numeric(10),
    salary_coefficient             numeric(5, 2),
    number_of_dependent            smallint,
    insurance_salary               numeric(10),
    bank_account                   character varying(64),
    bank_name                      character varying(128),
    address                        character varying(256),
    account_object_group_list      character varying(512),
    account_object_group_list_code character varying(512),
    company_tax_code               character varying(64),
    tel                            character varying(32),
    mobile                         character varying(32),
    fax                            character varying(32),
    email_address                  character varying(128),
    website                        character varying(128),
    payment_term_id                character varying(36),
    max_debt_amount                numeric(18, 2),
    due_time                       smallint,
    identification_number          character varying(64),
    issue_date                     date,
    issue_by                       character varying(128),
    country                        character varying(128),
    province_or_city               character varying(128),
    district                       character varying(128),
    ward_or_commune                character varying(128),
    account_object_prefix          character varying(64),
    contact_name                   character varying(128),
    contact_title                  character varying(128),
    contact_mobile                 character varying(32),
    other_contact_mobile           character varying(32),
    contact_fixed_tel              character varying(64),
    contact_email                  character varying(128),
    contact_address                character varying(256),
    is_vendor                      boolean                      not null,
    is_customer                    boolean                      not null,
    is_employee                    boolean                      not null,
    is_organization_entity         boolean                      not null,
    active_status                  boolean                      not null,
    organization_unit_id           character varying(36),
    branch_id                      character varying(36),
    created                        timestamp with time zone     not null,
    created_by                     character varying(128),
    modified                       timestamp with time zone,
    modified_by                    character varying(64),
    receivable_debt_amount         numeric(18, 2),
    shipping_address               character varying(256),
    account_object_group_list_name character varying(512),
    employee_id                    character varying(36),
    description                    character varying(256),
    bank_branch_name               character varying(256),
    bank_province_or_city          character varying(128),
    legal_representative           character varying(128),
    e_invoice_contact_name         character varying(256),
    e_invoice_contact_email        character varying(256),
    e_invoice_contact_address      character varying(256),
    e_invoice_contact_mobile       character varying(20),
    employee_type                  smallint,
    tenant_id                      character varying(36)
);
CREATE INDEX account_object_idx ON account_object (id);
CREATE INDEX account_object_idx2 ON account_object (tenant_id);

COMMENT ON TABLE public.account_object IS 'Khách hàng, nhà cung cấp, nhân viên';
COMMENT ON COLUMN public.account_object.id IS 'PK Đối tượng';
COMMENT ON COLUMN public.account_object.account_object_code IS 'Mã đối tượng';
COMMENT ON COLUMN public.account_object.account_object_name IS 'Tên đối tượng';
COMMENT ON COLUMN public.account_object.gender IS 'Giới tính';
COMMENT ON COLUMN public.account_object.birth_date IS 'Ngày sinh';
COMMENT ON COLUMN public.account_object.birth_place IS 'Nơi sinh';
COMMENT ON COLUMN public.account_object.agreement_salary IS 'Lương thỏa thuận';
COMMENT ON COLUMN public.account_object.salary_coefficient IS 'Hệ số lương';
COMMENT ON COLUMN public.account_object.number_of_dependent IS 'Số người phụ thuộc';
COMMENT ON COLUMN public.account_object.insurance_salary IS 'Lương đóng bảo hiểm';
COMMENT ON COLUMN public.account_object.bank_account IS 'Tài khoản ngân hàng (Là số TK cá nhân nếu là nhân viên)';
COMMENT ON COLUMN public.account_object.bank_name IS 'Tên ngân hàng';
COMMENT ON COLUMN public.account_object.address IS 'Địa chỉ của đối tượng';
COMMENT ON COLUMN public.account_object.account_object_group_list IS 'Lưu internal_code_id của nhóm KH, NCC được chọn, cách nhau bởi dấu ;';
COMMENT ON COLUMN public.account_object.account_object_group_list_code IS 'Lưu AccountObjectGroupCode của các nhóm KH, NCC được chọn, cách nhau bởi dấu ;';
COMMENT ON COLUMN public.account_object.company_tax_code IS 'Mã số thuế';
COMMENT ON COLUMN public.account_object.tel IS 'Số điện thoại cố định';
COMMENT ON COLUMN public.account_object.mobile IS 'Số điện thoại di động';
COMMENT ON COLUMN public.account_object.fax IS 'Fax';
COMMENT ON COLUMN public.account_object.email_address IS 'Địa chỉ Email của tổ chức';
COMMENT ON COLUMN public.account_object.website IS 'Website';
COMMENT ON COLUMN public.account_object.payment_term_id IS 'Điều khoản thanh toán';
COMMENT ON COLUMN public.account_object.max_debt_amount IS 'Số nợ tối đa';
COMMENT ON COLUMN public.account_object.due_time IS 'Hạn nợ ( Số ngày)';
COMMENT ON COLUMN public.account_object.identification_number IS 'Số CMTND của người liên hệ';
COMMENT ON COLUMN public.account_object.issue_date IS 'Ngày cấp CMTND người liên hệ';
COMMENT ON COLUMN public.account_object.issue_by IS 'Nơi cấp CMTND người liên hệ';
COMMENT ON COLUMN public.account_object.country IS 'Quốc gia';
COMMENT ON COLUMN public.account_object.province_or_city IS 'Tỉnh/ Thành phố';
COMMENT ON COLUMN public.account_object.district IS 'Quận/ Huyện';
COMMENT ON COLUMN public.account_object.ward_or_commune IS 'Phường/Xã';
COMMENT ON COLUMN public.account_object.account_object_prefix IS 'Xưng hô';
COMMENT ON COLUMN public.account_object.contact_name IS 'Tên người liên hệ';
COMMENT ON COLUMN public.account_object.contact_title IS 'Chức vụ người liên hệ (Nếu đối tượng là nhân viên thì đây chính là chức vụ mặc định của nhân viên đó)';
COMMENT ON COLUMN public.account_object.contact_mobile IS 'Số điện thoại di động của người liên hệ';
COMMENT ON COLUMN public.account_object.contact_fixed_tel IS 'Điện thoại cố định người liên hệ';
COMMENT ON COLUMN public.account_object.contact_email IS 'Email người liên hệ';
COMMENT ON COLUMN public.account_object.is_vendor IS 'Là nhà cung cấp';
COMMENT ON COLUMN public.account_object.is_customer IS 'Là khách hàng';
COMMENT ON COLUMN public.account_object.is_employee IS 'Là cán bộ nhân viên';
COMMENT ON COLUMN public.account_object.is_organization_entity IS 'Là tổ chức';
COMMENT ON COLUMN public.account_object.active_status IS 'Trạng thái theo dõi';
COMMENT ON COLUMN public.account_object.organization_unit_id IS 'Đơn vị của nhân viên';
COMMENT ON COLUMN public.account_object.branch_id IS 'Chi nhánh';
COMMENT ON COLUMN public.account_object.bank_branch_name IS 'Chi nhánh tài khoản ngân hàng)';
COMMENT ON COLUMN public.account_object.bank_province_or_city IS 'Tỉnh/Thành phố nơi mở tài khoản ngân hàng';
COMMIT;

Model

using System;
using System.Collections.Generic;

namespace acc.Models
{
    /// <summary>
    /// Khách hàng, nhà cung cấp, nhân viên
    /// </summary>
    public partial class AccountObject
    {
        /// <summary>
        /// PK Đối tượng
        /// </summary>
        public Guid Id { get; set; }
        /// <summary>
        /// Mã đối tượng
        /// </summary>
        public string AccountObjectCode { get; set; } = null!;
        /// <summary>
        /// Tên đối tượng
        /// </summary>
        public string? AccountObjectName { get; set; }
        /// <summary>
        /// Giới tính
        /// </summary>
        public short? Gender { get; set; }
        /// <summary>
        /// Ngày sinh
        /// </summary>
        public DateOnly? BirthDate { get; set; }
        /// <summary>
        /// Nơi sinh
        /// </summary>
        public string? BirthPlace { get; set; }
        /// <summary>
        /// Lương thỏa thuận
        /// </summary>
        public decimal? AgreementSalary { get; set; }
        /// <summary>
        /// Hệ số lương
        /// </summary>
        public decimal? SalaryCoefficient { get; set; }
        /// <summary>
        /// Số người phụ thuộc
        /// </summary>
        public short? NumberOfDependent { get; set; }
        /// <summary>
        /// Lương đóng bảo hiểm
        /// </summary>
        public decimal? InsuranceSalary { get; set; }
        /// <summary>
        /// Tài khoản ngân hàng (Là số TK cá nhân nếu là nhân viên)
        /// </summary>
        public string? BankAccount { get; set; }
        /// <summary>
        /// Tên ngân hàng
        /// </summary>
        public string? BankName { get; set; }
        /// <summary>
        /// Địa chỉ của đối tượng
        /// </summary>
        public string? Address { get; set; }
        /// <summary>
        /// Lưu internal_code_id của nhóm KH, NCC được chọn, cách nhau bởi dấu ;
        /// </summary>
        public string? AccountObjectGroupList { get; set; }
        /// <summary>
        /// Lưu AccountObjectGroupCode của các nhóm KH, NCC được chọn, cách nhau bởi dấu ;
        /// </summary>
        public string? AccountObjectGroupListCode { get; set; }
        /// <summary>
        /// Mã số thuế
        /// </summary>
        public string? CompanyTaxCode { get; set; }
        /// <summary>
        /// Số điện thoại cố định
        /// </summary>
        public string? Tel { get; set; }
        /// <summary>
        /// Số điện thoại di động
        /// </summary>
        public string? Mobile { get; set; }
        /// <summary>
        /// Fax
        /// </summary>
        public string? Fax { get; set; }
        /// <summary>
        /// Địa chỉ Email của tổ chức
        /// </summary>
        public string? EmailAddress { get; set; }
        /// <summary>
        /// Website
        /// </summary>
        public string? Website { get; set; }
        /// <summary>
        /// Điều khoản thanh toán
        /// </summary>
        public string? PaymentTermId { get; set; }
        /// <summary>
        /// Số nợ tối đa
        /// </summary>
        public decimal? MaxDebtAmount { get; set; }
        /// <summary>
        /// Hạn nợ ( Số ngày)
        /// </summary>
        public short? DueTime { get; set; }
        /// <summary>
        /// Số CMTND của người liên hệ
        /// </summary>
        public string? IdentificationNumber { get; set; }
        /// <summary>
        /// Ngày cấp CMTND người liên hệ
        /// </summary>
        public DateOnly? IssueDate { get; set; }
        /// <summary>
        /// Nơi cấp CMTND người liên hệ
        /// </summary>
        public string? IssueBy { get; set; }
        /// <summary>
        /// Quốc gia
        /// </summary>
        public string? Country { get; set; }
        /// <summary>
        /// Tỉnh/ Thành phố
        /// </summary>
        public string? ProvinceOrCity { get; set; }
        /// <summary>
        /// Quận/ Huyện
        /// </summary>
        public string? District { get; set; }
        /// <summary>
        /// Phường/Xã
        /// </summary>
        public string? WardOrCommune { get; set; }
        /// <summary>
        /// Xưng hô
        /// </summary>
        public string? AccountObjectPrefix { get; set; }
        /// <summary>
        /// Tên người liên hệ
        /// </summary>
        public string? ContactName { get; set; }
        /// <summary>
        /// Chức vụ người liên hệ (Nếu đối tượng là nhân viên thì đây chính là chức vụ mặc định của nhân viên đó)
        /// </summary>
        public string? ContactTitle { get; set; }
        /// <summary>
        /// Số điện thoại di động của người liên hệ
        /// </summary>
        public string? ContactMobile { get; set; }
        public string? OtherContactMobile { get; set; }
        /// <summary>
        /// Điện thoại cố định người liên hệ
        /// </summary>
        public string? ContactFixedTel { get; set; }
        /// <summary>
        /// Email người liên hệ
        /// </summary>
        public string? ContactEmail { get; set; }
        public string? ContactAddress { get; set; }
        /// <summary>
        /// Là nhà cung cấp
        /// </summary>
        public bool IsVendor { get; set; }
        /// <summary>
        /// Là khách hàng
        /// </summary>
        public bool IsCustomer { get; set; }
        /// <summary>
        /// Là cán bộ nhân viên
        /// </summary>
        public bool IsEmployee { get; set; }
        /// <summary>
        /// Là tổ chức
        /// </summary>
        public bool IsOrganizationEntity { get; set; }
        /// <summary>
        /// Trạng thái theo dõi
        /// </summary>
        public bool ActiveStatus { get; set; }
        /// <summary>
        /// Đơn vị của nhân viên
        /// </summary>
        public string? OrganizationUnitId { get; set; }
        /// <summary>
        /// Chi nhánh
        /// </summary>
        public string? BranchId { get; set; }
        public DateTime Created { get; set; }
        public string? CreatedBy { get; set; }
        public DateTime? Modified { get; set; }
        public string? ModifiedBy { get; set; }
        public decimal? ReceivableDebtAmount { get; set; }
        public string? ShippingAddress { get; set; }
        public string? AccountObjectGroupListName { get; set; }
        public string? EmployeeId { get; set; }
        public string? Description { get; set; }
        /// <summary>
        /// Chi nhánh tài khoản ngân hàng)
        /// </summary>
        public string? BankBranchName { get; set; }
        /// <summary>
        /// Tỉnh/Thành phố nơi mở tài khoản ngân hàng
        /// </summary>
        public string? BankProvinceOrCity { get; set; }
        public string? LegalRepresentative { get; set; }
        public string? EInvoiceContactName { get; set; }
        public string? EInvoiceContactEmail { get; set; }
        public string? EInvoiceContactAddress { get; set; }
        public string? EInvoiceContactMobile { get; set; }
        public short? EmployeeType { get; set; }
        public string? TenantId { get; set; }
    }
}

controller

using acc.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace acc.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountObjectController : ControllerBase
    {
        private readonly ILogger<AccountObjectController> _logger;
        private readonly acc200Context _db;

        public AccountObjectController(ILogger<AccountObjectController> logger, acc200Context acc200Context)
        {
            _logger = logger;
            _db = acc200Context;
        }

        [HttpGet("{tenant_id}")]
        public IEnumerable<AccountObject> Get(string tenant_id)
        {
            return _db.AccountObjects.Where(x => x.TenantId == tenant_id).ToArray();
        }

    }
}

Error

System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' instances are not supported. The unsupported member type is located on type 'System.Nullable`1[System.DateOnly]'. Path: $.BirthDate.
 ---> System.NotSupportedException: Serialization and deserialization of 'System.DateOnly' instances are not supported.
   at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
   at System.Text.Json.Serialization.Converters.NullableConverter`1.Write(Utf8JsonWriter writer, Nullable`1 value, JsonSerializerOptions options)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.ArrayConverter`2.OnWriteResume(Utf8JsonWriter writer, TElement[] array, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& state, NotSupportedException ex)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore[TValue](JsonConverter jsonConverter, Utf8JsonWriter writer, TValue& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at System.Text.Json.JsonSerializer.WriteStreamAsync[TValue](Stream utf8Json, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: text/plain
Host: localhost:7283
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
:method: GET
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,vi-VN;q=0.8,vi;q=0.7
Referer: https://localhost:7283/swagger/index.html
sec-ch-ua: "Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
DNT: 1
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty

Image https://i.imgur.com/tb8uj13.png

How to fix?

CodePudding user response:

Yes, DateOnly and TimeOnly serialization is not supported right now. There is a workaround

public sealed class DateOnlyJsonConverter : JsonConverter<DateOnly>
{
    public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateOnly.FromDateTime(reader.GetDateTime());
    }

    public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
    {
        var isoDate = value.ToString("O");
        writer.WriteStringValue(isoDate);
    }
}

And ensure you added new converter

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      services.AddControllers()
            .AddJsonOptions(options =>
            {
               options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
            });

      // ...
   }
}
  • Related