I am using .NET 6, ASP.NET Core Web API 6.
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());
});
// ...
}
}