作者:hongxiaochen8847_106 | 来源:互联网 | 2022-12-10 12:21
我有一点问题。我的环境是.NET Core 2.1中的控制台应用程序。
看下面的代码:
private static void Main(string[] args)
{
try
{
Console.WriteLine($"Test starts: {DateTime.Now.ToString("o")}");
string cOnnectionString= "[My connection string]";
string cOntainerName= "mycontainer";
CloudStorageAccount account = CloudStorageAccount.Parse(connectionString);
CloudBlobClient serviceClient = account.CreateCloudBlobClient();
CloudBlobContainer cOntainer= serviceClient.GetContainerReference(containerName);
container.CreateIfNotExistsAsync().Wait();
CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference($"{containerName}/Test.txt");
CloudBlobStream cloudBlobStream = cloudBlockBlob.OpenWriteAsync().Result;
string json = JsonConvert.SerializeObject(cloudBlobStream);
Console.WriteLine($"Test ends: {DateTime.Now.ToString("o")}");
}
catch (Exception e)
{
string stackTrace = e.StackTrace;
while(e != null)
{
Console.WriteLine(e.Message);
e = e.InnerException;
}
Console.WriteLine(stackTrace);
}
Console.Write("Press any key to exit...");
Console.ReadKey();
}
当我尝试CloudBlobStream
使用命令序列化对象时string json = JsonConvert.SerializeObject(cloudBlobStream);
,获得以下异常:
从“ Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream”上的“长度”获取值时出错。不支持指定的方法。在Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter作家,对象值,JsonContainerContract合同,JsonProperty成员,JsonProperty属性,JsonNewton&Value,JsonContract&memberContract),在Newtonsoft.Json.Serialization.Json.Serialization.ExpressionValueProvider.GetValue(对象目标)处。 .Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,Object value,JsonObjectContract contract,JsonProperty member,JsonContainerContract collectionContract,JsonProperty containerProperty)在Newton.Json.Serialization.JsonSerializerInternalWriter.Serialize()
关于如何解决问题有什么想法?
问候,Attilio
1> Brian Rogers..:
在您的代码中,看起来您实际上是在尝试序列化Stream
对象,就好像它是数据一样。这是行不通的。发生异常是因为序列化程序正在尝试从Stream
对象读取所有公共属性。这些属性之一是Length
,当打开流进行写入时,该属性不可读。
我认为您误会了如何将流与Json.Net和Azure存储Blob一起使用。该JsonConvert
班是真的只是一个门面,不幸的是它的SerializeObject()
方法不具有过载,支持流。为了在使用Json.Net流工作,你需要使用JsonSerializer
带有沿实例StreamWriter
和JsonTextWriter
如果你序列化到流,或StreamReader
和JsonTextReader
,如果你从它要反序列化。
以下是一些扩展方法,您可能会发现它们有用和有启发性:
public static class BlobExtensions
{
public static async Task SerializeObjectToBlobAsync(this CloudBlockBlob blob, object obj)
{
using (Stream stream = await blob.OpenWriteAsync())
using (StreamWriter sw = new StreamWriter(stream))
using (JsonTextWriter jtw = new JsonTextWriter(sw))
{
JsonSerializer ser = new JsonSerializer();
ser.Serialize(jtw, obj);
}
}
public static async Task DeserializeObjectFromBlobAsync(this CloudBlockBlob blob)
{
using (Stream stream = await blob.OpenReadAsync())
using (StreamReader sr = new StreamReader(stream))
using (JsonTextReader jtr = new JsonTextReader(sr))
{
JsonSerializer ser = new JsonSerializer();
return ser.Deserialize(jtr);
}
}
}
现在,假设您有一个类,Item
表示要序列化为JSON并存储到Azure Blob中的某些数据:
class Item
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
使用第一种扩展方法的方法如下:
...
var item = new Item { Id = 1, Name = "Widget", Price = 2.5 };
cloudBlockBlob.SerializeObjectToBlobAsync(item).Wait();
相反,如果您想从Blob中检索JSON并将其反序列化为Item
,则可以使用其他扩展方法:
var item = cloudBlockBlob.DeserializeObjectFromBlobAsync- ().Result;
注意:如果要从一个async
方法中使用这些方法,则应分别使用await
语法而不是Wait()
和.Result
:
await cloudBlockBlob.SerializeObjectToBlobAsync(item);
...
var item = await cloudBlockBlob.DeserializeObjectFromBlobAsync- ();