繁体   English   中英

在发布到 api 端点的 CosmosDB 中存储任意 json

[英]Store arbitrary json in CosmosDB posted into api endpoint

我正在尝试将任意 json 保存到 CosmosDb

我说是因为 json 的开头会有一些已知的属性。 例如:

{
    "id": "88e37e40-fd7e-478e-9ac5-140601fcddad",
    "type": "http",
    "name": "request1",
    "body": {
        "property1" : 1,
        "otherProperty": "foo"
    }
}

如您所见, body是任意部分。

idtypename用于演示目的,但我们可能需要验证这些属性。

这就是我正在尝试的

app.MapPost
(
    "/", async (HttpRequest httpRequest, Container db) =>
    {
        var postedRequest = await httpRequest
            .ReadFromJsonAsync<Request>();

        var id = postedRequest.id;
        var type = postedRequest.type;

        var savedItem = await db.CreateItemAsync(postedRequest, new PartitionKey(type));

        return Results.Created($"/requests/{type}/{id}", savedItem.Resource);
    }
);

public record Request(string id, string type, string name, dynamic body);

我的问题是当我在这个问题的顶部发布示例 json 时,它会像这样持续存在:

{
    "id": "88e37e40-fd7e-478e-9ac5-140601fcddad",
    "type": "http",
    "name": "request1"
    "body": {
        "ValueKind": 1
    },

    "_rid": "WxgaAN+DhzoBAAAAAAAAAA==",
    "_self": "dbs/WxgaAA==/colls/WxgaAN+Dhzo=/docs/WxgaAN+DhzoBAAAAAAAAAA==/",
    "_etag": "\"00000000-0000-0000-96ae-5ccf928801d8\"",
    "_attachments": "attachments/",
    "_ts": 1657712863
}

它使用 ValueKind 代替任意 json。 我相信这是因为框架如何反序列化它,可能是因为我使用了dynamic

还有其他类型应该使用吗? 或者也许首先将 HttpRequest 主体反序列化为流,然后探测我有兴趣验证它们的属性? 使用 Utf8JsonReader? 我不知道从这里去哪里。


这是我的完整代码

using Microsoft.Azure.Cosmos;
using CosmosClient client = new("<connectionstring>");
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "testing"
);
Container container = await database.CreateContainerIfNotExistsAsync(
    id: "requests",
    partitionKeyPath: "/type",
    throughput: 400
);

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<Container>(container);

var app = builder.Build();

app.MapGet("/", () => "Started");

app.MapPost
(
    "/", async (HttpRequest httpRequest, Container db) =>
    {
        var postedRequest = await httpRequest
            .ReadFromJsonAsync<Request>();

        var id = postedRequest.id;
        var type = postedRequest.type;

        var savedItem = await db.CreateItemAsync(postedRequest, new PartitionKey(type));

        return Results.Created($"/requests/{type}/{id}", savedItem.Resource);
    }
);

app.MapGet
(
    "/requests/{type}/{id}", (Container db, string type, string id) =>
    {
        var dbResult = db.ReadItemAsync<Request>(id, new PartitionKey(type));

        return Results.Ok(dbResult);
    }
);

app.Run();

public record Request(string id, string type, string name, dynamic body);

如果您知道分区键(例如,它在 url 中),那么使用 Stream API 会更简单。 示例: https ://github.com/ealsur/ondotnet-cosmosdb/tree/master/src/episode1/streams#streams

app.MapPost
(
    "/{type}/{id}", async (string type, string id, HttpRequest httpRequest, Container db) =>
    {
        var savedItem = await db.CreateItemStreamAsync(httpRequest.Body, new PartitionKey(type));

        return Results.Stream(savedItem.Content, "application/json");
    }
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM