两年前,我使用 Node Express 和 Postgresql 为 Angular 前端网站编写了 ASP.NET Core 8.0 Web API,我们与前端程序员和我的 Web API 一起从该项目中养成了习惯。我在数据库中提供了一些我从未涉及过的列,前端使用该列来保存其类型的设置。我使用 Dapper 是因为我喜欢掌握 SQL 而不是 EF Core。
现在我们正在使用 Angular 的 ASP.NET Core 8 Web API 编写一个新项目,但我在 json 列方面遇到问题。
让我们举个例子吧
数据库:
create table users
(
user_id bigserial,
username character varying[50],
fullname character varying[200],
password character varying[300],
salt character varying[300],
frontends_field jsonb,
adress_data jsonb
)
public class User
{
[Required]
public long? User_Id { get; set; }
[Required]
[MaxLength(50)]
public string UserName { get; set; } = string.Empty;
[Required]
[MaxLength(200)]
public string FullName { get; set; } = string.Empty;
[Required]
[MaxLength(300)]
public string Password { get; set; } = string.Empty;
[MaxLength(300)]
public string Salt { get; set; } = string.Empty;
public ??WHICH_TYPE?? frontends_field { get; set; }
public ??WHICH_TYPE?? adress_data { get; set; }
}
public class Adress_Data
{
public string? adress_name { get; set; }
public string? streetinfo { get; set; }
public string? buildinginfo { get; set; }
public string? city { get; set; }
}
在控制器中,我像这样保存这些数据
[HttpPost]
public async Task<ActionResult<User>> PostUser([FromBody] User req)
{
try
{
using var MyCnt = _db.GetConnection(); //Npgsqlconnection here
{
string MySql = """
INSERT INTO public.users (username, fullname, password, salt, frontends_field, adress_data)
VALUES (@username, @fullname, @password, @salt, @frontends_field, @adress_data)
returning *;
""";
var result = await MyCnt.QueryFirstOrDefaultAsync<User>(MySql,req);
return Ok(result);
}
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
请求的 JSON 示例
{
"username" : "{username}",
"fullname" : "John DOE",
"password" : "{password}",
"salt" "asdşfmi<sdmfpwefkpüpowefi",
"frontends_field" :
{ "somenumfield" : 15,
"sometextfield" : "Cry me a river"
},
"adress_data" :
{
"adress_name" : "home",
"streetinfo" : "Susame Streeet No:21",
"buildinginfo" : "A Block",
"city" : "IZMIR"
}
}
我真的被代码的 JSON 端困住了......
谢谢大家
您可以尝试使用
JsonDocument
命名空间中的 JsonElement
或 System.Text.Json
类型来表示通用 JSON 字段,或者您也可以为结构化 JSON 字段创建自定义类。
以下是您可以参考的示例代码:
用户.cs:
using System.Text.Json;
namespace webapitest.Models
{
public class User
{
public long? User_Id { get; set; }
public string UserName { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string Salt { get; set; } = string.Empty;
public JsonDocument Frontends_Field { get; set; }
public AddressData Adress_Data { get; set; }
}
}
地址数据.cs:
namespace webapitest.Models
{
public class AddressData
{
public string? Adress_Name { get; set; }
public string? StreetInfo { get; set; }
public string? BuildingInfo { get; set; }
public string? City { get; set; }
}
}
UsersController.cs
using Dapper;
using Microsoft.AspNetCore.Mvc;
using Npgsql;
using System.Text.Json;
using webapitest.Models;
namespace webapitest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly NpgsqlConnection _dbConnection;
public UsersController(NpgsqlConnection dbConnection)
{
_dbConnection = dbConnection;
}
[HttpPost]
public async Task<ActionResult<User>> PostUser([FromBody] User req)
{
try
{
string sql = @"
INSERT INTO public.users (username, fullname, password, salt, frontends_field, adress_data)
VALUES (@UserName, @FullName, @Password, @Salt, @Frontends_Field::jsonb, @Adress_Data::jsonb)
RETURNING *;
";
var parameters = new
{
req.UserName,
req.FullName,
req.Password,
req.Salt,
Frontends_Field = req.Frontends_Field.RootElement.ToString(),
Adress_Data = JsonSerializer.Serialize(req.Adress_Data)
};
var result = await _dbConnection.QueryFirstOrDefaultAsync(sql, parameters);
var user = MapUser(result);
return Ok(user);
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
private static User MapUser(dynamic record)
{
return new User
{
User_Id = record.user_id,
UserName = record.username,
FullName = record.fullname,
Password = record.password,
Salt = record.salt,
Frontends_Field = JsonDocument.Parse((string)record.frontends_field),
Adress_Data = JsonSerializer.Deserialize<AddressData>((string)record.adress_data)
};
}
}
}
样品要求:
{
"username" : "",
"fullname" : "John DOE",
"password" : "",
"salt": "asdşfmi<sdmfpwefkpüpowefi",
"frontends_field" :
{
"somenumfield" : 15,
"sometextfield" : "Cry me a river"
},
"adress_data" :
{
"adress_name" : "home",
"streetinfo" : "Susame Street No:21",
"buildinginfo" : "A Block",
"city" : "IZMIR"
}
}