如何在C#中使用流序列化对象

用户名

我正在寻找一种方法来将带有流的对象序列化为JSON,以发布到API。我继续收到此错误:

Newtonsoft.Json.JsonSerializationException:'从'System.IO.FileStream'的'ReadTimeout'获取值时出错。

我了解错误在说什么,但我不了解解决该问题所需的实现。是否需要在JSON之前将其转换为其他内容?

这是我的代码:

模型:

[Serializable]
public class Document
{
    public string Number { get; set; }
    public string Revision { get; set; }
    public string FileName { get; set; }
    public Stream File { get; set; }
}

建筑要求:

public Document BuildRequest(string pdfFile, string txtFile)
{
    Document document = new Document();

    try
    {
        string data = File.ReadAllText(txtFile);
        string[] array = data.Split('|');

        FileStream fs = new FileStream(pdfFile, FileMode.Open);

        document.Number = array[0];
        document.Revision = array[1];
        document.FileName = file;
        document.File = fs;
    }
        // rest of code...
}

发布:

public void Post(Document document)
{
    var json = JsonConvert.SerializeObject(document);
    // rest of code in method...
}
科林

发布此内容后,我看到Lasse已经在评论中回答了这个问题,因此,此答案将替代实现此目标

这是一个实现自定义的示例,该自定义JsonConverterFile属性与Base64字符串之间来回转换,以便可以在网络上进行传输。

一些要点:

  1. 您需要在具有大PDF文件的情况下测试此代码
  2. 如果您发现任何极端情况,则必须重构此代码以处理某些极端情况
  3. 我写这纯粹是为了回答您的“可以做到”的问题,我没有考虑任何例外,边缘情况甚至网络延迟,具体取决于Base64字符串的大小-您将遇到的问题和限制取决于内容HTTP请求的大小。
  4. API需要知道如何处理此请求,从而将Base 64文本作为流读取。

首先,我创建了一个 StreamStringConverter

/// <summary>
/// Handles the (de)serialization of <see cref="Stream"/>.
/// </summary>
/// <remarks>
/// The <see cref="Stream"/> will be written as a Base64 encoded string, on the inverse it will be converted from a Base64 string to a <see cref="MemoryStream"/>.
/// </remarks>
public class StreamStringConverter : JsonConverter
{
    private static Type AllowedType = typeof(Stream);

    public override bool CanConvert(Type objectType)
        => objectType == AllowedType;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var objectContents = (string)reader.Value;
        var base64Decoded = Convert.FromBase64String(objectContents);

        var memoryStream = new MemoryStream(base64Decoded);

        return memoryStream;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var valueStream = (FileStream)value;
        var fileBytes = new byte[valueStream.Length];

        valueStream.Read(fileBytes, 0, (int)valueStream.Length);

        var bytesAsString = Convert.ToBase64String(fileBytes);

        writer.WriteValue(bytesAsString);
    }
}

您可以装饰Document班级中的适当成员以使用此自定义StreamStringConverter

public class Document
{
    public string Number { get; set; }
    public string Revision { get; set; }
    public string FileName { get; set; }

    // Specify a custom JsonConverter for our StreamJsonConverter
    [JsonConverter(typeof(StreamStringConverter))]
    public Stream File { get; set; }
}

您的模型现在可以开始序列化和反序列化stringtxtFile,为简单起见,我已经更新了一些代码以代替实际的文件句柄

static void Main(string[] args)
{
    Document document = new Document();

    const string file = "file";
    const string txtFileContents = "1|1.0";
    const string pdfFile = "myPdfFile.pdf";

    try
    {
        string[] array = txtFileContents.Split('|');

        FileStream fs = new FileStream(pdfFile, FileMode.Open);

        document.Number = array[0];
        document.Revision = array[1];
        document.FileName = file;
        document.File = fs;
    }
    catch (Exception exception)
    {
    }

    // Serialize the Document object
    // File, in the JSON contents, will be a Base64 encoded string
    var serializedContents = JsonConvert.SerializeObject(document);

    // Deserialize the contents
    // File will be a Stream
    var deserializedContents = JsonConvert.DeserializeObject<Document>(serializedContents);

    // For demo purposes, this will write the Document.File object back to a new PDF file for comparison
    using (var fileStream = File.Create("myDeserializedPdfFile.pdf"))
    {
        var fileAsMemoryStream = (MemoryStream)deserializedContents.File;
        fileAsMemoryStream.WriteTo(fileStream);
    }
}

再次重申,我尚未编写此代码以进行生产准备,这取决于您,这只是在指导您正确的方向。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在C#中使用json.net忽略序列化的属性,但保留反序列化

如何使用XElement在C#中使用List序列化对象?

如何在C ++中使用对象序列化保存和加载std :: string?

如何在c#中使用循环依赖项将对象序列化为xml?

如何在C#中使用表和值反序列化JSON

如何在C#中使用Newtonsoft反序列化

如何在C#中使用动态和静态键名反序列化JSON

如何在C#中使用JavascriptSerializer序列化嵌套实体(模型)?

如何在 C# 中使用 JSON 反序列化 oData V2?

如何使用反序列化对象 c#

如何在我的kafka使用者中使用对象反序列化json列表?

如何在C#中使用JSON.NET反序列化JSON RPC响应数组?

C#:如何在Unity中使用数组而不是列表重写用于管理游戏数据序列化的代码?

如何在不使用 File.ReadAllLines 的情况下从 json 文件读取序列化对象?C#

在C#中使用嵌套列表反序列化JSON数组对象

反序列化XML以在C#中使用列表对象

在C#中使用Newtonsoft对嵌套的JSON对象进行反序列化

如何在Java中使用Gson @SerializedName序列化嵌套对象?

如何在Java中使用Jackson的dataformat.xml序列化LookAndFeel对象?

如何在python中使用pickle序列化套接字对象

如何在 Greenplum/Postgres 中使用 PL/R 反序列化模型对象?

如何在UDAF中使用第三方不可序列化对象?

如何在C#中使元组或键值对json像字典一样序列化

如何在C#中反序列化多个JSON对象?

如何在不进行序列化的情况下Redis缓存大型C#对象?

如何在C#模型中反序列化不同对象的数组

如何在 C# 中设置从对象到数组的 json 反序列化

如何反序列化C#对象的值列表

如何反序列化Json对象-C#