【发布时间】:2020-09-09 22:00:00
【问题描述】:
我正在尝试通过我自己的 API 将 Stream 的数据发送到 API。第三方 API 获取一个对象,该对象有一个对象属性,其属性值为Stream。在使用我的 API 的代码中,我需要读取一个 CSV 文件,然后序列化包含 Stream 属性的 DTO 对象以将其发送到我的 API。然后,我的 API 会将 DTO 对象传递给第三方 API。
我的问题是我目前正在将 Stream 属性序列化为 base 64 字符串,但无法将其反序列化回 DTO 对象。
DTO 对象:
public class BulkLeadRequest
{
public Format3 FileFormat { get; set; }
public FileParameter FileParameter { get; set; }
public string LookupField { get; set; }
public string PartitionName { get; set; }
public int? ListId { get; set; }
public int? BatchId { get; set; }
}
Format3 是一个枚举:
public enum Format3
{
[System.Runtime.Serialization.EnumMember(Value = @"csv")]
Csv = 0,
[System.Runtime.Serialization.EnumMember(Value = @"tsv")]
Tsv = 1,
[System.Runtime.Serialization.EnumMember(Value = @"ssv")]
Ssv = 2,
}
FileParamter 具有Stream 属性的对象:
public partial class FileParameter
{
public FileParameter(System.IO.Stream data)
: this(data, null)
{
}
public FileParameter(System.IO.Stream data, string fileName)
: this(data, fileName, null)
{
}
public FileParameter(System.IO.Stream data, string fileName, string contentType)
{
Data = data;
FileName = fileName;
ContentType = contentType;
}
public System.IO.Stream Data { get; private set; }
public string FileName { get; private set; }
public string ContentType { get; private set; }
}
为了测试序列化我有这个小单元测试。
public void TestSerializationDeserialization()
{
BulkLeadRequest bulkLeadRequest = new BulkLeadRequest();
bulkLeadRequest.FileFormat = Format3.Csv;
bulkLeadRequest.FileParameter = new FileParameter(new StreamReader("C:\temp\\SmallFile.csv").BaseStream);
string serializedObject = JsonConvert.SerializeObject(bulkLeadRequest, new StreamStringConverter());
var obj = JsonConvert.DeserializeObject<BulkLeadRequest>(serializedObject,
new JsonSerializerSettings {Converters = new List<JsonConverter> {new StreamStringConverter()}}); // Issue here
Assert.Equal(bulkLeadRequest, obj);
}
StreamStringConverter:
public class StreamStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Stream).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string objectContents = (string)reader.Value;
byte[] base64Decoded = Convert.FromBase64String(objectContents);
MemoryStream memoryStream = new MemoryStream(base64Decoded);
return memoryStream;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
FileStream valueStream = (FileStream)value;
byte[] fileBytes = new byte[valueStream.Length];
valueStream.Read(fileBytes, 0, (int)valueStream.Length);
string bytesAsString = Convert.ToBase64String(fileBytes);
writer.WriteValue(bytesAsString);
}
}
在我的TestSerializationDeserialization 单元测试中,我收到以下错误:
Newtonsoft.Json.dll 中出现“Newtonsoft.Json.JsonSerializationException”类型的异常,但未在用户代码中处理 找不到用于 Cocc.MarketoSvcs.Business.FileParameter 类型的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有 JsonConstructor 属性的构造函数。路径“FileParameter.Data”,第 1 行,位置 40。
如果我向FileParameter 添加一个默认构造函数,那么在反序列化时Data 属性将为空。如果我删除 JsonConvert.DeserializeObject<BulkLeadRequest>(..); 对 JsonConvert.DeserializeObject(...); 的调用中的隐式转换,我将得到一个对象,但不是 BulkLeadRequest 并且仍然是 base64 字符串,而不是我期望的 Stream 对象。
序列化:
{"FileFormat":0,"FileParameter":{"Data":"RklSU1ROQU1FLE1ETElOSVQsTEFTVE5BTUUNCkNyaXN0aW5hLE0sRGlGYWJpbw0KTmVsbHksLFBhbGFjaW9zDQpNYXR0aGV3LEEsTmV2ZXJz","FileName":null,"ContentType":null},"LookupField":null,"PartitionName":null,"ListId":null,"BatchId":null}
我做错了什么?
【问题讨论】:
标签: c# serialization json.net deserialization