返回 Azure TableEntity 对象列表时出现 SerializationException
SerializationException when returning List of Azure TableEntity objects
使用 WebAPI 返回 TableEntities 列表时,出现 500 内部服务器错误。当我查看 Visual Studio 中的输出时,我发现我得到了这些 'System.Runtime.Serialization.SerializationException'.
这是我在控制器中的代码
public IEnumerable<ContactEntity> Get()
{
var creds = new StorageCredentials("MyAccountName", "MyKey");
var storageAccount = new CloudStorageAccount(creds, false);
// Create the table client.
var tableClient = storageAccount.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
return items;
}
这是我的自定义 TableEntity 代码
[Serializable]
public class ContactEntity: TableEntity
{
public ContactEntity(string firstName, string lastName)
{
this.PartitionKey = lastName;
this.RowKey = firstName;
}
public ContactEntity() { }
public string Email { get; set; }
}
在控制器中,如果我手动创建实体列表,我不会遇到序列化问题。
public IEnumerable<ContactEntity> Get()
{
var creds = new StorageCredentials("MyAccountName", "MyKey");
var storageAccount = new CloudStorageAccount(creds, false);
// Create the table client.
var tableClient = storageAccount.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
var manualList = new List<ContactEntity>() { };
manualList.Add(new ContactEntity { PartitionKey = items[0].PartitionKey, RowKey = items[0].RowKey, ETag = items[0].ETag, Timestamp = items[0].Timestamp });
manualList.Add(new ContactEntity { PartitionKey = items[1].PartitionKey, RowKey = items[1].RowKey, ETag = items[1].ETag, Timestamp = items[1].Timestamp });
return manualList;
}
知道为什么吗?
这是输出中列出的异常 window。
抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException'
抛出异常:'System.Runtime.Serialization.SerializationException' in mscorlib.dll
由于内部委托成员等原因,无法序列化从 TableEntity 继承的类型。见下文:
您有几个选择:
从 ITableEntity 接口而不是 TableEntity 继承...您必须自己实现核心 TableEntity 行为(一般情况下还不错),如果需要,这使您有机会实现序列化, 太
更改您的 Web API 以输出仅包含您想要 return 的实体属性的单独类型,并为您的实体类型实现一个转换函数,例如这个:
在 ContactEntity 中 class:
public JObject ToJson()
{
var jo = new JObject();
jo["PartitionKey"] = PartitionKey;
jo["RowKey"] = RowKey;
jo["Email"] = Email;
// etc
return jo;
}
在你的控制器中:
public IEnumerable<JObject> Get()
{
// Create the table client.
var tableClient = _account.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
return items.Select(i => i.ToJson());
}
请注意从 returnContactEntity 的 IEnumerable 到 JObject 的 IEnumerable 的切换。如果愿意,您还可以定义一个单独的 class 并使用它代替 JObject。
希望对您有所帮助...祝您好运!
JshL 建议的另一个替代方法是,您可以将 Web api 更改为 return IEnumerable of json serialized DynamicTableEntities。在客户端将 json 反序列化回 DynamicTableEntity 并处理将其转换为您的具体 class 如果您想要或只是将其作为 DynamicTableEntity 使用。
您可以查看我在此处实现的 DynamicTableEntity json 序列化程序:
https://www.nuget.org/packages/DynamicTableEntityJsonSerializer/
使用 WebAPI 返回 TableEntities 列表时,出现 500 内部服务器错误。当我查看 Visual Studio 中的输出时,我发现我得到了这些 'System.Runtime.Serialization.SerializationException'.
这是我在控制器中的代码
public IEnumerable<ContactEntity> Get()
{
var creds = new StorageCredentials("MyAccountName", "MyKey");
var storageAccount = new CloudStorageAccount(creds, false);
// Create the table client.
var tableClient = storageAccount.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
return items;
}
这是我的自定义 TableEntity 代码
[Serializable]
public class ContactEntity: TableEntity
{
public ContactEntity(string firstName, string lastName)
{
this.PartitionKey = lastName;
this.RowKey = firstName;
}
public ContactEntity() { }
public string Email { get; set; }
}
在控制器中,如果我手动创建实体列表,我不会遇到序列化问题。
public IEnumerable<ContactEntity> Get()
{
var creds = new StorageCredentials("MyAccountName", "MyKey");
var storageAccount = new CloudStorageAccount(creds, false);
// Create the table client.
var tableClient = storageAccount.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
var manualList = new List<ContactEntity>() { };
manualList.Add(new ContactEntity { PartitionKey = items[0].PartitionKey, RowKey = items[0].RowKey, ETag = items[0].ETag, Timestamp = items[0].Timestamp });
manualList.Add(new ContactEntity { PartitionKey = items[1].PartitionKey, RowKey = items[1].RowKey, ETag = items[1].ETag, Timestamp = items[1].Timestamp });
return manualList;
}
知道为什么吗?
这是输出中列出的异常 window。
抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:Newtonsoft.Json.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:mscorlib.dll 中的 'System.Runtime.Serialization.SerializationException' 抛出异常:'System.Runtime.Serialization.SerializationException' in mscorlib.dll
由于内部委托成员等原因,无法序列化从 TableEntity 继承的类型。见下文:
您有几个选择:
从 ITableEntity 接口而不是 TableEntity 继承...您必须自己实现核心 TableEntity 行为(一般情况下还不错),如果需要,这使您有机会实现序列化, 太
更改您的 Web API 以输出仅包含您想要 return 的实体属性的单独类型,并为您的实体类型实现一个转换函数,例如这个:
在 ContactEntity 中 class:
public JObject ToJson()
{
var jo = new JObject();
jo["PartitionKey"] = PartitionKey;
jo["RowKey"] = RowKey;
jo["Email"] = Email;
// etc
return jo;
}
在你的控制器中:
public IEnumerable<JObject> Get()
{
// Create the table client.
var tableClient = _account.CreateCloudTableClient();
// Retrieve a reference to the table.
var contactsTable = tableClient.GetTableReference("contacts");
// Create the table if it doesn't exist.
contactsTable.CreateIfNotExists();
// Construct the query operation for all contact entities
var query = new TableQuery<ContactEntity>();
var items = contactsTable.ExecuteQuery<ContactEntity>(query).ToList();
return items.Select(i => i.ToJson());
}
请注意从 returnContactEntity 的 IEnumerable 到 JObject 的 IEnumerable 的切换。如果愿意,您还可以定义一个单独的 class 并使用它代替 JObject。
希望对您有所帮助...祝您好运!
JshL 建议的另一个替代方法是,您可以将 Web api 更改为 return IEnumerable of json serialized DynamicTableEntities。在客户端将 json 反序列化回 DynamicTableEntity 并处理将其转换为您的具体 class 如果您想要或只是将其作为 DynamicTableEntity 使用。
您可以查看我在此处实现的 DynamicTableEntity json 序列化程序: https://www.nuget.org/packages/DynamicTableEntityJsonSerializer/