Skip to content

Proposal: Utf8JsonWriter.WriteUtf8Json #32849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
declspec opened this issue Feb 26, 2020 · 5 comments
Closed

Proposal: Utf8JsonWriter.WriteUtf8Json #32849

declspec opened this issue Feb 26, 2020 · 5 comments

Comments

@declspec
Copy link

I would like to propose an addition to the System.Text.Json.Utf8JsonWriter API which would allow writing existing UTF8-encoded JSON fragments into the current JSON document.

Something like the following:

public  sealed class Utf8JsonWriter {
    public void WriteUtf8JsonValue(ReadOnlySpan<byte> utf8json);

    public void WriteUtf8Json(string propertyName, ReadOnlySpan<byte> utf8json);
    // ... and the rest of the standard overloads for the different types of `propertyName`
}

An example of usage would be:

var utf8json = Encoding.UTF8.GetBytes("{ \"foo\": 42, \"bar\": \"baz\" }").AsSpan();

using (var ms = new MemoryStream()) {
    using (var writer = new Utf8JsonWriter(ms)) {
        writer.WriteStartObject();
        writer.WriteUtf8Json("fragment", utf8json);
        writer.WriteEndObject();
    }

    Debug.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

    // Expected output:
    // { "fragment": { "foo": 42, "bar": "baz" } }
}

I believe this would be useful when you are trying to augment or wrap existing JSON payloads (i.e. from external services) in a parent document without needing to deserialize and reserialize them.

I have read through all the documentation I can find and as far as I can see there doesn't currently seem to be any way of doing what I'm proposing. If there is already a better way of doing this please let me know.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Feb 26, 2020
@declspec declspec changed the title Proposal: System.Text.Json.Utf8JsonWriter.WriteUtf8Json Proposal: Utf8JsonWriter.WriteUtf8Json Feb 26, 2020
@FiniteReality
Copy link

I've also had a use for something like this, particularly when interacting with multiple serializers. (With different behaviour to System.Text.Json, which is fairly hard to implement without writing a lot of custom code.) The workaround I came up with was to serialize to a JsonDocument and write that to the output.

A better name is probably something like WriteRaw though, since you're writing the raw value to the output.

@declspec
Copy link
Author

declspec commented Feb 26, 2020

Yeah I ended up deserializing to a JsonElement and then re-serializing that; sounds like a similar situation.

As for naming, I'm sure that the team would have some strong opinions as well so I'm happy to leave that open to discussion.

My original thinking was along the lines that you may need to convey to the caller than the method does not do any transcoding; the input ReadOnlySpan<byte> should contain UTF8-encoded JSON, not JSON in any encoding.
That may be obvious enough by the fact you're using Utf8JsonWriter though so maybe WriteJson is acceptable.

@artelk
Copy link

artelk commented Feb 27, 2020

Writing raw data can be unsafe. I would propose a method that writes all tokens from a Utf8JsonReader. That would implicitly validate the content.

@declspec
Copy link
Author

declspec commented Feb 28, 2020

Writing raw data can be unsafe. I would propose a method that writes all tokens from a Utf8JsonReader. That would implicitly validate the content.

That was a pattern I was hoping existed when I was first looking for a solution. Something like

public ref struct Utf8JsonReader {
    void CopyTo(Utf8JsonWriter writer);
}

Alternatively (and this seems like a objectively worse API) only allow WriteUtf8Json to be called when JsonWriterOptions.SkipValidation = true.

Or implement both options; have WriteUtf8Json(ReadOnlySpan<byte>) internally create a Utf8JsonReader and call CopyTo() when SkipValidation = false and just do a naive copy when SkipValidation = true.

@layomia
Copy link
Contributor

layomia commented Feb 28, 2020

We are looking into this for 5.0. Closing as a duplicate of #1784.

@layomia layomia closed this as completed Feb 28, 2020
@layomia layomia added this to the 5.0 milestone Feb 28, 2020
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Feb 28, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants