CosmosSerializer 自定义 json 序列化以修剪字符串值

问题描述 投票:0回答:1

我正在尝试创建一个自定义 CosmosSerializer,它在序列化和反序列化(从 Cosmos 容器读取和写入)期间修剪属性值中的所有空格。本质上,我有一个包含 json 文档的容器,其中某些值周围有多余的空格,我想在读取文档时忽略空格,并在继续编写文档时防止任何空格进入任何值。

我创建了一个 CosmosSerializer 并将其传递到 CosmosClient 实例化中:

var cosmosClientOptions = new CosmosClientOptions
{
     ConnectionMode = ConnectionMode.Direct,
     RequestTimeout = new TimeSpan(10),
     Serializer = new CustomCosmosSerializer()
};

private readonly CosmosClient _cosmosClient = new CosmosClient(uri, key, cosmosClientOptions);
    

到目前为止我的 CosmosSerializer 如下:

public class CustomCosmosSerializer: CosmosSerializer
{
    private readonly Newtonsoft.Json.JsonSerializer _serializer = new();

    public override T FromStream<T>(Stream stream)
    {
        //go from stream to object of type T
        //trim all excess whitespace of all string property values along the way
        return _serializer.Deserialize<T>(new JsonTextReader(new StreamReader(stream)));
    
    }

    public override Stream ToStream<T>(T input)
    {
        //go from object to stream
        //trim all excess whitespace of all string property values along the way
    
        using var stringWriter = new StringWriter();
        using var jsonTextWriter = new JsonTextWriter(stringWriter);
        _serializer.Serialize(jsonTextWriter, input, input.GetType());

        return new MemoryStream(Encoding.UTF8.GetBytes(stringWriter.ToString()));
    }
}

但是,我不确定在序列化/反序列化期间应用所需的空白修剪的最高效策略。我尝试过利用反射来获取和分析属性值,但我担心性能并且对更好的策略感到好奇。谢谢!

c# json json.net azure-cosmosdb
1个回答
0
投票

根据此 MSDOC,您可以使用

.Trim
方法来修剪字符串值。

我在下面的代码中使用了这种方法来修剪字符串值。它用于在字符串属性的 JSON 序列化和反序列化期间修剪空格。我在下面的代码中使用了

ReadJson
方法,该方法在反序列化期间修剪空格。

我插入了一些由 IdNameDept 组成的示例项目,其中 NameDept 由空格组成,使用

.Trim()
方法将其删除,如下面的代码所示。

我尝试过的代码:

public class TrimmingConverter : JsonConverter
{
    public override bool CanRead => true;
    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => objectType == typeof(string);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return ((string)reader.Value)?.Trim();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public class Person
{
    [JsonProperty("id")] 
    [JsonConverter(typeof(TrimmingConverter))]
    public string Id { get; set; }

    [JsonProperty("name")]
    [JsonConverter(typeof(TrimmingConverter))]
    public string Name { get; set; }

    [JsonProperty("dept")]
    [JsonConverter(typeof(TrimmingConverter))]
    public string Dept { get; set; }
}

class Program
{
    static async Task Main()
    {
        string endpointUrl = "****";
        string authorizationKey = "****";
        string databaseId = "newdb";
        string containerId = "thirdCont";

        CosmosClient client = new CosmosClient(endpointUrl, authorizationKey);
        Container container = client.GetContainer(databaseId, containerId);
 
        var sampdata = "{ ""id"": ""1"", ""name"":"" Balaji "", ""dept"":"" IT "" }";
        var prsn = JsonConvert.DeserializeObject<Person>(sampdata);
 
        await StorePersonData(container, prsn);
        Console.WriteLine("Data has been stored successfully!");
    }

    static async Task StorePersonData(Container container, Person person)
    {
        person.Id = person.Id?.Trim();
        person.Name = person.Name?.Trim();
        person.Dept = person.Dept?.Trim();

        var sampdata = JsonConvert.SerializeObject(person, Formatting.None, new TrimmingConverter());        
        var trimmedPerson = JsonConvert.DeserializeObject<Person>(sampdata);       
        await container.CreateItemAsync(trimmedPerson, new PartitionKey(trimmedPerson.Id));
    }
}

输出: 在控制台中:

Data has been stored successfully!

在 Azure Cosmos DB 容器中:

{
    "id": "1",
    "name": "Balaji",
    "dept": "IT"
}

这里 namedept 键的值没有任何空格。

© www.soinside.com 2019 - 2024. All rights reserved.