我正在寻找一种方法来将带有流的对象序列化为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已经在评论中回答了这个问题,因此,此答案将替代实现此目标
这是一个实现自定义的示例,该自定义JsonConverter
将File
属性与Base64字符串之间来回转换,以便可以在网络上进行传输。
一些要点:
首先,我创建了一个 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);
}
}
再次重申,我尚未编写此代码以进行生产准备,这取决于您,这只是在指导您正确的方向。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句