gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 03:00:06 27 4
gpt4 key购买 nike

我正在寻找一种方法来将对象序列化为 JSON 以 POST 到 API。我继续收到此错误:

Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'ReadTimeout' on 'System.IO.FileStream'.'

我明白错误的意思,但我不明白我需要实现什么来解决它。在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 已经在评论中回答了这个问题,因此这个答案将作为实现这个的替代方法

这是一个实现自定义 JsonConverter 的示例,它将 File 属性与 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; }
}

您的模型现在已准备好开始序列化和反序列化,为了简单起见,我更新了一些代码以使用 string 代替 txtFile 的实际文件句柄.

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);
}
}

我再次重申,我编写这段代码并不是为了生产就绪,这取决于您,这只是为了引导您朝着正确的方向前进。

关于c# - 如何在C#中使用流序列化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57187206/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com